Monday, February 25, 2019

Reversing C++ codes tutorial series: Inheritance and Dynamic memory

In this post, I will be sharing a key concept in OOP; Inheritance. I will also make use of dynamic memory to store the new objects.

Key takeaways:
1. Identify the differences between object creation of parent from child class.
2. Track the creation of objects using dynamic memory (Heap).

Assumptions
The example code only has a single class and 1 child class. The member functions in class are all static.

Let me begin with this C++ code:


Explanation on what the above code does
Please ignore the commented out codes they will be un-commented for next blog post.

Explanation on what the above code does
The above code first define a "Animal" class. The "Animal" class contains 3 public variables "name", "food" and "legs". It also has 3 member functions. "Animal()" is the constructor while "~Animal()" is the destructor function. "Naming" is a member function implemented to interact with the "name" variable in the object of "Animal" class.

Next is the "Cats" class with 1 public variable "toys". It also have constructor and destructor functions. "Playing" is a member function implemented to interact with the "toys" variable in the object of "Cats" class.

Inside the main function, an object "Generic_Animal" of type class "Animal" is created. And its member function "Naming" is called. Then an object pointed by "pCat1" of type class "Cats" is created. Note that this object is created using the "new" keyword. Finally, the member functions "Naming" and "Playing" are called.


Analysing the compiled version of the above C++ code
Let's look at the main() of the binary.


I have gone ahead to label the constructor of Animal class as "FN_Constructor_Animal", functions related to using of std:string as "FN_String_stuff_XX", function related to use of "New" keyword as "FN_New" and mem copy as FN_MemCopy". If you have trouble understanding how/why I labeled these functions please leave a comment I will explain with more details.

1. Identify the differences between object creation of parent from child class.
For the object of type class "Animal", it is created in the "FN_Constructor_Animal" function.

Next is the creation object of type class "Cats". Very soon after the "FN_New" the "FN_Constructor_Animal" is called. This is because "Cats" is the child class of "Animal". So the object of type "Cats" will first be populated with the members of class "Animal". This is the OOP concept, Inheritance.

Following the "FN_Constructor_Animal" you will see the constructor of "Cats" where the member variables "name" and "food" are overwritten those in "Cats". An additional member variable, "toys" is appended to the object of type "Cats".
This is where you can create the struct for "Animal" and "Cats".


2. Track the creation of objects using dynamic memory (Heap).
Zooming into the construction of object type "Cats"

We notice the use of "FN_New". Inside this function contains a call to malloc(), the key is to note the return address of "FN_New" is in the Heap memory which is used to store dynamically allocated memory. The other thing to note is the value 0x38 at 0x0040127C. This is the size of the object created. So we know the size and address of the object type "Cats".

The following picture show the contents of object type "Cats" in the Heap memory. At 0x00401287 the value of EAX contained the address of the object created in Heap memory.


Next, the constructor of the "Animal" class is called and the member variables and functions are populated. The following happened at 0x00401295 after "FN_Constructor_Animal" is called.


Inside the constructor of the "Cats" class the "name" and "food" member variables are overwritten.(0x004012C4 and 0x004012D3). Do note the member variable "legs" remained unchanged but a new member variable "toys" is appended! (0x04012E1)


Knowing where the object of type "Cats" is created allowed us to trace the changes taken place inside it.

No comments:

Post a Comment