int print_out(int begin, int end) { printf("%d ", begin++); int *p; p = (int*)(int(&begin) - 4); if(begin <= end) *p -= 5; return 1; } int add(int a, int b) { return a+b; } int pass(int a, int b, int c) { char buffer[4] = {0}; int sum = 0; int *ret; ret = (int*)(buffer+28); //(*ret) += 0xA; sum = a + b + c; return sum; } int main() { print_out(0, 2); printf("\n"); int a = 1; int b = 2; int c; c = add(a, b); pass(a, b, c); int __sum; __asm { mov __sum, eax } printf("%d\n", __sum); system("pause"); }
28: int main() 29: { 011C1540 push ebp //压栈,保存ebp,注意push操作隐含esp-4 011C1541 mov ebp,esp //把esp的值传递给ebp,设置当前ebp 011C1543 sub esp,0F0h //给函数开辟空间,范围是(ebp, ebp-0xF0) 011C1549 push ebx 011C154A push esi 011C154B push edi 011C154C lea edi,[ebp-0F0h] //把edi赋值为ebp-0xF0 011C1552 mov ecx,3Ch //函数空间的dword数目,0xF0>>2 = 0x3C 011C1557 mov eax,0CCCCCCCCh 011C155C rep stos dword ptr es:[edi] //rep指令的目的是重复其上面的指令.ECX的值是重复的次数. //STOS指令的作用是将eax中的值拷贝到ES:EDI指向的地址,然后EDI+4
30: print_out(0, 2); 013D155E push 2 //第二个实参压栈 013D1560 push 0 //第一个实参压栈 013D1562 call print_out (13D10FAh)//返回地址压栈,本例中是013D1567,然后调用print_out函数 013D1567 add esp,8 //两个实参出栈 //注意在call命令中,隐含操作是把下一条指令的地址压栈,也就是所谓的返回地址
013D141C mov eax,1 //返回值传入eax中 013D1421 pop edi 013D1422 pop esi 013D1423 pop ebx //寄存器出栈 013D1424 add esp,0D0h //以下3条命令是调用VS的__RTC_CheckEsp,检查栈溢出 013D142A cmp ebp,esp 013D142C call @ILT+315(__RTC_CheckEsp) (13D1140h) 013D1431 mov esp,ebp //ebp的值传给esp,也就是恢复调用前esp的值 013D1433 pop ebp //弹出ebp,恢复ebp的值 013D1434 ret //把返回地址写入EIP中,相当于pop EIP
int *p; p = (int*)(int(&begin) - 4); if(begin <= end) *p -= 5;
013D1560 push 0 //第一个实参压栈 013D1562 call print_out (13D10FAh)//返回地址压栈,本例中是013D1567,然后调用print_out函数 013D1567 add esp,8 //两个实参出栈
http://blog.csdn.net/masefee/article/details/5630154,通过ecx和edx传递参数, 局部变量有数组时使用
转载于:https://www.cnblogs.com/fightformylife/p/4072113.html
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/109672.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...