};
};
0064FDE0
84 30 41 00 E8 FD 64
„0A.èýd
0064FDE7 00 54 30 41 00 28 FE .T0A.(þ 0064FDEE 64 00 CF 10 40 00 01 d.Ï.@.. 0064FDF5 00 00 00 38 FE 64 00 ...8þd. 0064FDFC D9 27 40 00 01 00 00 Ù'@.... 0064FE03 00 48 02 76 00 98 02 .H.v.˜. 0064FE0A 76 00 68 F1 59 81 48 v.hñY.H |
The first four bytes are pointer to the virtual table. The virtual table itself contains pointers to the virtual functions of the object. In our case, it is a pointer to VirtFunc().
Memory layout of the virtual
table is :
00413084
32 10 40 00 FF FF FF 2.@.ÿÿÿ
0041308B FF DE 2D 40 00 EB 2D ÿÞ-@.ë- 00413092 40 00 00 00 00 00 FF @.....ÿ 00413099 FF FF FF 00 00 00 00 ÿÿÿ.... |
With this information, we
can tweak an object and make it do weird things !! (just for fun)
Let us change the virtual
table pointer and point it to our own table !!!.
//Pointer
to a function returning void
typedef
void (*PFN)();
typedef
struct
{
PFN
Fn;
} VTable;
//The
function which will replace VirtFunc
void
TweakFunc() { cout << "I tweaked the vitual table !!!" << endl
; }
int
main()
{
CDerived
DerivedObj;
CBase
*pBase = &DerivedObj;
//Create
our own virtual table
VTable MyOwnTable;
//Point Fn to TweakFunc
MyOwnTable.Fn
= TweakFunc;
//Holder
for pointer to virtual table
VTable
*pVTable = &MyOwnTable;
//Tweak
the virtual table pointer by changing the first 4 bytes (assuming a long
holds a pointer)
memcpy(&DerivedObj,
&pVTable , sizeof(long));
//Call
the virtual function
pBase->VirtFunc();
//Viola !! TweakFunc() is called
return
0;
}