gpt4 book ai didi

c - 为什么 Windows 不继续随机化我的可执行文件的基地址?

转载 作者:可可西里 更新时间:2023-11-01 13:12:59 26 4
gpt4 key购买 nike

我制作了一个简单的 C 程序,它在执行时简单地打印 main() 的地址:

printf("%08X\n", &main);

我用 Visual C++ 2015 用参数 /DYNAMICBASE 为 x86 编译它(为 x64 编译时发生同样的事情)。

前两次我运行它,返回的地址不同,正如预期的那样。但是,两次之后,程序返回的地址还是一样的:

00C31050
00221050
00221050
00221050

重新编译或重命名可执行文件会再次随机化地址。

这里发生了什么? Windows 是否以某种方式缓存可执行文件?

最佳答案

首先,您不需要获取函数地址,并且指针最好使用 %p 说明符打印,这有助于编译器检查类型。更准确的代码是:

printf ("%p\n", main);

关于主题,ASLR technology ,负责重新定位可执行镜像是一项操作系统功能,旨在通过降低地址的可预测性来抵御缓冲区溢出攻击。 它不保证对于两次连续运行,图像将被放置在不同的位置,但操作系统会尝试不时改 rebase 础,这取决于许多因素.对于我的测试,我在编译后立即在 Windows-7 32 位构建中获得了以下结果,连续运行 10 次:

00BE1260
00BE1260
00221260
00F71260
01391260
01391260
01391260
01391260
01391260
003A1260

如您所见,即使连续运行放置在相同的位置,基地也会在一段时间后改变。可以保证的是,不支持动态库的可执行镜像将始终放置在库中,由链接器在 exe 头文件中设置。可执行镜像的默认基数是 400000h,因此打印的值将是这样的:

00401260
00401260
00401260
00401260
00401260
...

至于您的情况,我认为操作系统 rebase 算法更具预测性,因为操作系统算法处理攻击威胁的可能性较小或由于缺乏熵或资源。 rebase 需要额外的时间和资源来重新映射内存页面和调整重定位,因此操作系统可能会决定在您的情况下不需要频繁 rebase 。

当然,Windows 会缓存加载的可执行文件以加快其启动速度。这就是为什么下一次运行时碱基不会改变的概率足够高的原因。如果您有足够的 RAM,则用于缓存的 RAM 越多,该图像就越有可能不会被重新定位。如果图像完全重新加载,则没有理由保持相同的基础。此外, rebase 策略可能因操作系统版本而异。

关于缓存。它不仅是功能上的缓存。如果图像被加载到内存中,它可以同时用于多个进程(实例)。这些实例可以安全地共享代码页,因为代码是只读的。这是 Windows 在进程终止后不立即“卸载”图像的主要原因之一。但是只有当代码调整到相同的基础时,两个进程才能共享代码,因为重定位会修补内存中的代码。如果我们强制不同的进程重新定位,我们不可避免地需要放弃代码共享,这将导致 RAM 消耗增加。

编辑:

顺便说一句,我发现/DYNAMICBASE 选项被 VS2015 忽略,并且链接器总是生成支持 ASLR 的可执行镜像,即使我明确设置/DYNAMICBASE:NO。逐位比较还表明,除了一个时间戳和(作为结果)校验和之外,编译的文件是相同的。要在没有 ASLR 支持的情况下获得由 VS2015 构建的可执行文件,我必须手动删除 exe-header 中的 IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 位。不知道是故意的还是微软的bug。

关于c - 为什么 Windows 不继续随机化我的可执行文件的基地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44842899/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com