0

I was reading about mapped and unmapped PE format, and how the alignment between sections changes after loading it into memory and that caused two question for me:

  1. is the relocation table used before the PE is loaded into memory? (just before loading)

  2. how does the loader deal with relative addresses and offsets after loading it into memory considering the offsets between sections changes? for example if i have a instruction that addresses another section using relative addresses (offset from its own location), but not an absolute address, then does the loader has to deal with these relative addresses as well? if so, then this means the relocation table fixes instruction that don't use absolute addresses as well?

  • Relative Virtual Address here Relative is Related to the Virtual Limits of Section do you have a an example snippet for your query the loader checks the load address if it is preferred imagebase it skips relocation else performs fixups relocation table again uses a base address and offsets from the Base address for each section – blabb Oct 19 '19 at 20:16
0

Relocations are processed by the loader, just like imports and everything else in the PE header is. All of this is processed before executing the entry point. Typically speaking relocations will be initially set to the VA (virtual address) of the target using preferred image base address. Of course in many cases the binary will not be loaded at the base address, so it's a simple reloc += (mapped_address - preferred_address).

For example, consider an instruction of mov eax, 0x40100000 assuming a preferred address of 0x40000000. The instruction bytes will be { 0xB8, 0x00, 0x00, 0x10, 0x40 } with offset 0x1 holding the relocation. If the binary is loaded at 0x50000000 then the offset would be (0x50000000 - 0x40000000) = 0x10000000. This would set our example relocation to (0x40100000 + 0x10000000) = 0x50100000.

1

Sections are always mapped to the same location relative to each other (the section table in the file describes the layout, via the VirtualAddress field). Only the starting address for the entire module can change. The relocation table is generally(*) used to update absolute values according to the difference between the starting address that was specified when the program was compiled versus the starting address that is current when the file is loaded.

The file is loaded into memory first, then the starting address is passed to the relocation table parser to apply the relocations.

(*) there are special cases of individual bytes being relocated but only via hand-crafted files. No compiler is going to produce such a thing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.