#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下断点只能断下第一个。
来源:https://www.cnblogs.com/Kali-Team/p/12182160.html