When Windows maps a PE32+ executable in memory and ASLR is enabled, OptionalHeader.ImageBase is relocated to the virtual address at which the image is loaded. However, this does not happen for PE32 executables (at least under WoW64); OptionalHeader.ImageBase is still the preferred virtual address. Hence when creating a Pe object via PeView::module, for example, the Pe methods that perform VA to RVA translation using this value may end up reading unnacessible or out-of-bounds memory.
I have encountered this issue while trying to use the provided pe32::msvc RTTI structs to extract class names and virtual function tables from a loaded DLL in the same 32-bit process, as these structs have Ptr<T> fields (whose values have been adjusted by the OS due to ASLR).
EDIT: After more testing, it appears that OptionalHeader.ImageBase is normally relocated for 32-bit DLLs as well. I checked a couple 32-bit DLLs but only the one I was initially working with, steamclient.dll from Steam, had this weird behaviour. After inspecting steam_api.dll, which is responsible for loading steamclient.dll, it does so by using a call to LoadLibraryEx with only the LOAD_WITH_ALTERED_SEARCH_PATH flag set. I doubt this should affect how the ImageBase value behaves under ASLR, but did not find any difference in the DLL's headers that should do so either.
When Windows maps a PE32+ executable in memory and ASLR is enabled,
OptionalHeader.ImageBase
is relocated to the virtual address at which the image is loaded. However, this does not happen for PE32 executables (at least under WoW64);OptionalHeader.ImageBase
is still the preferred virtual address. Hence when creating aPe
object viaPeView::module
, for example, thePe
methods that perform VA to RVA translation using this value may end up reading unnacessible or out-of-bounds memory.I have encountered this issue while trying to use the provided
pe32::msvc
RTTI structs to extract class names and virtual function tables from a loaded DLL in the same 32-bit process, as these structs havePtr<T>
fields (whose values have been adjusted by the OS due to ASLR).EDIT: After more testing, it appears that
OptionalHeader.ImageBase
is normally relocated for 32-bit DLLs as well. I checked a couple 32-bit DLLs but only the one I was initially working with,steamclient.dll
from Steam, had this weird behaviour. After inspectingsteam_api.dll
, which is responsible for loadingsteamclient.dll
, it does so by using a call to LoadLibraryEx with only theLOAD_WITH_ALTERED_SEARCH_PATH
flag set. I doubt this should affect how theImageBase
value behaves under ASLR, but did not find any difference in the DLL's headers that should do so either.