C和汇编混合编程--------函数调用后ebp、esp值问题
今天老師又給了一個程序,讓我們分析,記錄一下分析過程
程序:
結果:
fun2函數執行了,沒有輸出來end
首先我們來看看為什么fun2執行了,將程序反匯編
當執行完char aa[4]={0},我們發現0x0019fed0這個地址存放這個數據,此時我們看一下0x0019fed4和0x0019fed8內的數據
當執行完strcpy時,0x0019fed0到0x0019fed8存放的內容是shellcode的內容,為什么是這個數據,看這篇文章(https://blog.csdn.net/qq_41683305/article/details/104282462),繼續往下執行
當執行到ret命令時,我們觀察esp的值,發現存放的內容是00401005,這個是什么?我們找到fun2的地址
發現和fun2的地址一樣,這就是為什么會執行fun2
為什么不會輸出end呢?
下面繼續分析,按照上面的繼續執行,當執行到ret時,此時esp存放的數據是00000001,我們會到這個地址執行
00000001啥都不是,所以不會執行end
下面來解決問題
現在我們來理一理思路,程序先執行fun1,然后去執行fun2,然后到00000001執行,沒有返回來,我們要注意,00000001是我們程序fun1(1,2)中的1,所以我們將1改成我們要fun2執行完跳轉的地址,就可以繼續執行了,這個地址就是下圖中的地址,跳轉到這里繼續執行
我們來改一下,程序:
我們可以看到fun1里填的0x401191不是0x40118e,這是1和0x401191和所占的字節不同導致的
繼續報錯,提示堆棧沒有平衡,繼續分析
我們分析一下,當調用fun1函數前,esp的值如圖
fun2執行完,執行完下圖的add esp,8時,esp的值為
本應該執行完add esp,8,esp的值應該是調用fun1函數前的值,結果差了4,找到原因了,補上:
棧都平衡了,為什么還會報錯呢,這就和檢查有沒有平衡棧的機制有關了
ebp存放的是調用函數前的esp,函數調用最后需要平衡棧數據,也就是將esp還原成調用函數前的esp,如果比較ebp和esp相等就不報錯
沒錯還和ebp有關,在執行strcpy時,把原來的ebp內容修改了,所以會報錯,繼續改,還原原來的ebp
#include "stdio.h" #include "string.h"char *shellcode="\x64\x65\x66\x67\x68\x69\x70\x71\x05\x10\x40\x00"; void fun1(int a, int b) {printf("fun1 run!para a=%d,b=%d\n",a,b);char aa[4]={0}; strcpy(aa,shellcode); } void fun2(int a) {printf("fun2 run! para a=%d\n",a);} void fun3(int a,int b,int c) {printf("fun3 run! para a=%d,b=%d,c=%d\n",a,b,c); } int main(int argc, char* argv[]) {printf("begin\n");fun1(0x401191,2);__asm{sub esp,4mov ebp,0x19ff30}printf("end\n");return 0; }執行,完美解決問題
總結:
- 檢查棧有沒有平衡,是根據ebp和esp的值,有一個修改都要還原
- ebp存放的是調用函數前的esp,函數調用最后需要平衡棧數據,也就是將esp還原成調用函數前的esp,如果比較ebp和esp相等就不報錯,就是下圖這兩條語句檢查的
- esp和ebp的值最后要相同
中間涉及esp和ebp的值變換,沒有寫了,反匯編調試注意一下
總結
以上是生活随笔為你收集整理的C和汇编混合编程--------函数调用后ebp、esp值问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 固原治疗卵巢功能减退最好的医院推荐
- 下一篇: 获得jmp esp地址