class Base { public: virtual ~Base() {} virtual int Magic() { return 9000; } }; class Derived : public Base { public: virtual int Magic() { return 100500; } };
int main() { Derived derived; return derived.Magic(); }
main: # @main movl $100500, %eax # imm = 0x18894 ret
int magic( Base& object ) { return object.Magic(); } int main() { Base* base = new Derived(); int result = magic( *base ); delete base; return result; }
magic(Base&): # @magic(Base&) movq (%rdi), %rax jmpq *(%rax) # TAILCALL main: # @main movl $100500, %eax # imm = 0x18894 ret
main: subq $8, %rsp movl $8, %edi call operator new(unsigned long) movq vtable for Derived+16, (%rax) movq %rax, %rdi call Derived::~Derived() movl $100500, %eax addq $8, %rsp ret
Derived::~Derived(): jmp operator delete(void*)
movq %rax, %rdi call operator delete(void*)
magic(Base&): subq $8, %rsp movq (%rdi), %rax call *(%rax) addq $8, %rsp ret main: pushq %rbp pushq %rbx subq $8, %rsp movl $8, %edi call operator new(unsigned long) movq %rax, %rbx movq vtable for Derived+16, (%rax) movq %rax, %rdi call magic(Base&) movl %eax, %ebp testq %rbx, %rbx je .L12 movq (%rbx), %rax movq %rbx, %rdi call *16(%rax) .L12: movl %ebp, %eax addq $8, %rsp popq %rbx popq %rbp ret
//Classes.h class Base { public: virtual int Magic(); virtual ~Base(); }; class Derived : public Base { public: virtual int Magic(); }; //Classes.cpp #include <Classes.h> #include <stdio.h> Base::~Base() { } int Base::Magic() { return 9000; } int Derived::Magic() { return 100500; } //main.cpp #include <Classes.h> int magic( Base& object ) { return object.Magic(); } int main() { Base* base = new Derived(); int result = magic( *base ); delete base; return result; }
g++ -flto -g -O3 main.cpp Classes.cpp objdump -d -M intel -S --no-show-raw-insn a.exe >a.txt
int main() { 402830: push ebp 402831: mov ebp,esp 402833: and esp,0xfffffff0 402836: sub esp,0x10 402839: call 402050 <___main> Base* base = new Derived(); 40283e: mov DWORD PTR [esp],0x4 ::operator new() 402845: call 4015d8 <__Znwj> vtable 40284a: mov DWORD PTR [eax],0x404058 int result = magic( *base ); delete base; 402850: mov ecx,eax 402852: call 4015c0 <__ZN7DerivedD0Ev> return result; } 402857: mov eax,0x18894 40285c: leave 40285d: ret
//Factory.h #include <Classes.h> class Factory { public: static Base* CreateInstance(); }; //Factory.cpp #include <Factory.h> Base* Factory::CreateInstance() { return new Derived(); } //main.cpp #include <Factory.h> int magic( Base& object ) { return object.Magic(); } int main() { Base* base = Factory::CreateInstance(); int result = magic( *base ); delete base; return result; }
int main() { 402830: push ebp 402831: mov ebp,esp 402833: push esi 402834: push ebx 402835: and esp,0xfffffff0 402838: sub esp,0x10 40283b: call 402050 <___main> return new Derived(); 402840: mov DWORD PTR [esp],0x4 ::operator new() 402847: call 4015d8 <__Znwj> 40284c: mov ebx,eax int magic( Base& object ) { return object.Magic(); 40284e: mov ecx,eax vtable 402850: mov DWORD PTR [eax],0x404058 Derived::Magic() 402856: call 401580 <__ZN7Derived5MagicEv> int main() { delete base; 40285b: mov ecx,ebx 40285d: mov esi,eax 40285f: call 4015b0 <__ZN7DerivedD0Ev> return result; 402864: lea esp,[ebp-0x8] 402867: mov eax,esi 402869: pop ebx 40286a: pop esi 40286b: pop ebp 40286c: ret ( )
402856: call 401580 <__ZN7Derived5MagicEv>
00401580 <__ZN7Derived5MagicEv>: int Derived::Magic() { return 100500; } 401580: mov eax,0x18894 401585: ret
//Factory.h #include <Classes.h> enum ClassType { BaseType, DerivedType }; class Factory { public: static Base* CreateInstance(ClassType classType); }; //Factory.cpp #include <Factory.h> Base* Factory::CreateInstance(ClassType classType) { switch( classType ) { case BaseType: return new Base(); case DerivedType: return new Derived(); } } //main.cpp #include <Factory.h> int magic( Base& object ) { return object.Magic(); } int main() { Base* base = Factory::CreateInstance(DerivedType); int result = magic( *base ); delete base; return result; }
#include <Factory.h> #include <cstdlib> int magic( Base& object ) { return object.Magic(); } int main() { Base* base = Factory::CreateInstance(rand() ? BaseType : DerivedType); int result = magic( *base ); delete base; return result; }
int main() { 402830: push ebp 402831: mov ebp,esp 402833: push esi 402834: push ebx 402835: and esp,0xfffffff0 402838: sub esp,0x10 40283b: call 402050 <___main> Base* base = Factory::CreateInstance(rand() ? BaseType : DerivedType); rand() 402840: call 4027c8 <_rand> Base* Factory::CreateInstance(ClassType classType) { switch( classType ) { switch 402845: test eax,eax 402847: mov DWORD PTR [esp],0x4 40284e: jne 402875 <_main+0x45> rand() , 402875 rand() , ... case DerivedType: return new Derived(); ::operator new() 402850: call 4015d8 <__Znwj> vtable Derived 402855: mov DWORD PTR [eax],0x404070 40285b: mov ebx,eax int magic( Base& object ) { return object.Magic(); - "" , , 402875 (rand() != 0) 40285d: mov eax,DWORD PTR [ebx] 40285f: mov ecx,ebx Magic() 402861: call DWORD PTR [eax] 402863: mov esi,eax int main() { delete base; 402865: mov eax,DWORD PTR [ebx] 402867: mov ecx,ebx 402869: call DWORD PTR [eax+0x8] return result; } 40286c: lea esp,[ebp-0x8] 40286f: mov eax,esi 402871: pop ebx 402872: pop esi 402873: pop ebp 402874: ret Base* Factory::CreateInstance(ClassType classType) { switch( classType ) { case BaseType: return new Base(); 40284e rand() != 0 ::operator new() 402875: call 4015d8 <__Znwj> vtable Base 40287a: mov DWORD PTR [eax],0x404058 402880: mov ebx,eax 402882: jmp 40285d <_main+0x2d>
Source: https://habr.com/ru/post/248429/
All Articles