2011-04-20 153 views
0

可能重複:
how to skip a line doing a buffer overflow in c緩衝區溢出(返回地址)

我拆開使用RHEL5上的gdb main()功能。基本上我想要將代碼中的返回地址更改爲其他指令。

場景:

function(int a,int b) 
{ 
    char buffer[16]; 
    //some operations here.. 
} 

int main() 
{ 
    int x = 12; 
    int y =13; 
    int p ; 

    function(x,y); 

    p = 100; 

    printf("%d",p); 
} 

我想跳過P = 100,想跳就printf的電話! 在GDB中我檢查函數調用的地址。 > 0x080 .....東西 -

something --> 0x0804827b 

main()function()地址範圍。

但在程序中,當我嘗試使用&a獲取變量的地址時,十六進制地址看起來像0xbfeca ...。

爲什麼這麼說?我沒有得到這個原因,所以我甚至無法獲取返回地址或更改返回地址。我應該如何繼續?可能是什麼原因?

+0

也許** [這個答案](http://stackoverflow.com/questions/5280789/how-to-skip-a-line-doing-a-buffer-overflow-in-c/5571224#5571224)* * to * [如何跳過在c中執行緩衝區溢出的行](http://stackoverflow.com/q/5280789/203667)*可能有些用處。 – jschmier 2011-04-20 18:35:05

回答

1

a變量放置在堆棧上。這是一個局部變量的功能。返回地址也存儲在堆棧中。

地址0xbf ......通常用於堆棧和地址0x080 .....是代碼段的典型代碼。

要替換返回地址,您應該檢查(例如使用gdb)&a附近的內存以找到返回地址(它應該是地址,如0x080 .....)。然後你可以替換它。

0

在MSVC你有_AddressOfReturnAddress(不知道海灣合作委員會相當於*)的內在,你可以使用添加的跳過指令的大小與返回地址篡改。但失敗的cdecl函數或如果有任何重新排序。也在你的情況下,p = 100;會被優化出來。

TBH這樣的事情會非常情景化,並可能需要在'着陸點'編寫自定義程序集。對於你的情況,最好的選擇是用無條件的跳轉代替你的目標。

*但是取決於你的系統上(其ABI)的操作和使用的調用約定,你可以使用:

void* pAddressOfReturn = (&a) - sizeof(void*); 

其中函數是__stdcall__cdecl