PE file format + relocations
-
I'm writing a custom PE loader, and I finished everything except relocations, which I can't find anywhere in the EXE. I'm using Windows's notepad.exe as my initial test. Both the BASERELOC directory entry (DataDirectory[5]) and the PointerToRelocations field of the .text section are set to all 0's. Also, there is no ".reloc" section. Any ideas where these relocations would be located?
-
I'm writing a custom PE loader, and I finished everything except relocations, which I can't find anywhere in the EXE. I'm using Windows's notepad.exe as my initial test. Both the BASERELOC directory entry (DataDirectory[5]) and the PointerToRelocations field of the .text section are set to all 0's. Also, there is no ".reloc" section. Any ideas where these relocations would be located?
Anyone? A possibility is that modern compilers assume the base image address will never change, and forego creating relocations. Can anyone confirm or deny this?
-
I'm writing a custom PE loader, and I finished everything except relocations, which I can't find anywhere in the EXE. I'm using Windows's notepad.exe as my initial test. Both the BASERELOC directory entry (DataDirectory[5]) and the PointerToRelocations field of the .text section are set to all 0's. Also, there is no ".reloc" section. Any ideas where these relocations would be located?
This program will list all the addresses in "Kernel32.dll" that would need relocating if it didn't load at its preferred base address:
// Relocations.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;
int main(int argc, char* argv[])
{
// First get the DOS header.
char *pBase = (char*)GetModuleHandle("kernel32.dll");
PIMAGE_DOS_HEADER pDOS = (PIMAGE_DOS_HEADER)pBase;
assert(pDOS->e_magic == IMAGE_DOS_SIGNATURE);
// Get the NT headers.
PIMAGE_NT_HEADERS pNT = (PIMAGE_NT_HEADERS)(pBase + pDOS->e_lfanew);
assert(pNT->Signature == IMAGE_NT_SIGNATURE);
// Now get the "optional" header.
PIMAGE_OPTIONAL_HEADER pOpt = &(IMAGE_OPTIONAL_HEADER)(pNT->OptionalHeader);
assert(pOpt->Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC);
// Get a pointer to the relocation table and its size.
PIMAGE_DATA_DIRECTORY pRelocDD = &(pOpt->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]);
DWORD SizeOfRelocs = pRelocDD->Size;
PIMAGE_BASE_RELOCATION pReloc = (PIMAGE_BASE_RELOCATION)(pBase + pRelocDD->VirtualAddress);
for (DWORD ToGo = SizeOfRelocs; ToGo>0; /*Empty*/)
{
WORD *pRelocArray = (WORD*)(pReloc + 1);
DWORD NumRelocs = (pReloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
for (DWORD i=0; i<NumRelocs; ++i)
{
WORD val = pRelocArray[i];
WORD Type = val >> 12;
WORD RVA = val & 0x0FFF;
cout << hex << "Type = " << Type << ", Address = " << (DWORD)(pBase + pReloc->VirtualAddress + RVA) << endl;
}
ToGo -= pReloc->SizeOfBlock;
pReloc = (PIMAGE_BASE_RELOCATION)((char*)pReloc + pReloc->SizeOfBlock);
}
return 0;
}See here[^] for for information.
Steve