[ << ALL_FEED ]

Reverse engineering Delphi without IDR

More in General

🛠 Reverse Engineering Delphi without IDR

When you’re actively involved in reverse engineering, sooner or later you encounter an executable file written in Delphi. Analyzing objects in Delphi requires a special approach, and doing it manually is difficult. However, such analysis can be significantly accelerated with automation, if you know exactly how the object structure is organized.

🕵️ The first step when analyzing Delphi — don’t forget to toggle the compiler parameter in Options → Compiler Options → Compiler, then IDA will handle function calls better.

Classes in Delphi are created through the ClassCreate function, which receives a pointer to the class structure as input and calls the Tobject_NewInstance function within it by subtracting an offset from the VMT pointer.

👀 The class structure in Delphi itself looks as follows (example in screenshot 1):


struct DelphiClassInternal
{
  DWORD* vmt;
  DWORD* InterfaceTable; used only for interfaces
  DWORD* PAutoTable; 
  DWORD* PInitTable;  
  DWORD* TypeInfo;
  DWORD* FieldTable;
  DWORD* MethodTable;
  DWORD* DynamicMethodTable;
}
Code language: plaintext (plaintext)


💼 Let’s examine the contents of the TypeInfo, MethodTable, and FieldTable fields in more detail, since they contain the most information useful for analysis.

➡️ TypeInfo

In Delphi, every object type has its own identifier. As seen in screenshot 2, our object has identifier 7 — type Class. Depending on this type, the corresponding context is specified for the object. For classes, this is information about Property and a pointer to the parent type. Knowing the Property name, it’s easy to understand and annotate the Get/Set functions. Recovering these names greatly simplifies the perception of certain code blocks. Example in screenshot 3.

➡️ MethodTable

The attentive reader will notice that in screenshot 1 some method names are present. They can be extracted by looking into the table of published methods (of the current and parent classes). Delphi does not store information about other method types: private, protected, and public. Besides the name, it also provides: the return type, the number of arguments, their types and names.

The pseudo-structure of a method can be represented as follows (example in screenshot 4):


struct CMArg
{
  DWORD* TypeInfo;
  WORD   UNK;
  BYTE   NameLen;
  char   Name[];
  BYTE   UNK2[3];
}
struct ClassPubMethod
{
   WORD   EntrySize;
   DWORD* MethodPtr;
   BYTE   NameLen;
   char   Name[];
   WORD   W_UNK1;
   DWORD* ReturnType;
   WORD   W_UNK2;
   BYTE   ArgCount;
   CMArg  Args[];
}
Code language: plaintext (plaintext)


Due to the method inheritance mechanism in Delphi, recovering even a portion of method names is highly beneficial if done globally, for all classes. This can then be used, among other things, to generate the class VMT structure with meaningful names. Example — in screenshot 5.

➡️ FieldTable

By looking into Class → FieldTable, you can find a large amount of information about variables (example in screenshot 6). It can be presented in two variants:

1. As a name, offset, and variable type number (from the type table). The first two bytes in FieldTable — the number of entries in this table, the next four — a pointer to the type table.

2. As a name, offset, and pointer to the variable type (the table begins immediately after the table from item 1).

The variable structure has the following form:


struct VarTypeTable
{
  WORD   Count;
  DWORD* Entries[];
}
struct ClassVar
{
  DWORD* TypeInfo;
  WORD   VarOffset;
  WORD   UNK;
  BYTE   NameLen;
  char   Name[];
}
struct TableClassVar
{
  WORD VarOffet;
  WORD UNK;
  WORD TableTypeNum;
  BYTE NameLen;
  char Name[];
}
Code language: plaintext (plaintext)


Based on the obtained information about variables, a class structure can be composed (don’t forget that variables are also inherited from parent classes). Example — in screenshot 7.

🤔 Summary: Delphi contains a large amount of RTTI information, thanks to which it is relatively easy to annotate a large number of functions or recover class structures to simplify static analysis.


#TI #Delphi #Reverse
@ptescalator

More from ti_author

More from ti_author

More in General