Wednesday, March 1, 2023

Reverse Engineering Notes - Objects Creation

 Basic Constructor - Assembly

 Constructor is a function that is tasked with setting up an objects structure in memory. This is the first function that will be called when we create an object.

  • How can you recognize a constructor in assembly?
  • inheritance from vtable in the first bytes (4 bytes for x86 and 8 bytes for x64)
  • object members are stored in the object structure memory
  • If there is inheritance we can see a call to the base class constructor
  • May be another function call inside constructor to another constructor

Constructor's parameters:
Name(char* - pointer - 8 bytes)
Age(int - 4 bytes)
push    rbp
mov    rbp, rsp
mov    [rbp+this], rdi  ; "this" is stored onto stack
mov    [rbp+name], rsi 

; "This" pointer is the first parameter passed for every object's function(constructor, destructor and any other function)

mov    [rbp+age], edx
mov    rax, [rbp+this]    ; storing the "name" provided
mov    rdx, [rbp+name] ; at offset 0x0 in
mov    [rax], rdx ; the objects structure

Copy Constructor

Copies an object from a previously created one.

Constructors in C++ have a certain pattern that can help you recognize them in disassembled code. In C++, constructors are special functions that have the same name as the class they belong to and do not have a return type. They are also typically called when an object is created.

Here's an example of a simple C++ class and its constructor:

class MyClass { public: MyClass() { // Constructor code goes here } // Other class methods go here };

In disassembled code, you can recognize a constructor by its name, which should be the same as the class name. For example, if the class name is MyClass, the constructor name should be _ZN7MyClassC1Ev (for a constructor with no parameters) or _ZN7MyClassC2Ev (for a constructor with default parameters). The C1 and C2 represent the constructor and the Ev stands for "void" (i.e., no parameters).

You can also look for the call instruction that corresponds to the constructor call. This should be located in the code that creates the object, which may be in a function that is not the constructor itself. The call instruction should have the constructor's name as its operand.

In addition, constructors may have certain characteristics that can help you identify them. For example, constructors often initialize member variables and allocate memory for the object. You may also see calls to other functions that are part of the object initialization process.

Overall, recognizing constructors in disassembled code requires some knowledge of C++ syntax and programming concepts. Once you know what to look for, you can use Radare2's disassembly view and call stack to locate and analyze constructors.

Defining Objects

object structure in memeory. One type has virtual functions inherited or defined with a VTABLE in the first 4 to 8 bytes of the objects structure in memory.  All the members of the object in data where we don't have virtual tables and we will only see the members of the object in memory.

To find the object structure in Cutter, you can use the Classes view, which displays the classes and their respective methods.

  1. Open the Classes view by clicking on the Classes button in the sidebar or by pressing Ctrl + 2.

  2. In the Classes view, you will see a list of classes. Select the class you want to view the object structure for.

  3. Once you have selected the class, you can view its methods and attributes in the Methods and Attributes tabs at the bottom of the Classes view.

  4. To view the object structure, you can right-click on an instance of the class in the disassembly view and select Follow Pointer -> to Object. This will open a new tab that displays the object's structure.

Alternatively, you can use the Graph view to visualize the object structure. Right-click on an instance of the class in the disassembly view and select Follow Pointer -> to Graph. This will open a new tab that displays a graph of the object's structure. You can use the graph to navigate through the object's fields and their relationships.


No comments:

Post a Comment

A Guide to Multi-Level Pointer Analysis

  A Comprehensive Guide to Multi-Level Pointer Analysis   A regular pointer points to only one address, but when it's accompanied by a l...