Assembly Language for Beginners

(Jeff_L) #1

3.18. C++


Let’s compile it again in MSVC 2008 with/Oxand/Ob0options and see thebox::dump()method code:


?dump@box@@QAEXXZ PROC ; box::dump, COMDAT
; _this$ = ecx
mov eax, DWORD PTR [ecx+12]
mov edx, DWORD PTR [ecx+8]
push eax
mov eax, DWORD PTR [ecx+4]
mov ecx, DWORD PTR [ecx]
push edx
push eax
push ecx
; 'this is box. color=%d, width=%d, height=%d, depth=%d', 0aH, 00H
push OFFSET ??_C@_0DG@NCNGAADL@this?5is?5box?4?5color?$DN?$CFd?0?5width?$DN?$CFd?0@
call _printf
add esp, 20
ret 0
?dump@box@@QAEXXZ ENDP ; box::dump


Here is a memory layout of the class:


offset description
+0x0 int color
+0x4 int width
+0x8 int height
+0xC int depth

All fields are private and not allowed to be accessed from any other function, but knowing this layout, can
we create code that modifies these fields?


To do this we’ll add thehack_oop_encapsulation()function, which is not going to compile if it looked
like this:


void hack_oop_encapsulation(class box * o)
{
o->width=1; // that code can't be compiled':
// "error C2248: 'box::width' : cannot access private member declared in class ⤦
Ç'box'"
};


Nevertheless, if we cast theboxtype to apointer to an int array, and we modify the array ofint-s that we
have, we can succeed.


void hack_oop_encapsulation(class box o)
{
unsigned int
ptr_to_object=reinterpret_cast<unsigned int*>(o);
ptr_to_object[1]=123;
};


This function’s code is very simple—it can be said that the function takes a pointer to an array ofint-s for
input and writes 123 to the secondint:


?hack_oop_encapsulation@@YAXPAVbox@@@Z PROC ; hack_oop_encapsulation
mov eax, DWORD PTR _o$[esp-4]
mov DWORD PTR [eax+4], 123
ret 0
?hack_oop_encapsulation@@YAXPAVbox@@@Z ENDP ; hack_oop_encapsulation


Let’s check how it works:


int main()
{
box b(1, 10, 20, 30);


b.dump();

hack_oop_encapsulation(&b);

b.dump();
Free download pdf