不说废话,上来高级语言C++的源代码
int _tmain(int argc, _TCHAR* argv[])
{
int a[3]={(int)test,(int)test1,(int)test2};
for(int i=0;i<3;i++)
{
int (*f)();
f=(int(*)())a[i];
f();
}
}
反汇编之后如下:
.text:004010A0 ; int __cdecl wmain(int argc, wchar_t **argv)
.text:004010A0 _wmain proc near ; CODE XREF: __tmainCRTStartup+11Dp
.text:004010A0
.text:004010A0 a = dword ptr -10h
.text:004010A0 var_4 = dword ptr -4
.text:004010A0 argc = dword ptr 8
.text:004010A0 argv = dword ptr 0Ch
.text:004010A0
.text:004010A0 push ebp
.text:004010A1 mov ebp, esp
.text:004010A3 sub esp, 10h
.text:004010A6 mov eax, ___security_cookie
.text:004010AB xor eax, ebp ; cookie
.text:004010AD mov [ebp+var_4], eax
.text:004010B0 push esi
.text:004010B1 mov [ebp+a], offset ?test@@YAHXZ ; test(void)
.text:004010B8 mov [ebp+a+4], offset ?test1@@YAHXZ ; test1(void)
.text:004010BF mov [ebp+a+8], offset ?test2@@YAHXZ ; test2(void)
.text:004010C6 xor esi, esi
.text:004010C8
.text:004010C8 loc_4010C8: ; CODE XREF: _wmain+32j
.text:004010C8 mov eax, [ebp+esi*4+a]
.text:004010CC call eax
.text:004010CE inc esi
.text:004010CF cmp esi, 3
.text:004010D2 jl short loc_4010C8
.text:004010D4 mov ecx, [ebp+var_4]
.text:004010D7 xor ecx, ebp
.text:004010D9 xor eax, eax
.text:004010DB pop esi
.text:004010DC call @__security_check_cookie@4 ; __security_check_cookie(x)
.text:004010E1 mov esp, ebp
.text:004010E3 pop ebp
.text:004010E4 retn
.text:004010E4 _wmain endp
不用考虑,test,test1和test2函数的具体实现,以上汇编代码在IDA中得出,在
.text:004010A0 a = dword ptr -10h
可以看到这是一个局部变量,数组指针,指向test,test1和test2的函数地址
ebp中存放的是主函数的起始地址,而a中的元素是int型,也就是4个字节,所以在
.text:004010B8 mov [ebp+a+4], offset ?test1@@YAHXZ ; test1(void)
中进行的是+4或者+8的操作ebp是主函数的起始地址a是数组的起始地址,在其中每个元素占据内存是4个字节,所以将这三个函数地址放在以a为起始地址的数组当中是
.text:004010B1 mov [ebp+a], offset ?test@@YAHXZ ; test(void)
.text:004010B8 mov [ebp+a+4], offset ?test1@@YAHXZ ; test1(void)
.text:004010BF mov [ebp+a+8], offset ?test2@@YAHXZ ; test2(void)
调用这三个函数则是只需要将三个函数的地址放在一个通用寄存器中然后call eax即可(这是最简单的无参数的调用,嗯有参数的应该也类似,只是笔者还没有学习到...)
另外还有就是
.text:004010A3 sub esp, 10h
这一句将栈顶指针向上移动了10h个位置,其实就是为局部变量开辟的栈空间,esi占据一个,a数组占据3个,也就是一共四个,即0x10h