我正在尝试调试使用大量指针的二进制文件。有时为了快速查看输出以找出错误,我打印出对象的地址及其相应的值,但是,对象地址是随机的,这违背了快速检查的目的。 有没有办法临时/永久禁用它,以便每次运行程序时都得到相同的值。
糟糕。操作系统为Linux fsttcs1 2.6.32-28-generic #55-Ubuntu SMP Mon Jan 10 23:42:43 UTC 2011 x86_64 GNU/Linux
答案 0 :(得分:39)
在Ubuntu上,可以使用...
禁用它echo 0 > /proc/sys/kernel/randomize_va_space
在Windows上,这篇文章可能会有所帮助...
http://blog.didierstevens.com/2007/11/20/quickpost-another-funny-vista-trick-with-aslr/
答案 1 :(得分:27)
要暂时禁用特定程序的ASLR,您始终可以发出以下命令(不需要sudo)
setarch `uname -m` -R ./yourProgram
答案 2 :(得分:5)
您也可以在UNIX exec
之前以编程方式从C源代码执行此操作。
如果您查看setarch的来源(此处有一个来源):
http://code.metager.de/source/xref/linux/utils/util-linux/sys-utils/setarch.c
您可以查看是归结为系统调用(syscall
)还是函数调用(取决于系统定义的内容)。来自setarch.c:
#ifndef HAVE_PERSONALITY
# include <syscall.h>
# define personality(pers) ((long)syscall(SYS_personality, pers))
#endif
在我的CentOS 6 64位系统上,看起来它使用了一个函数(可能会调用上面的自相同系统调用)。从/usr/include/sys/personality.h
中的包含文件(在setarch源代码中引用为<sys/personality.h>
)中查看此代码段:
/* Set different ABIs (personalities). */
extern int personality (unsigned long int __persona) __THROW;
归结为,您可以从C代码中调用并设置个性以使用ADDR_NO_RANDOMIZE,然后使用exec
(就像setarch
一样)。
#include <sys/personality.com>
#ifndef HAVE_PERSONALITY
# include <syscall.h>
# define personality(pers) ((long)syscall(SYS_personality, pers))
#endif
...
void mycode()
{
// If requested, turn off the address rand feature right before execing
if (MyGlobalVar_Turn_Address_Randomization_Off) {
personality(ADDR_NO_RANDOMIZE);
}
execvp(argv[0], argv); // ... from set-arch.
}
很明显,你不能在你所处的过程中关闭地址随机化(咧嘴笑:除非动态加载),所以这只会影响以后的分叉和执行。我相信地址随机化标志是由子子进程继承的吗?
无论如何,这是如何以编程方式关闭C源代码中的地址随机化。如果您不希望用户手动干预并使用setarch或之前列出的其他解决方案启动,这可能是您唯一的解决方案。
在您关闭安全问题之前,一些共享内存库/工具(例如PickingTools shared memory和一些IBM databases)需要能够关闭内存地址的随机化。