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 0x1234 means 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 0x1000 RVA, 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 = 0x100000 and RVA = 0xd17e7c, the VA is 0x1117e7c.

4. Image Base (Base Address)

  • The preferred starting address where Windows loads the PE file.
  • Common defaults: 0x400000 for 32-bit, 0x140000000 for 64-bit, or 0x100000 for 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, or lea 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.