我在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 ...某事。
为什么这样?我没有得到这背后的原因,所以我甚至无法获得返回地址或更改返回地址。我该怎么办?可能是什么原因?
答案 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
。