返回地址相关
函数的返回地址保存在[ESP]中,第一个参数保存在[ESP+4]中,第二个参数保存在[ESP+8]中,以此类推
于是可以写出这样一段东西出来:
1 #include<stdio.h> 2 #include<stdlib.h> 3 void hello(int x); 4 void f(int x); 5 int main(){ 6 f(0); 7 return 0; 8 } 9 void hello(int x){ 10 printf("Hello, World!"); 11 int esp=(int)&x-4; 12 *((int*)esp)=(int)main+26; 13 } 14 void f(int x){ 15 int esp=(int)&x-4; 16 *((int*)esp)=(int)hello; 17 }
第12行处的main+26实际上就是main中return 0的位置(我用的32位编译,64位编译结果可能不同),可以通过反汇编再查.lst文件,数一下字节数得出
9 [SECTION .text] 10 00000000 GLOBAL _main 11 00000000 _main: 12 00000000 55 PUSH EBP 13 00000001 89 E5 MOV EBP,ESP 14 00000003 83 E4 F0 AND ESP,-16 15 00000006 83 EC 10 SUB ESP,16 16 00000009 E8 [00000000] CALL ___main 17 0000000E C7 04 24 00000000 MOV DWORD [ESP],0 18 00000015 E8 00000031 CALL __Z1fi 19 0000001A B8 00000000 MOV EAX,0 20 0000001F C9 LEAVE 21 00000020 C3 RET