- #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 [[email protected] (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 下断点只能断下第一个.
来源: http://www.bubuko.com/infodetail-3377110.html