C和汇编混合编程--------函数调用后ebp、esp值问题
今天老師又給了一個程序,讓我們分析,記錄一下分析過程
程序:
結(jié)果:
fun2函數(shù)執(zhí)行了,沒有輸出來end
首先我們來看看為什么fun2執(zhí)行了,將程序反匯編
當執(zhí)行完char aa[4]={0},我們發(fā)現(xiàn)0x0019fed0這個地址存放這個數(shù)據(jù),此時我們看一下0x0019fed4和0x0019fed8內(nèi)的數(shù)據(jù)
當執(zhí)行完strcpy時,0x0019fed0到0x0019fed8存放的內(nèi)容是shellcode的內(nèi)容,為什么是這個數(shù)據(jù),看這篇文章(https://blog.csdn.net/qq_41683305/article/details/104282462),繼續(xù)往下執(zhí)行
當執(zhí)行到ret命令時,我們觀察esp的值,發(fā)現(xiàn)存放的內(nèi)容是00401005,這個是什么?我們找到fun2的地址
發(fā)現(xiàn)和fun2的地址一樣,這就是為什么會執(zhí)行fun2
為什么不會輸出end呢?
下面繼續(xù)分析,按照上面的繼續(xù)執(zhí)行,當執(zhí)行到ret時,此時esp存放的數(shù)據(jù)是00000001,我們會到這個地址執(zhí)行
00000001啥都不是,所以不會執(zhí)行end
下面來解決問題
現(xiàn)在我們來理一理思路,程序先執(zhí)行fun1,然后去執(zhí)行fun2,然后到00000001執(zhí)行,沒有返回來,我們要注意,00000001是我們程序fun1(1,2)中的1,所以我們將1改成我們要fun2執(zhí)行完跳轉(zhuǎn)的地址,就可以繼續(xù)執(zhí)行了,這個地址就是下圖中的地址,跳轉(zhuǎn)到這里繼續(xù)執(zhí)行
我們來改一下,程序:
我們可以看到fun1里填的0x401191不是0x40118e,這是1和0x401191和所占的字節(jié)不同導(dǎo)致的
繼續(xù)報錯,提示堆棧沒有平衡,繼續(xù)分析
我們分析一下,當調(diào)用fun1函數(shù)前,esp的值如圖
fun2執(zhí)行完,執(zhí)行完下圖的add esp,8時,esp的值為
本應(yīng)該執(zhí)行完add esp,8,esp的值應(yīng)該是調(diào)用fun1函數(shù)前的值,結(jié)果差了4,找到原因了,補上:
棧都平衡了,為什么還會報錯呢,這就和檢查有沒有平衡棧的機制有關(guān)了
ebp存放的是調(diào)用函數(shù)前的esp,函數(shù)調(diào)用最后需要平衡棧數(shù)據(jù),也就是將esp還原成調(diào)用函數(shù)前的esp,如果比較ebp和esp相等就不報錯
沒錯還和ebp有關(guān),在執(zhí)行strcpy時,把原來的ebp內(nèi)容修改了,所以會報錯,繼續(xù)改,還原原來的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; }執(zhí)行,完美解決問題
總結(jié):
- 檢查棧有沒有平衡,是根據(jù)ebp和esp的值,有一個修改都要還原
- ebp存放的是調(diào)用函數(shù)前的esp,函數(shù)調(diào)用最后需要平衡棧數(shù)據(jù),也就是將esp還原成調(diào)用函數(shù)前的esp,如果比較ebp和esp相等就不報錯,就是下圖這兩條語句檢查的
- esp和ebp的值最后要相同
中間涉及esp和ebp的值變換,沒有寫了,反匯編調(diào)試注意一下
總結(jié)
以上是生活随笔為你收集整理的C和汇编混合编程--------函数调用后ebp、esp值问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 固原治疗卵巢功能减退最好的医院推荐
- 下一篇: 做个灵魂猎者要多久?我打的困难一天也只能