这是我正在使用的一些代码的简化版本:
int Do_A_Thing(void)
{
return(42);
}
void Some_Function(void)
{
int (*fn_do_thing)(void) = Do_A_Thing;
fn_do_thing();
}
当我在xcode 4.1中编译它时,它生成的汇编器会像这样设置fn_do_thing变量:
0x2006: calll 0x200b ;
0x200b: popl %eax ; get EIP
0x200c: movl 1333(%eax), %eax
即。它为该地点生成一个相对地址,以找到Do_A_Thing函数 - “当前指令加上1333”,根据映射文件是该函数的“非惰性指针”。
当我使用Visual Studio在Windows上编译类似的代码时,Windows会生成一个固定的地址,而不是像这样做。如果Do_A_Thing位于例如0x40050914,则它只将fn_do_thing设置为0x40050914。相比之下,xcode将其设置为“我在哪里+某些偏移”。
有没有办法让xcode生成一个绝对地址来设置函数指针,就像visual studio一样?或者有什么理由不起作用?我注意到每次运行程序时,Do_A_Thing函数(以及所有其他函数)似乎都加载到不同的地址。
答案 0 :(得分:3)
您正在考虑与位置无关的代码(更具体地说是位置独立可执行文件)。正如您所注意到的,这允许操作系统在内存中的任何位置加载二进制文件,这为潜在的不安全代码提供了许多安全性改进。
您可以通过删除XCode中的链接器选项(-Wl,-pie
)来禁用它。
请注意,在x86_64(amd64)上,指令可以相对于指令指针进行操作,这可以提高此技术的效率(并使其在性能成本方面基本上“免费”)。