深入淺出》根據函式呼叫過程談棧回溯原理

2021-07-30 16:23:41 字數 1485 閱讀 3151

通過分析函式呼叫過程的堆疊變化,可以看出在被調函式的ebp暫存器位址存放的是呼叫函式的ebp暫存器位址,ebp位址+4存放的是函式呼叫完成後的下一條指令存放位址,該指令的前一條指令則是呼叫函式的指令。說起來有點拗口,接下來**分析一下:

分析使用的原始碼如下:

[cpp]view plain

copy

print

?int _cdecl funa(int a, int b)  

int _cdecl funb(int a, int b)  

int _cdecl func(int a, int b)  

int _cdecl main(int argc, char* argv)    

int _cdecl funa(int a, int b)

int _cdecl funb(int a, int b)

int _cdecl func(int a, int b)

int _cdecl main(int argc, char* argv)

在函式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的函式入口位置如下所示:

所以通過ebp加函式返回的指令位址可以一步一步的回溯整個過程的函式呼叫關係,也就是所謂的棧回溯原理了。

好吧,原理歸原理,我們還是乖乖的命令視窗敲下》kb命令看看整個的函式呼叫過程吧。

可以看出到後面vs也沒法知道整個系統的符號檔案,只能給出乙個位址。

至此棧回溯原理分析結束,若有問題,請幫忙指出,不勝感激。



《深入淺出》函式呼叫過程堆疊變化分析

總是被問及函式呼叫過程中堆疊的變化以及棧回溯的原理,最近好好的研究了一下函式呼叫過程中各個暫存器和堆疊狀態的變化,在這邊分享一下,如果有不對的地方,希望得到指正,本文使用vs2008工具執行下面這段 執行,並將各個過程中堆疊資料的變化記下。如下 int cdecl fund int a,int b ...

深入淺出談GIS 測繪

首先我們通過對全球測繪地理資訊裝備產品 技術體系進行系統梳理,一起看看先進的空天地一體化對地觀測體系的測繪地理資訊裝備的生態鏈,見下圖 載波相位差分技術又稱rtk real time kinematic 技術,是實時處理兩個測站載波相位觀測量的差分方法。即是將基準站採集的載波相位發給使用者接收機,進...

深入淺出談Android 幾種布局方式

我們對android應用程式執行原理及布局檔案可謂有了比較深刻的認識和理解,並且用 hello world!程式來實踐證明了。在繼續深入android開發之旅之前,有必要解決前兩篇中沒有介紹的遺留問題 view的幾種布局顯示方法,以後就不會在針對布局方面做過多的介紹。view的布局顯示方式有下面幾種...