深入浅出根据函数调用过程谈栈回溯原理
?
???????????? ? ? ? 通過分析函數調用過程的堆棧變化,可以看出在被調函數的EBP寄存器地址存放的是調用函數的EBP寄存器地址,EBP地址+4存放的是函數調用完成后的下一條指令存放地址,該指令的前一條指令則是調用函數的指令。說起來有點拗口,接下來代碼分析一下:
? ? ? ? 分析使用的源碼如下:
[cpp] view plaincopyprint?在函數FunA內的任意位置添加斷點,然后執行代碼,則會在該處停住,通過VS的cmd窗口分析步驟如下:
1、? 查看寄存器值,得出EBP=0x002FF734
2、? 根據該EBP,找到FuncA返回后的指令執行地址0x0005142B
3、? 因為CALL函數執行的機器碼=call機器碼(1個字節)+函數地址(4個字節),得出call funcA這條指令的執行地址為0x00051426(0x0005142B-5)
4、? 得出指令機器碼為e8 6b fc ff ff
5、? 機器碼算出調用指令地址 0Xfffffc6B+5(五個字節)+0x00051426(call指令地址)=0x00051096
6、? 查看0x00051096地址得出機器碼 e9 25 0300 00,該機器碼顯示為jmp指令
7、 ?再通過計算0x000325+5+0x0005196=0x000513c0最終得出調用函數的地址。在VS2008窗口中分析命令如下:
通過實際查看FunA的函數入口位置如下所示:
? ? ? ? 通過以上分析可以得出FunA函數的調用地址,但是整個過程是沒辦法知道函數的名稱的,知道函數名稱需要使用.pdb(symbol文件:在編譯過程中生成的符號文件)。這邊就不分析了。
? ? ? ? 所以通過EBP加函數返回的指令地址可以一步一步的回溯整個過程的函數調用關系,也就是所謂的棧回溯原理了。
? ? ? ? 好吧,原理歸原理,我們還是乖乖的命令窗口敲下>kb命令看看整個的函數調用過程吧。
? ? ? ? ?可以看出到后面VS也沒法知道整個系統的符號文件,只能給出一個地址。
? ? ? ? ?至此棧回溯原理分析結束,若有問題,請幫忙指出,不勝感激。 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的深入浅出根据函数调用过程谈栈回溯原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Winsock网络编程快速入门
- 下一篇: 函数调用 压栈的工作原理