在windbg中細究函數調用

在windbg中細究函數調用

來自專欄 代碼日常寒冷總是短暫的,從西伯利亞吹過來的冷空氣在11月份並沒有停頓多久,便銷聲匿跡。生活總在繼續,編碼無時無刻不在進行。正如張銀奎在他的書中寫道:「如不逢軟體,此生和所用」。無論是c/c++,抑或面向對象的java,我們都會把一個過程分成多個模塊,或者分層。函數這個東西應該是封裝最小的東西,趁著天氣還挺軟和,今天就來詳細的研究下函數調用的道與術。

有圖有實例,今天的測試代碼如下:

代碼不多,主函數裡面調用fun1,嵌套調用fun2。下面該干點啥呢?

fun2函數的反彙編:

又是一天清晨,繼續工作。前面幾句都沒啥區別,很像,但數據又有點不同,代碼不多,乾脆一句一句來分析。

首先函數還沒有開始運行,但是已經由fun1調用fun2,並且也已經跳轉到了fun2當中了,那麼有幾樣東西應該是已經準備好了,一個是fun2執行完要返回的地址,還有一個就是fun2要使用的參數。看一下調用棧:

很明顯可以看到函數調用關係,而且可以看到fun2前面有幾個數值,注意那個RetAddr就是返回地址,而這個返回地址應該是存放在棧上的,查看一下當前棧:

果然就是存放著函數的返回地址。

push ebp:把幀指針入棧,因為下面這句就要用到它了,所以得首先保存

mov ebp, esp:這句就是把當前進程的可用棧指針地址賦值給ebp,在函數裡面我們主要用ebp尋找棧上的東西,如果你樂意,完全可以不用ebp,全用esp。

sub esp, 0D8h:棧指針下移0D8h個位元組,其實就是給這個函數開闢了D8個位元組大小的棧空間。

下面接著三個push指令把三個寄存器的值入棧保存

藍色標記的這一句開始尋找參數了,ebp+8處就是第一個參數的地址了,ebp+0xc處就是第二個地址了,然後fun2裡面新建的連個局部變數被存放在ebp-8,ebp-0x14這兩個地方了。這就是fun2裡面兩條語句的執行情況,執行完之後先強入棧保存的寄存器值得還給他們了,所以依次出棧。接著就到了返回的時刻了:

其實這個時候棧的狀態就和剛進入fun2函數時是一樣的,棧上面保存的第一個數據就是返回地址:

正因為有了這個返回地址,函數才能正常的返回。

思考一下,如何在執行這個函數的時候修改這個返回地址呢?那就是緩衝區溢出了,不多說了。最後上一張自己分析的內存棧構造圖:

推薦閱讀:

魔獸爭霸三 單機遊戲修改器 系列三

TAG:軟體調試 | 反彙編 |