缓冲区溢出(返回地址)

时间:2011-04-20 11:08:46

标签: c assembly stack buffer-overflow

  

可能重复:
  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中,我检查了函数调用的地址。

 something --> 0x0804827b

main()function()的地址范围 - > 0x080 .....东西。

但在程序中,当我尝试使用&a获取变量的地址时,十六进制地址看起来像0xbfeca ...某事。

为什么这样?我没有得到这背后的原因,所以我甚至无法获得返回地址或更改返回地址。我该怎么办?可能是什么原因?

2 个答案:

答案 0 :(得分:1)

a变量放在堆栈上。它是一个可以运行的局部变量。返回地址也存储在堆栈中。

地址0xbf ......典型的堆栈和地址0x080 .....是代码段的典型值。

要替换返回地址,您应该检查(例如使用gdb)&a附近的内存以找到返回地址(它应该是地址,如0x080 .....)。然后你可以替换它。

答案 1 :(得分:0)

在MSVC下,您拥有_AddressOfReturnAddress(dunno与GCC等效*)内在函数,您可以通过添加要跳过的指令大小来篡改返回地址。但是,对于cdecl函数或者有任何重新排序,失败。同样在你的情况下,p = 100;将被优化。

这样的TBH将是非常不稳定的,可能需要在“登陆站点”编写自定义组件。对于您的情况,最好的选择是用无条件跳转到目标来替换作业。

*但是,根据您的操作系统(其ABI)和使用的调用约定,您可以使用:

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

其中函数为__stdcall__cdecl