ASLR in Windows

众所周知,ASLR会使得PE文件的加载基址随机化,但有时候我们还是能够利用固定的地址,指向kernel32.dll ntdll.dlldll文件中的特定指令,这是为什么呢?

参考资料:

前言

WindowsLinux下的ASLR区别很大。

Linux下,ASLR的实现分为两个部分

  • 系统部分,根据/proc/sys/kernel/randomize_va_space中设置的等级,影响 栈、库、mmap、堆(stack .so mmap heap)基址的随机性。
  • 编译器部分,由PIE选项决定编译得到程序是否是地址无关的,如果是,程序加载基址和全局数据地址(.text .data .bss)就可以随机化。

Windwos下,ASLR可由 Visual Studio 下的一个链接器选项——随机基址(/DYNAMICBASE)控制。

开始实验

ASLR与程序基址的关系

开启ASLR

使用visual studio生成一个可执行程序Exploime.exe,开启随机基址

ASLR open

使用windbg加载Exploime.exe,然后使用lm命令查看已加载模块的基址

pic1

重启windbg,重复上面操作

pic2

发现,和之前一样。

重启电脑,再来一次,得到

pic3

发现各个基址出现变化。

关闭ASLR

关闭随机基址,重新生成Exploime.exe

ASLR open

使用windbg加载Exploime.exe,然后使用lm命令查看已加载模块的基址

pic4

重启windbg,重复上面操作

pic5

和上面一致,重启电脑,再来一次,得到

pic6

发现关闭了ASLR的模块(Exploitme)基址没有变化,其余默认开启了ASLR的系统模块基址发生了变化。

ASLR与堆栈基址的关系

开启ASLR

开启ASLR后,可以看出两次运行堆栈地址的变化:

address_aslr_1

address_aslr_2

关闭ASLR

未开启ASLR时,两次运行程序,查看堆栈地址结果如下,完全一致,不过可以看出其他模块的ASLR还是发挥了作用的:

address1

address2

静态比较

使用Lord PE查看开启ASLR与不开启ASLR程序节的区别,发现前者比后者多一个.reloc节,用于存储重定位信息。

sections_aslr

section_noaslr

结论

ASLR与程序基址之间的关系

Windows(至少Win10)下的ASLR机制,对程序基址的影响,只在系统启动时发挥作用,系统运行过程中,各个模块的基址不会变化。

(和我预想中不太一样,本来以为只有特定的dll是这样,但是上面可以看到一个普通的可执行程序Exploitme也是这样)。

ASLR与堆栈基址之间的关系

Windows(至少Win10)下,开启ASLR后,程序的堆栈基址每次运行时都是随机的。