Address Types in Reverse Engineering
When analyzing a binary you will see several different address spaces. The same byte can be described by each of them depending on which tool you are using. The key types are:
1. File Offset (Raw Offset)
- The number of bytes from the very start of the file on disk.
- Used by hex editors,
hex(), and when you read the file directly with Python. - Example:
offset 0x1234means the byte is 0x1234 bytes from the beginning of the EXE/DLL.
2. RVA (Relative Virtual Address)
- An offset from the image base once the PE is loaded in memory.
- Used heavily in the PE header and in
pefile. - Formula:
RVA = VA - ImageBase - Example: if a section starts at
0x1000RVA, it is 0x1000 bytes from the start of the loaded image.
3. VA (Virtual Address)
- The actual address where something lives when the PE is mapped into memory.
- Used by debuggers, disassemblers, and the running process.
- Formula:
VA = ImageBase + RVA - Example: with
ImageBase = 0x100000andRVA = 0xd17e7c, the VA is0x1117e7c.
4. Image Base (Base Address)
- The preferred starting address where Windows loads the PE file.
- Common defaults:
0x400000for 32-bit,0x140000000for 64-bit, or0x100000for some custom/legacy binaries. - Because of ASLR, the actual load address at runtime may differ. The PE header still stores the preferred base.
5. Section Offset
- An offset inside a specific section, such as
.text,.rdata, or.data. - Useful when you know which section contains the byte and want to keep the math local.
- Formula:
RVA = Section.VirtualAddress + section_offset
6. Relative / PC-Relative Address
- Used in instructions like
jmp +0x50,call +0x1234, orlea rax, [rip + 0x...]on x64. - The target is computed relative to the current instruction pointer (RIP/EIP) or the next instruction.
- Capstone and disassemblers resolve these into absolute VAs for you.
Quick Reference
| Address type | Starts from | Typical tool |
|---|---|---|
| File offset | Start of file | Hex editor, Python file read |
| Section offset | Start of a section | Manual PE analysis |
| RVA | Start of loaded image | PE header, pefile |
| VA | Actual memory address | Debugger, disassembler, Capstone |
| Relative | Current/next instruction | Disassembly, patching jumps |
When to Convert
Use pefile to convert between file offset and RVA:
import pefile
pe = pefile.PE("binary.exe")
file_offset = pe.get_offset_from_rva(0xd17e7c)
rva = pe.get_rva_from_offset(0x1234)
Keep in mind that ASLR can change the actual runtime base address, so the VA computed from the PE header is only the preferred VA.