- AgentConfig.reverse_tools (Settings -> Agents & commands) gives any mode binary_info and decompile; the clean-room check of the tools applies to craft only (ToolCtx.clean_room = clean room && craft). - decompile: optional processor (Ghidra language id) and base_address for raw images (BinaryLoader); separate cache per processor/address. - Skill "reverse-engineering": identify, convert HEX, processor table for common chips, decompile, explore, notes in analysis/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
65 lines
3.9 KiB
Markdown
65 lines
3.9 KiB
Markdown
---
|
||
name: reverse-engineering
|
||
description: Analyse programs and firmware – identify the format, inspect with binary_info, decompile with Ghidra (decompile tool, also raw firmware with processor/base address), explore the output and write down findings. For file formats, protocols, bugs and interoperability.
|
||
---
|
||
# Reverse engineering of programs and firmware
|
||
|
||
You analyse a binary to understand how it works – a file format, a protocol, an algorithm,
|
||
a bug, or how to talk to a device. Work from cheap to expensive and write down what you learn.
|
||
|
||
Only analyse binaries the user owns or may analyse (their own builds, their devices, programs
|
||
for interoperability). Decompiled code is third-party material: never commit it and never paste
|
||
it into the user's source – describe behaviour in your own words.
|
||
|
||
## 1. Identify
|
||
- `file <path>` – format, architecture, stripped or not.
|
||
- Executables and libraries (PE .exe/.dll, ELF, Mach-O): `binary_info` – sections, imports,
|
||
exports, strings. Imports and strings tell a lot (file names, error messages, protocol
|
||
keywords, library names) before any decompiling.
|
||
- Archives and update packages: unpack first (`unzip`, `7z x`), then identify the parts.
|
||
- Intel HEX / S-record firmware: convert to a raw image –
|
||
`objcopy -I ihex -O binary fw.hex fw.bin` (the lowest address in the HEX file is the base
|
||
address). An ELF from the firmware's build (e.g. `zephyr.elf`, `firmware.elf`) is far better
|
||
than a raw image: symbols and addresses are included – look for it first.
|
||
- Raw images: look for clues with `strings -n 6 fw.bin | head -200` and
|
||
`python3 -c` one-liners (vector table, magic numbers, embedded file systems).
|
||
|
||
## 2. Raw firmware: processor and load address
|
||
`decompile` needs both for images without a file format:
|
||
|
||
| Chip family | `processor` | typical `base_address` |
|
||
|---|---|---|
|
||
| ARM Cortex-M (STM32, nRF52, RP2040, SAMD) | `ARM:LE:32:Cortex` | STM32 `0x08000000`, nRF52 `0x00000000`, RP2040 `0x10000000` |
|
||
| ARM Cortex-A / ARMv7 | `ARM:LE:32:v7` | from the bootloader / datasheet |
|
||
| AArch64 | `AARCH64:LE:64:v8A` | |
|
||
| ESP32 (Xtensa) | `Xtensa:LE:32:default` | per segment (use the ELF if possible) |
|
||
| AVR (Arduino) | `AVR8:LE:16:atmega256` or `AVR8:LE:16:default` | `0x0` |
|
||
| MIPS (routers) | `MIPS:BE:32:default` or `MIPS:LE:32:default` | e.g. `0x80000000` |
|
||
|
||
Cortex-M check: the first word of the image is the initial stack pointer (0x2000xxxx = RAM),
|
||
the second the reset vector – it points just behind the base address. If the decompiled output
|
||
is mostly garbage, the processor or base address is wrong: fix it and run again (results are
|
||
cached per file *and* processor/address).
|
||
|
||
## 3. Decompile
|
||
- `decompile` with the path (plus `processor`/`base_address` for raw images). Large programs:
|
||
start with `max_functions` (e.g. 2000), widen when needed.
|
||
- Output in `.codecraft/decompiled/<name>/`: `functions.tsv` (address, name, size, file,
|
||
signature), `functions/*.c`, `strings.tsv`, `imports.tsv`, `exports.tsv`.
|
||
|
||
## 4. Explore
|
||
- Start from what you know: a string, an import or an export.
|
||
`grep -l "SetCommState" .codecraft/decompiled/<name>/functions` finds the functions that use it.
|
||
- Follow the calls by reading the functions; note addresses (`FUN_00401a30`) as you go.
|
||
- Broad searches through thousands of functions: delegate them to an `explore` subagent with a
|
||
precise question and let it report file:line.
|
||
- File formats: compare the reading/writing code with a sample file (`python3` to dump the bytes)
|
||
until every field is explained.
|
||
|
||
## 5. Write it down
|
||
Keep findings in `analysis/notes.md` (create it; it is not committed): structure of the
|
||
program, important functions with addresses, data structures, file formats and protocols with
|
||
field tables, open questions. Make sure `.gitignore` excludes `analysis/`, `original/` and
|
||
`.codecraft/decompiled/`. At the end, report what you found and how sure you are – mark guesses
|
||
as guesses.
|