windows > 大于 vista 实现称为 ASLR(地址空间布局随机化)的安全功能
此功能在每次重新启动时随机更改二进制文件的基地址,以防止依赖于恒定地址的漏洞利用过时
对于 dll,每次启动都会更改基地址
即使地址空间是随机的,也可能会发生冲突,并且二进制文件可能会多次加载到同一个基地址中
假设你有这样的代码
#include <stdio.h>
#include <windows.h>
void main (void) {
char buff[MAX_PATH] = {0};
GetModuleFileName(NULL,buff,MAX_PATH);
printf("%p\t%s\n" , GetModuleHandle(NULL) , buff);
HMODULE hntdll = GetModuleHandle("kernel32");
GetModuleFileName(hntdll,buff,MAX_PATH);
printf("%p\t%s\n" , hntdll , buff);
}
您可以看到二进制文件连续 3 次加载到同一地址,同时第四次更改其基址,您还可以看到 dll 在所有 4 次重新启动时始终加载到同一地址(此地址可能会在重新启动时更改)
C:\Users\printbaseaddr>printbaseaddr.exe
00C80000 C:\Users\printbaseaddr\printbaseaddr.exe
774E0000 C:\Windows\system32\kernel32.dll
C:\Users\printbaseaddr>printbaseaddr.exe
00C80000 C:\Users\printbaseaddr\printbaseaddr.exe
774E0000 C:\Windows\system32\kernel32.dll
C:\Users\printbaseaddr>printbaseaddr.exe
00C80000 C:\Users\printbaseaddr\printbaseaddr.exe
774E0000 C:\Windows\system32\kernel32.dll
C:\Users\printbaseaddr>printbaseaddr.exe
003D0000 C:\Users\printbaseaddr\printbaseaddr.exe <<<<<<<<<
774E0000 C:\Windows\system32\kernel32.dll
您可以使用任何 pe 文件浏览器查看您的二进制文件是否启用了 ASLR,一种方法是使用 dumpbin /headers 并在 Dll 特征中查找动态基础
C:\Users\printbaseaddr>dumpbin /headers printbaseaddr.exe | grep Dyna
Dynamic base
您可以在文件中修补它以禁用可执行文件的 aslr,您会注意到 exe 始终加载在其首选基础中,对于 exe 通常为 0x400000
:\>fc printbaseaddr.exe printbaseaddrmod.exe
Comparing files printbaseaddr.exe and PRINTBASEADDRMOD.EXE
00000156: 40 00
:\>xxd -s 0x154 -l 10 printbaseaddrmod.exe
0000154: 0300 0081 0000 1000 0010 ..........
:\>xxd -s 0x154 -l 10 printbaseaddr.exe
0000154: 0300 4081 0000 1000 0010 ..@.......
:\>echo off
for /L %i in (1,1,10) do printbaseaddrmod.exe
00400000 printbaseaddr\printbaseaddrmod.exe
774E0000 C:\Windows\system32\kernel32.dll
00400000 printbaseaddr\printbaseaddrmod.exe
774E0000 C:\Windows\system32\kernel32.dll
00400000 printbaseaddr\printbaseaddrmod.exe
774E0000 C:\Windows\system32\kernel32.dll
00400000 printbaseaddr\printbaseaddrmod.exe
774E0000 C:\Windows\system32\kernel32.dll
00400000 printbaseaddr\printbaseaddrmod.exe
774E0000 C:\Windows\system32\kernel32.dll
00400000 printbaseaddr\printbaseaddrmod.exe
774E0000 C:\Windows\system32\kernel32.dll
00400000 printbaseaddr\printbaseaddrmod.exe
774E0000 C:\Windows\system32\kernel32.dll
00400000 printbaseaddr\printbaseaddrmod.exe
774E0000 C:\Windows\system32\kernel32.dll
00400000 printbaseaddr\printbaseaddrmod.exe
774E0000 C:\Windows\system32\kernel32.dll
00400000 printbaseaddr\printbaseaddrmod.exe
774E0000 C:\Windows\system32\kernel32.dll