Hacktricks-skills unsafe-relocation-exploitation
Analyze and exploit unsafe relocation fixup vulnerabilities in asset loaders. Use this skill when investigating binary vulnerabilities in game engines, asset parsers, or any software that applies relocation tables to loaded data. Trigger when the user mentions relocation tables, asset loaders, heap corruption, pointer fixups, section arrays, or similar binary exploitation concepts. Make sure to use this skill whenever analyzing asset loading code, relocation handlers, or when the user is researching heap-based exploitation techniques in legacy software.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/binary-exploitation/common-exploiting-problems-unsafe-relocation-fixups/SKILL.MDUnsafe Relocation Fixup Exploitation
A skill for analyzing and exploiting unsafe relocation fixup vulnerabilities in asset loaders and binary parsers.
Overview
Unsafe relocation fixups occur when asset loaders blindly trust attacker-controlled metadata to patch pointers within loaded data. This creates arbitrary read/write primitives that can be weaponized for RCE.
Vulnerability Pattern
The classic unsafe relocation handler:
int *GrannyGRNFixUp_0(DWORD RelocationCount, Relocation *PointerFixupArray, int *SectionArray, char *destination) { while (RelocationCount--) { int target_base = SectionArray[PointerFixupArray->SectionNumber]; // UNCHECKED int *patch_site = (int *)(destination + PointerFixupArray->SectionOffset); // UNCHECKED *patch_site = target_base; if (target_base) *patch_site = target_base + PointerFixupArray->Offset; ++PointerFixupArray; } return SectionArray; }
Critical flaws:
index is never bounds-checkedSectionNumber
is never validated against section sizeSectionOffset- Negative offsets allow walking backwards into allocator metadata
- Oversized indices allow walking outside the section array
Exploitation Methodology
Stage 1: Write Backwards into Loader Metadata
Goal: Use negative offsets to corrupt the section pointer array itself.
Key insight: Custom allocators prepend headers to allocations. By calculating the exact distance between:
- Start of first section buffer
- Section pointer array (stored before first section)
You can craft relocations that write into the pointer array.
Calculation example:
0x20 (header) + 0x20 (section descriptors) + n * 1 (section types) + n * 1 (flags) + n * 4 (pointer table) = 0x4000
Solving for n gives the number of sections needed to position metadata at a specific offset.
Stage 2: Deterministic Heap Layout
Windows 10 NT Heap behavior:
- Allocations ≤ 0x4000 → randomized LFH (Large Free Heap)
- Allocations > 0x4000 → deterministic backend allocator
Strategy:
- Inflate metadata (many empty sections) until allocation > 0x4000
- Preload malicious assets to "prime" heap layout
- Force predictable placement of:
- Allocation #1: metadata + section pointer arrays
- Allocation #2: section 0 contents
- Allocation #3: section 1 contents
Stage 3: Convert to RCE
- Corrupt SectionContentArray[1] using negative offset relocation
- Recycle the corrupted pointer - Section 1's relocation table now uses your injected pointer
- Hit reliable dispatchers - Overwrite function pointers that fire during normal operation:
- Allocator callbacks (Malloc/Free)
- Virtual tables
- Animation dispatchers
- Rendering callbacks
Analysis Checklist
When investigating potential unsafe relocation vulnerabilities:
- Identify asset loaders that maintain SectionArray/relocation tables
- Diff relocation handlers for missing bounds on indices/offsets
- Measure allocator headers from both game wrapper and OS heap
- Calculate backwards offsets precisely
- Force deterministic placement by inflating metadata
- Identify reliable targets - function pointers that will fire
Defensive Considerations
- Always bounds-check relocation indices
- Validate offsets against section sizes
- Use safe integer arithmetic
- Consider ASLR/DEP hardening
- Validate asset metadata before processing