首先,我想說我在裝配中有足夠的背景知道大部分需要知道的功能組裝程序員。不幸的是,我不明白Windows API調用的返回地址是如何工作的。如何在Windows函數調用中設置堆棧?
下面是使用被寫入氣體裝置用於Windows的某些示例代碼的MinGW的作爲作爲彙編和MinGW的LD作爲接頭...
.extern [email protected]
.text
.globl _main
_main:
pushl $0
call [email protected]
此代碼編譯和組裝後運行...
as program.s -o program.o
和聯繫吧...
ld program.o -o program.exe -lkernel32
從我的理解中,Windows API通過推送指令調用參數,如上所述。然後在通話過程中;
call [email protected]
函數的返回地址放在堆棧上。然後,這就是我困惑的地方,函數將所有參數從堆棧中彈出。
我很困惑,因爲,由於堆棧是最後一個先出,在我腦海中彈出堆棧上的參數時,它會首先彈出返回地址。論點首先出現,接下來的回覆地址就是這樣,所以技術上首先會彈出。
我的問題是,通過推送操作將參數傳遞給函數調用和放置在堆棧上的返回地址之後,堆棧的佈局是什麼樣的?當函數執行時,參數和返回地址如何從堆棧中彈出?最後,返回地址如何從堆棧中彈出,函數調用返回到返回地址中指定的地址?
不好的例子,ExitProcess()根本不應該返回。 –
它不會返回值,但它在堆棧上有返回地址。當它通過ret指令返回時(最後一次檢查爲\ xc3),它會將返回值從堆棧中彈出並將執行流程指向Windows API,然後再次將執行指向執行到下一條指令,該指令位於開始函數調用的調用指令之後第一名。 – August
正如Turbo J所說,ExitProcess永遠不會返回。堆棧中有一個返回地址,但它從來沒有使用過,並且該函數從不執行RET指令。正如函數的名稱所示,該函數會導致進程退出,這意味着它無法返回給調用方,因爲調用方將不再存在。 –