Tool: Ghidra RE Environment
Static analysis and decompilation of firmware binaries. Used for ABL analysis (Phase 03a) and EPDC ioctl reverse engineering (Phase 03b).
Environment
| Item | Value |
|---|---|
| Docker image | ghidra-re:latest |
| Dockerfile | tools/docker/ghidra-re/Dockerfile |
| Ghidra version | 11.1.2 |
| Java | OpenJDK 21 |
| Run script | tools/ghidra-run |
| Project volume | Docker volume ghidra-projects (persistent) |
Usage
# Launch Ghidra GUI (X11 via XAUTHORITY)
./tools/ghidra-run
# Drop into analysis shell
./tools/ghidra-run bash
The run script uses --network=host and mounts $XAUTHORITY. Ghidra must be launched in foreground mode — the ghidraRun wrapper uses bg mode and exits immediately, killing the container. The tools/ghidra-run script invokes the foreground form directly.
Importing the ABL
The stock abl.bin is an ELF32 wrapper containing a UEFI Firmware Volume with an LZMA-compressed PE/COFF. Do NOT import abl.bin directly.
Import file: /firmware/ghidra-work/abl_pe.efi
Format: Portable Executable (PE)
Language: AARCH64:LE:64:v8A
# abl.bin structure:
# ELF32 LOAD → UEFI FV → FFS → GUID section (LZMA) → decompressed blob → PE at offset 0xb8
# Extraction (inside ghidra-run bash):
python3 - << 'EOF'
import lzma
data = open('/backup/abl.bin', 'rb').read()
comp = data[0x3078 : 0x3060 + 0x1b094]
decomp = lzma.decompress(comp)
open('/firmware/ghidra-work/abl_pe.efi', 'wb').write(decomp[0xb8:])
EOF
Key RE Findings
ABL (abl_pe.efi)
| Address | Name | Notes |
|---|---|---|
| 0x00014228 | Battery check | Returns 1=ok/0=fail before flash ops |
| 0x00025770 | AcceptData | USB bulk receive callback |
| 0x00029b10 | CmdDownload | Handles download:XXXXXXXX fastboot cmd |
Kernel EPDC (onyx_epdc_fb)
| Offset | Symbol/Purpose |
|---|---|
| 0x427a8c | onyx_waveform_mode_transform (A2→GC16 conversion) |
| 0x41d410 | BL to transform — NOP here to disable transform |
| 0x427bc8 | map_auto_mode (AUTO→GC16) |
| 0x41eaf8 | ioctl dispatch table (34 entries) |