Skip to content

Delphi Decompiler Dede

DeDe offers several features that bridge the gap between raw binary and source code:

DeDe is a historically important, specialized tool for recovering Delphi form layouts and symbol information from older (v2–v7) 32-bit Delphi executables. It is not a full decompiler (does not produce Pascal code for logic), and it is obsolete for modern Delphi versions or packed binaries. However, for legacy software maintenance, digital forensics, or malware analysis involving classic Delphi binaries, DeDe may still be useful – though newer alternatives like IDR or Ghidra are generally preferable.


Report prepared by: [Your Name / Organization]
Date: [Current Date]
Classification: Public – Technical Reference

DeDe is a specialized decompiler for applications built with Delphi (versions 2 through 6). While it doesn't provide fully recompilable source code, it is excellent for recovering UI forms and analyzing application logic through assembly. 1. Getting Started with DeDe

To begin using DeDe, you can find it on various archives or software repositories since it is no longer actively updated.

Load the Target: Open DeDe and use the File | Open menu to load a Delphi executable (.exe), DLL, or BPL.

Analyze the File: Click the Analyze button. DeDe will scan the binary for Delphi-specific metadata, such as the Virtual Method Table (VMT) and published methods. 2. Key Features and Outputs

Once analysis is complete, DeDe provides several tabs to explore the application:

DFM Files (Forms): You can view and extract all .dfm files. These contain the UI layout and property settings (e.g., button captions, positions). You can even open and edit these directly in Delphi.

Published Methods: DeDe lists event handlers (like OnClick events). It provides these in commented ASM (Assembly) code, often including references to strings, imported functions, and class method calls.

Project Creation: Use the Make Project feature to generate a Delphi project folder containing the retrieved .dfm, .pas, and .dpr files. Note that the .pas files contain assembly code and cannot be recompiled as-is. 3. Advanced Tools in DeDe

DeDe includes several built-in utilities for deeper analysis:

Disassemble Proc: If you know a specific Relative Virtual Address (RVA), you can manually disassemble any procedure via the Tools | Disassemble Proc menu. delphi decompiler dede

Symbol Files (DSF): You can load .dsf files (DeDe Symbol Files) via File | Load Symbol File. These help DeDe identify and comment on exports from BPL libraries, similar to FLIRT signatures in other tools.

Helper Tools: The interface includes a PE Editor, RVA Converter, and DOI Builder (Delphi Offset Info) to help navigate the binary structure. 4. Limitations and Modern Alternatives Because DeDe is a legacy tool, it has specific constraints:

Version Limit: It is most effective for 32-bit executables from older Delphi versions (up to version 6 or 7).

No Logic Recovery: It does not recover high-level Pascal logic; you must be comfortable reading x86 assembly to understand "what happens" after a button click.

For more modern or complex Delphi applications, developers often use IDR (Interactive Delphi Reconstructor) for better class reconstruction or Ghidra with specialized Delphi scripts.

Are you trying to recover a specific UI form or are you looking to understand the logic of an older application? DeDe - Download - Softpedia

Introduction

Delphi Decompiler Dede is a software tool designed to reverse-engineer and decompile programs written in Delphi, a popular object-oriented programming language. Dede is a free and open-source decompiler that can help developers understand and analyze the internal workings of Delphi applications. This paper provides an overview of Dede, its features, and its uses.

What is Delphi?

Delphi is a high-level, compiled, strongly typed language developed by Embarcadero Technologies. It is widely used for building Windows desktop applications, mobile apps, and web applications. Delphi is known for its fast development capabilities, large standard library, and strong support for object-oriented programming.

What is a Decompiler?

A decompiler is a software tool that takes compiled code as input and generates source code in a high-level programming language as output. Decompilers are used to reverse-engineer software, understand its internal workings, and analyze its behavior. Decompilers can be useful for various purposes, such as: DeDe offers several features that bridge the gap

Delphi Decompiler Dede

Dede is a free and open-source decompiler for Delphi programs. It was first released in 2004 and has since become one of the most popular decompilers for Delphi. Dede can decompile Delphi programs from version 3 to the latest version, including programs compiled with the .NET framework.

Features of Dede

Some of the key features of Dede include:

How Dede Works

Dede uses a combination of disassembly and decompilation techniques to recover the source code from a compiled Delphi program. Here is a high-level overview of the decompilation process:

Uses of Dede

Dede has various uses, including:

Conclusion

Delphi Decompiler Dede is a powerful tool for reverse-engineering and decompiling Delphi programs. Its ability to decompile programs from various Delphi versions and .NET framework makes it a valuable asset for developers, researchers, and educators. Dede's features, such as syntax highlighting and support for various output formats, make it a user-friendly tool for analyzing and understanding compiled Delphi programs.

Future Work

Future work on Dede could include:

References

I'll help you develop a feature for a Delphi decompiler similar to DEDE (DeDe). This feature will extract and display form information, event handlers, and component properties from a Delphi compiled executable.

"""
Delphi Decompiler Feature - Form & Component Extractor
Inspired by DEDE (Delphi Decompiler)
"""

import struct import re from dataclasses import dataclass, field from typing import List, Dict, Optional, BinaryIO from enum import Enum

class ComponentType(Enum): TFORM = "TForm" TBUTTON = "TButton" TEDIT = "TEdit" TMEMO = "TMemo" TLABEL = "TLabel" TCOMBOBOX = "TComboBox" TLISTBOX = "TListBox" TCHECKBOX = "TCheckBox" TRADIOBUTTON = "TRadioButton" TPANEL = "TPanel" TMAINMENU = "TMainMenu" TTIMER = "TTimer" UNKNOWN = "Unknown"

@dataclass class RTTIProperty: """Represents a component property from RTTI""" name: str value: str prop_type: str

@dataclass class EventHandler: """Represents an event handler method""" event_name: str method_name: str rva: int # Relative Virtual Address

@dataclass class Component: """Represents a Delphi component/form control""" name: str component_type: ComponentType parent: Optional[str] properties: Dict[str, RTTIProperty] = field(default_factory=dict) events: List[EventHandler] = field(default_factory=list) children: List['Component'] = field(default_factory=list)

@dataclass class FormInfo: """Represents a Delphi form""" name: str class_name: str unit_name: str components: List[Component] = field(default_factory=list)

class DelphiDecompiler: """Main decompiler class for Delphi executables"""

def __init__(self, file_path: str):
    self.file_path = file_path
    self.file_data = None
    self.forms: List[FormInfo] = []
    self.string_table: Dict[int, str] = {}
def load_file(self) -> bool:
    """Load the executable file"""
    try:
        with open(self.file_path, 'rb') as f:
            self.file_data = f.read()
        return True
    except Exception as e:
        print(f"Error loading file: e")
        return False
def find_delphi_signature(self) -> bool:
    """Detect if file is a Delphi executable"""
    signatures = [
        b'TPF0',  # Delphi 2009+
        b'PACKAGEINFO',  # Package info
        b'System@Sysinit',  # Delphi runtime
        b'@System@InitUnits',  # Unit initialization
    ]
for sig in signatures:
        if sig in self.file_data:
            return True
    return False
def extract_strings(self) -> None:
    """Extract string table references"""
    # Simple string extraction pattern
    # Delphi stores strings as length-prefixed
    pattern = re.compile(b'\x03([\x20-\x7E]+)\x00')
for match in pattern.finditer(self.file_data):
        try:
            string_val = match.group(1).decode('ascii', errors='ignore')
            offset = match.start()
            self.string_table[offset] = string_val
        except:
            pass
def find_form_resources(self) -> List[tuple]:
    """Find embedded form resource (DFM) data"""
    forms = []
# Search for DFM resource patterns
    dfm_patterns = [
        b'OBJECT ',  # DFM object declaration
        b'object ',  # Lowercase variant
        b'POBJECT',  # Pascal-style
    ]
for pattern in dfm_patterns:
        pos = 0
        while True:
            found = self.file_data.find(pattern, pos)
            if found == -1:
                break
# Extract form name
            end_of_obj = self.file_data.find(b'\n', found)
            if end_of_obj != -1:
                form_line = self.file_data[found:end_of_obj].decode('ascii', errors='ignore')
                form_name = form_line.replace('OBJECT ', '').replace('object ', '').strip()
                forms.append((found, form_name))
pos = found + 1
return forms
def parse_dfm_data(self, data: bytes) -> List[Component]:
    """Parse DFM (Delphi Form Module) binary/text data"""
    components = []
# Convert to string for easier parsing
    try:
        dfm_text = data.decode('ascii', errors='ignore')
        lines = dfm_text.split('\n')
current_component = None
        indent_stack = []
for line in lines:
            line = line.strip()
            if not line:
                continue
# Detect component start
            if line.upper().startswith('OBJECT'):
                # Parse component definition
                parts = line.split()
                if len(parts) >= 2:
                    comp_type = parts[1]
                    comp_name = parts[2] if len(parts) > 2 else "Unnamed"
component = Component(
                        name=comp_name,
                        component_type=self._parse_component_type(comp_type),
                        parent=None
                    )
                    components.append(component)
                    current_component = component
                    indent_stack.append(component)
# Detect component end
            elif line.upper() == 'END':
                if indent_stack:
                    indent_stack.pop()
                current_component = indent_stack[-1] if indent_stack else None
# Parse properties
            elif current_component and '=' in line:
                self._parse_property(line, current_component)
except Exception as e:
        print(f"Error parsing DFM: e")
return components
def _parse_component_type(self, type_str: str) -> ComponentType:
    """Convert Delphi type string to ComponentType enum"""
    type_upper = type_str.upper()
    mapping = 
        'TFORM': ComponentType.TFORM,
        'TBUTTON': ComponentType.TBUTTON,
        'TEDIT': ComponentType.TEDIT,
        'TMEMO': ComponentType.TMEMO,
        'TLABEL': ComponentType.TLABEL,
        'TCOMBOBOX': ComponentType.TCOMBOBOX,
        'TLISTBOX': ComponentType.TLISTBOX,
        'TCHECKBOX': ComponentType.TCHECKBOX,
        'TRADIOBUTTON': ComponentType.TRADIOBUTTON,
        'TPANEL': ComponentType.TPANEL,
        'TMAINMENU': ComponentType.TMAINMENU,
        'TTIMER': ComponentType.TTIMER,
return mapping.get(type_upper, ComponentType.UNKNOWN)
def _parse_property(self, line: str, component: Component) -> None:
    """Parse a property line from DFM"""
    try:
        prop_name, prop_value = line.split('=', 1)
        prop_name = prop_name.strip()
        prop_value = prop_value.strip().strip('"')
# Detect event handlers
        if prop_name.lower().endswith('on'):
            # Event handler reference
            event_handler = EventHandler(
                event_name=prop_name,
                method_name=prop_value,
                rva=0  # Would need actual RVA calculation
            )
            component.events.append(event_handler)
        else:
            # Regular property
            prop_type = self._guess_property_type(prop_value)
            rtti_prop = RTTIProperty(
                name=prop_name,
                value=prop_value,
                prop_type=prop_type
            )
            component.properties[prop_name] = rtti_prop
except Exception:
        pass
def _guess_property_type(self, value: str) -> str:
    """Guess property type from value"""
    if value.isdigit():
        return 'Integer'
    elif value.upper() in ['TRUE', 'FALSE']:
        return 'Boolean'
    elif value.startswith('$') and len(value) > 1:
        return 'Hex'
    else:
        return 'String'
def find_event_handlers(self) -> Dict[str, List[int]]:
    """Find event handler addresses in code section"""
    handlers = {}
# Pattern for Delphi method references
    method_patterns = [
        rb'\x68([\x00-\xFF]4)',  # push address (DELPHI)
        rb'\xB8([\x00-\xFF]4)',  # mov eax, address
    ]
for pattern in method_patterns:
        for match in re.finditer(pattern, self.file_data):
            try:
                address = struct.unpack('<I', match.group(1))[0]
                # Look for method name nearby
                method_name = self._find_method_name(match.start())
                if method_name:
                    handlers.setdefault(method_name, []).append(address)
            except:
                pass
return handlers
def _find_method_name(self, position: int) -> Optional[str]:
    """Find method name near given position"""
    # Look for Pascal string format (length byte + string)
    search_range = 100
    start = max(0, position - search_range)
    end = min(len(self.file_data), position + search_range)
for offset in range(start, end):
        if offset + 1 >= len(self.file_data):
            continue
str_len = self.file_data[offset]
        if 1 <= str_len <= 100:  # Reasonable string length
            try:
                name = self.file_data[offset+1:offset+1+str_len].decode('ascii', errors='ignore')
                if name and name[0].isalpha():
                    return name
            except:
                pass
    return None
def decompile(self) -> bool:
    """Main decompilation process"""
    print(f"[*] Loading file: self.file_path")
    if not self.load_file():
        return False
print("[*] Checking Delphi signature...")
    if not self.find_delphi_signature():
        print("[!] Warning: Delphi signature not found")
print("[*] Extracting strings...")
    self.extract_strings()
print("[*] Finding form resources...")
    form_resources = self.find_form_resources()
print(f"[*] Found len(form_resources) potential form(s)")
for offset, form_name in form_resources:
        print(f"\n[*] Processing form: form_name")
# Extract form data (simplified)
        end_offset = self.file_data.find(b'END', offset)
        if end_offset != -1:
            form_data = self.file_data[offset:end_offset+3]
            components = self.parse_dfm_data(form_data)
form_info = FormInfo(
                name=form_name,
                class_name=f"Tform_name",
                unit_name="",  # Would need unit detection
                components=components
            )
            self.forms.append(form_info)
print("[*] Finding event handlers...")
    event_handlers = self.find_event_handlers()
    print(f"[*] Found len(event_handlers) event handler(s)")
return True
def generate_report(self) -> str:
    """Generate a decompilation report"""
    report = []
    report.append("=" * 60)
    report.append("DELPHI DECOMPILER REPORT - DEDE STYLE")
    report.append("=" * 60)
    report.append(f"File: self.file_path")
    report.append(f"Forms Found: len(self.forms)")
    report.append("")
for i, form in enumerate(self.forms):
        report.append(f"\n--- FORM i+1: form.name ---")
        report.append(f"Class: form.class_name")
        report.append(f"Components: len(form.components)")
        report.append("")
for comp in form.components:
            report.append(f"  [+] Component: comp.name (comp.component_type.value)")
if comp.properties:
                report.append(f"      Properties:")
                for prop_name, prop in list(comp.properties.items())[:10]:  # Limit display
                    report.append(f"        - prop_name = prop.value")
if comp.events:
                report.append(f"      Events:")
                for event in comp.events:
                    report.append(f"        - event.event_name -> event.method_name")
if comp.children:
                report.append(f"      Children: len(comp.children)")
return "\n".join(report)
def export_to_dcr(self, output_file: str) -> None:
    """Export to DCR (DeDe format) compatible file"""
    with open(output_file, 'w') as f:
        f.write("[Delphi Decompiler Export]\n")
        f.write(f"File: self.file_path\n\n")
for form in self.forms:
            f.write(f"[Form: form.name]\n")
            f.write(f"Class: form.class_name\n")
            f.write("Components:\n")
for comp in form.components:
                f.write(f"  comp.name = comp.component_type.value\n")
                for prop in comp.properties.values():
                    f.write(f"    prop.name = prop.value\n")
            f.write("\n")

Let us address the elephant in the room. Is using a Delphi decompiler DeDe illegal?

DeDe is a tool of analysis, not theft. Professional developers use it to answer the question: "What does this legacy component do because the documentation is gone?" Malicious actors use it to crack software. The legality rests entirely on intent.