windows > greater than vista implement a security feature called ASLR (Address Space Layout Randomisation )
this feature randomly changes the Base Address of the binary each time it is restarted this prevents constant address dependent exploits obsolete
for dlls the base address is changed per boot
even though the address space is randomised there can be clashes and the binary might be loaded in the same base address several times
suppose you have code like this
#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);
}
you can see the binary is loaded in the same address 3 times consecutively while changing its base the fourth time also you can see the dll is always loaded in same address on all 4 restarts (this address may change on rebooting )
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
you can see if your binary is ASLR enabled using any pe file explorer
one way is to use dumpbin /headers and look for Dynamic Base in Dll Characteristics
C:\Users\printbaseaddr>dumpbin /headers printbaseaddr.exe | grep Dyna
Dynamic base
you can patch this in the file to diasble aslr for an executable and you will notice the exe is always loaded in its prefferred base which for an exe is normally 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