恩,识别虚函数调用单靠看调用是不能确定的。。
还得看构造函数时有没有对虚表的初始。。还有结合内存看。
3Q
typedef void (*pFn[4])();
void main()
{
pFn pfn;
int i = 0;
pfn[0] = Fn1;
pfn[1] = Fn2;
pfn[2] = Fn3;
scanf("%d", &i);
pfn[0 + i]();
pfn[1]();
pfn[2]();
return ;
}
00401030 /$ 83EC 14 sub esp, 14 ; 让栈空间出来
00401033 |. 8D4424 00 lea eax, dword ptr [esp]
00401037 |. C74424 00 000>mov dword ptr [esp], 0
0040103F |. 50 push eax
00401040 |. 68 48804000 push 00408048 ; ASCII "%d"
00401045 |. C74424 0C 001>mov dword ptr [esp+C], 00401000 ; fn1函数地址 。esp+C 数组首地址
0040104D |. C74424 10 101>mov dword ptr [esp+10], 00401010 ; fn2函数地址
00401055 |. C74424 14 201>mov dword ptr [esp+14], 00401020 ; fn3函数地址
0040105D |. E8 4F000000 call 004010B1 ; scanf函数,参数分别是上面的两个push。eax和%d
00401062 |. 8B4C24 08 mov ecx, dword ptr [esp+8] ; 取i给ecx
00401066 |. FF548C 0C call dword ptr [esp+ecx*4+C] ; 这里可以提取出来,esp+c+ecx*4,esp+c前面已经看到是数组的首地址,所以是首地址加上偏移访问数组其元素。
0040106A |. E8 A1FFFFFF call 00401010 ; 这两个被编译器直接识别出来了。。优化了。。。
0040106F |. E8 ACFFFFFF call 00401020 ; 这两个被编译器直接识别出来了。。优化了。。。
00401074 |. 83C4 1C add esp, 1C ; 平衡栈空间,sub esp,14.加上两个push = 1c
00401077 \. C3 retn
这样的应该就算数组首地址加偏移访问吧?
大家多多讨论高级语言到汇编下的形式哈。。。
这样对反汇编速度,和能力都会有大大的提高。。
学习。