#include<windows.h>
int main()
{
MessageBox(0,0,0,0); //77D5085C
int (__stdcall *pFun)(int,int,int,int,int);//定义函数指针类型的变量
pFun = (int (__stdcall *)(int,int,int,int,int))0x77D5085C;//给函数指针赋值
pFun(0,0,0,0,0);//调用函数
return 0;
}
- 还没学到PE,所以先使用硬编码地址,在MessageBox下断点跟进MessageBoxA函数里。
0040D478 8B F4 mov esi,esp
0040D47A 6A 00 push 0
0040D47C 6A 00 push 0
0040D47E 6A 00 push 0
0040D480 6A 00 push 0
0040D482 FF 15 AC A2 42 00 call dword ptr [__imp__MessageBoxA@16 (0042a2ac)]
0040D488 3B F4 cmp esi,esp
0040D48A E8 E1 3B FF FF call __chkesp (00401070)
- 上面一大段都是检查参数是否合法的,从五个push开始是传参数,到最后一个call是真正调用MessageBox函数,地址就是0x77D5085C,所以函数指针要有五个参数,赋值为0x77D5085C,从最后的ret 10h可以知道是内平栈的,所以要使用stdcall声明调用约定,如果是外平栈的要用cdecl。
77D507EA 8B FF mov edi,edi
77D507EC 55 push ebp
77D507ED 8B EC mov ebp,esp
77D507EF 83 3D BC 14 D7 77 00 cmp dword ptr ds:[77D714BCh],0
77D507F6 74 24 je 77D5081C
77D507F8 64 A1 18 00 00 00 mov eax,fs:[00000018]
77D507FE 6A 00 push 0
77D50800 FF 70 24 push dword ptr [eax+24h]
77D50803 68 24 1B D7 77 push 77D71B24h
77D50808 FF 15 C4 12 D1 77 call dword ptr ds:[77D112C4h]
77D5080E 85 C0 test eax,eax
77D50810 75 0A jne 77D5081C
77D50812 C7 05 20 1B D7 77 01 mov dword ptr ds:[77D71B20h],1
77D5081C 6A 00 push 0
77D5081E FF 75 14 push dword ptr [ebp+14h]
77D50821 FF 75 10 push dword ptr [ebp+10h]
77D50824 FF 75 0C push dword ptr [ebp+0Ch]
77D50827 FF 75 08 push dword ptr [ebp+8]
77D5082A E8 2D 00 00 00 call 77D5085C
77D5082F 5D pop ebp
77D50830 C2 10 00 ret 10h
- 执行程序会弹出两个信息框,如果使用调试工具bp MessageBox下断点只能断下第一个。