Every time I restart windows it breaks the patch I've made to an executable where I've called a function from the dll user32.dll. Currently the offset for the function call resides at 0x76E3CDB4, but when I restart my computer it will change to some other address. Why is this and what can I do to make sure my assembly code will always call the function properly?
1 Answer
This may be due to Address Space Layout Randomization aka ASLR (e.g. see this overview by Symantec)
System modules' load addresses are randomized on each boot and executable images' are randomized on each execution in OS > Vista
you can check that with some simple code like this
:\>cat aslr.cpp
#include <windows.h>
#include <stdio.h>
void main (void)
{
HMODULE hMod = LoadLibraryA("user32.dll");
if(hMod){
printf("My Load Addr\t%p My user Addr\t%p\n" , &main,hMod);
FreeLibrary(hMod);
}
}
compiled and executed the result as follows
:\>for /L %i in (1,1,10) do aslr.exe
:\>aslr.exe
My Load Addr 00121000 My user Addr 773A0000
:\>aslr.exe
My Load Addr 00031000 My user Addr 773A0000
:\>aslr.exe
My Load Addr 00FB1000 My user Addr 773A0000
:\>aslr.exe
My Load Addr 002F1000 My user Addr 773A0000
:\>aslr.exe
My Load Addr 011B1000 My user Addr 773A0000
:\>aslr.exe
My Load Addr 011B1000 My user Addr 773A0000
:\>aslr.exe
My Load Addr 011B1000 My user Addr 773A0000
:\>aslr.exe
My Load Addr 011B1000 My user Addr 773A0000
:\>aslr.exe
My Load Addr 00181000 My user Addr 773A0000
:\>aslr.exe
My Load Addr 01121000 My user Addr 773A0000
to be sure you patch right you should work with RVA (Relative Virtual Address)
that is get the base of module every time and add a fixed offset that you determined earlier every time
suppose you patched @ 0x12345678 and when you patched the module was loaded at 0x10000000 then you have a difference of 0x2345678
next time if the module was loaded at 0x20000000 you use the address 0x20000000+0x2345678 == 0x22345678