2012-03-13 75 views
3

我想組裝一個函數的返回地址,然後比較與另一個值返回地址值,而不會破壞堆棧或堆棧進行任何更改,大會返回地址

如何能在組裝完成?

我什麼用STDCALL約定的返回地址存儲在寄存器EBP +4的內容用在x86 86

+0

你一般不能。請指定體系結構,arm,mips,x86等,這是編譯器特有的一個特殊問題。我認爲這是你寫的一個asm函數,等等?請在問題中提供更多細節。 – 2012-03-13 21:30:22

+0

使用x86,有沒有什麼好方法呢?最好的辦法是什麼? – codrgi 2012-03-13 21:57:44

+0

假設返回地址是堆棧中的最後一個東西,並且您可以使用堆棧指針來檢查堆棧指針(假設堆棧指針沒有被修改爲堆棧幀),那麼......仔細檢查它...您會假設需要使用內聯彙編或手動編寫函數來避免另一個調用。所創建的堆棧內容和堆棧框架都是特定於該代碼的編譯器,您不能一般地這樣做,您必須知道編譯器如何創建該特定功能。或者更好,自己創建功能。 – 2012-03-13 22:08:14

回答

6

Usualy。所以cmp ebp, whatever;應該做的工作。實際上,它不依賴於調用約定,而是取決於您的編譯器是否將push ebp作爲您函數的第一條指令,通常它會這樣做。一般功能如下:

push ebp 
mov ebp,esp 
sub esp,size_of_local_variables 
... 
somehting something something 
... 
mov esp, ebp 
pop ebp 
ret 
1

您可以創建一個包裝函數。顯然

function_name: 
    save registers if needed 
    grab the return address here 
    if passed on stack copy parameters 
    call the_real_function 
    if return is stack based place it where needed 
    restore registers if needed 
    return 

不是真正的彙編代碼:

int the_real_function (unsigned int a, unsigned int b) 
{ 
//stuff 
return(something); 
} 

創建彙編幾行。你希望檢查你的函數會重命名,然後asm會有函數的名字,編譯和鏈接,並且所有對函數的調用都會通過包裝器。要編寫上述內容,您必須知道該目標,編譯器,編譯器選項等的調用約定。

1

一般而言,您需要手動或使用您的某些代碼來反彙編有問題的函數,並分析反彙編再次,無論是手動或在代碼中的某種啓發式算法)查看堆棧指針和任何相關的寄存器(例如ebp)或該函數中的變量的行爲,直到開始您的代碼需要返回地址的點。

如果你手工做所有事情,很容易找到返回地址的位置並對其進行硬編碼,但是結果代碼將非常脆弱,因爲任何代碼的變化以及編譯過程中的變化都可能導致代碼崩潰。

OTOH,在代碼中實現一種解決方案,即使代碼發生變化,編譯變化也會非常繁瑣和困難。

你能告訴我們爲什麼你需要返回地址嗎?你試圖用這個解決什麼問題?