A tool to fix Android ARM64 shared object memory dumps for static analysis.
gosofix processes memory-dumped .so files from Android processes and normalizes them back to valid ELF files that can be analyzed in tools like IDA Pro, Ghidra, or Binary Ninja.
- Base address normalization β Converts absolute virtual addresses back to relative offsets
- Relocation processing β Fixes
R_AARCH64_RELATIVE,GLOB_DAT,JUMP_SLOT, and other relocation types - Section header reconstruction β Rebuilds section headers from dynamic segment information
- Symbol table fixing β Normalizes symbol values and section indices
- Init/Fini array patching β Corrects constructor/destructor function pointers
- Dual interface β Available as CLI binary and shared library (for integration via
dlopen)
# Clone the repository
git clone https://github.com/Arsylk/gosofix.git
cd gosofix
# Build CLI binary
xmake build gosofix
# Build shared library (optional)
xmake build libgosofixBuilt artifacts are placed in the dist/ directory:
dist/gosofixβ CLI executabledist/libgosofix.soβ Shared library
# Basic usage (auto-detect base address from filename)
./gosofix libexample.so_dump_0x7abc123000.so
# Explicit base address
./gosofix -i input.so -m 0x7abc123000 -o output_fixed.so
# With verbose output
./gosofix -v 2 -i input.so -m 0x7abc123000| Flag | Description |
|---|---|
-i |
Input file path |
-m |
Memory base address (hex) |
-o |
Output file path (default: <input>_fix.so) |
-v |
Verbosity level: 0=quiet, 1=info, 2=debug |
--version |
Show version |
# Equivalent forms:
./gosofix dump.so 0x7abc123000 output.so
./gosofix -i dump.so -m 0x7abc123000 -o output.soThe shared library exports a FixElf function for integration:
// C/C++ example
void* lib = dlopen("./libgosofix.so", RTLD_NOW);
typedef char* (*FixElfFunc)(const char*, uint64_t, const char*);
FixElfFunc fix = (FixElfFunc)dlsym(lib, "FixElf");
char* result = fix("/path/to/dump.so", 0x7abc123000, "/path/to/output.so");
// result contains success message or "error: ..."
free(result);When a shared library is loaded into an Android process, the dynamic linker:
- Maps the file at a runtime base address
- Applies relocations (fixing up pointers with the base address)
- Runs initializers
Memory dumps capture the post-relocation state. gosofix reverses this:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Memory Dump (absolute addresses) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Entry: 0x7abc125000 (base + 0x2000) β β
β β GOT[0]: 0x7abc130000 (base + actual_offset) β β
β β init_array[0]: 0x7abc12f000 β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ gosofix (subtract base 0x7abc123000)β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Entry: 0x2000 β β
β β GOT[0]: 0xd000 β β
β β init_array[0]: 0xc000 β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β Fixed ELF (relative offsets) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Component | Transformation |
|---|---|
ELF Header (e_entry) |
Normalize entry point |
Program Headers (p_vaddr, p_paddr) |
Normalize virtual addresses |
| Dynamic Section | Normalize address tags (DT_STRTAB, DT_SYMTAB, etc.) |
Symbol Table (st_value) |
Normalize symbol addresses |
| Relocations | Apply inverse relocation for target locations |
| Init/Fini Arrays | Normalize function pointers |
| Section Headers | Reconstruct from dynamic information |
- ARM64/AArch64 only β No support for x86, ARM32, or other architectures
- Shared objects only β Designed for
ET_DYN(.so) files, not executables - Android memory dumps β Assumes addresses contain the runtime base address
# Run full test suite
xmake test
# Or use the bulk test script
./run_all_tests.shMIT License β See LICENSE for details.
- charmbracelet/log β Styled logging
- ianlancetaylor/demangle β C++ symbol demangling