2011-04-20 151 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