Reputation: 51
I was analyzing format of one executable file, I found Base relocation table in image_optional_header
, what is this base relocation table?
Upvotes: 5
Views: 11045
Reputation: 1509
The relocation table is a lookup table that lists all parts of the PE file that need patching when the file is loaded at a non-default base address.
Here is the microsoft spec on PE files: https://github.com/tpn/pdfs/blob/master/Microsoft%20Portable%20Executable%20and%20Common%20Object%20File%20Format%20Specification%20-%201999%20(pecoff).doc
And a good article: http://web.archive.org/web/20200806080448/http://www.csn.ul.ie/~caolan/pub/winresdump/winresdump/doc/pefile2.html
Upvotes: 8
Reputation: 4677
There are 2 relocation tables. COFF relocation table, which is only present in .obj files and contains the addresses of the rip-relative offset bytes of all instructions accessing local/extern linkage symbols in the object file, paired with an index into the symbol table to the entry for the symbol it references. The COFF relocation table for the section is pointed to by the section header for the section in the section table after the COFF header.
typedef struct {
unsigned long r_vaddr; /* address of relocation */
unsigned long r_symndx; /* symbol we're adjusting for */
unsigned short r_type; /* type of relocation */
} RELOC; //COFF relocation table entry
For a symbol that is not defined in the object file, it will be an *UNDEF*
entry in the symbol table (the section number will be of the *UNDEF*
section), and the offset from the *UNDEF*
section is always 0. For a symbol that is defined, it will have a correct section and a correct offset into the section in the symbol table, and if the symbol name can't be inlined in the string table entry, it points to the index in the string table for the name of the symbol. The linker will use these section+offsets for the static symbols and the section+offsets of the extern symbols it includes to calculate the correct offset from the end of r_vaddr
to the section+offset of the symbol. It then replaces the address at r_vaddr
with that value i.e. it replaces call -1
or call 0
with the correct relative value
The base relocation table is for runtime and is built in the .obj file and merged into the final .exe and is pointed to by BaseRelocationTable
in the PE header and is usually in .reloc
. If the image is loaded at an address that isn't the ImageBase the linker selected and placed in the PE header, then the patches in the base relocation table need to be applied. The base relocation table is made up of base relocation blocks and each block describes a 4 KiB page. The block header contains the RVA of the page and the size of the block structure. The rest of the block contains an array of 2 byte fields where the first 4 bits of the 2 bytes indicates the relocation type and the latter 12 bits indicates the offset from the page RVA to which the relocation needs to be applied. This will be the offset to an address field in an instruction. To relocate, the loader just calculates the difference between ImageBase and the real base address of the process in the PEB and adds/subtracts it from the address. There won't be many base relocations because most of the symbols in the code use register indirect rip-relative addressing (for mov and dllimport calls) and direct relative addressing (for regular calls). In COFF objects, both relative and absolute addresses need to be relocated, in the PE executable, only absolute addresses need relocations.
typedef struct _IMAGE_BASE_RELOCATION {
DWORD VirtualAddress; //Page RVA
DWORD SizeOfBlock;
WORD TypeOffset[1];
} IMAGE_BASE_RELOCATION; //base relocation table
Upvotes: 4