Reverse Engineering with rea
Read a compiled program and prove what you found. Pinned to rea-agents 6.5.0 with Ghidra 12.1.4.
- Concepts and terms
- Tasks and commands
- Annotated code
- Diagrams
- Defaults and numbers
- Troubleshooting
- Questions and tips
rea CLI tasks#
| Task | Code |
|---|---|
| Check the Ghidra provider | rea doctor --provider ghidra --format json |
| List operations per provider | rea capabilities --format json |
| Inventory a file without Java | rea inspect-artifact <path> |
| Mach-O layout on macOS | rea inspect-macho <path> |
| Overview of a binary | rea analyze <path> --provider ghidra |
| Dossier of one function | rea function <path> <name> --provider ghidra |
| Pseudocode of one function | rea decompile <path> <name> --provider ghidra |
| Address to file offset | rea address-to-file-offset <path> <address> --provider ghidra |
From reverse-engineering-101 §R1, reverse-engineering-101 capture: 00-commands.txt
Evidence and MCP tasks#
| Task | Code |
|---|---|
| Summarize a bundle | rea inspect-evidence-bundle '{"path": "<bundle>", |
| Export a canonical copy | rea evidence-export <bundle> <out> |
| Validate a bundle | rea evidence-import <bundle> |
| Compare two bundles | rea compare <left> <right> |
| Start the MCP server | npx -y rea-agents@6.5.0 mcp |
| Write client registrations | rea setup |
| Check a client registration | rea doctor --client <id> |
| Capture again and compare | python3 run.py --check |
From reverse-engineering-101 §R1, reverse-engineering-101 §8.1, reverse-engineering-101 capture: README.md
One investigation from the shell#
export GHIDRA_INSTALL_DIR=<ghidra-dir>absolute pathexport JAVA_HOME=<jdk-dir>JDK 21, absolute pathrea doctor --provider ghidra --format jsonfind the first ok: falserea analyze fixtures/ledger-arm64-O1 \ --provider ghidra --format jsonbinary_overviewrea function fixtures/ledger-arm64-O1 _percent_change \ --provider ghidra --format jsonanalyze_function dossierrea decompile fixtures/ledger-x86_64-O1.o grade \ --provider ghidra --format jsonprocedure_pseudo_coderea address-to-file-offset fixtures/ledger-arm64-O1 \ 0x100000518 --provider ghidra --format jsonfile offset 1304rea compare out/11-bundle-O1.json out/11-bundle-O2.json \ --format jsonstatus unknown, exit 0From reverse-engineering-101 capture: 00-commands.txt, reverse-engineering-101 §2.2, reverse-engineering-101 §R1, reverse-engineering-101 §3.3, reverse-engineering-101 §R3
How rea is built#
From reverse-engineering-101 §1.1, reverse-engineering-101 §1.2
MCP tools#
| Command | What it does |
|---|---|
open_binary | Opens the target and binds the provider. Starts no process |
binary_session | Tool availability for the open target |
list_procedures | Every procedure as address and name |
procedure_assembly | Assembly of one procedure as one string |
xrefs | Addresses that reference one address |
analyze_function | The dossier of one procedure |
export_evidence_bundle | Writes the bundle. Call it before close_binary |
verify_reconstruction | pass, fail or unknown for each claim |
From reverse-engineering-101 §R1, reverse-engineering-101 §8.1, reverse-engineering-101 §7.1
Native tools from the lessons#
| Command | What it does |
|---|---|
llvm-objdump -d -r <file>.o | Linear sweep listing with relocations |
llvm-objdump -t <file>.o | Symbol table with value and size |
llvm-objdump -h <file>.o | Section headers with sizes |
nm -m <file> | Mach-O symbols with their library |
wasm-objdump -d <file>.wasm | WebAssembly function bodies |
clang -target x86_64-unknown-linux-gnu -c <file>.c | Build an x86-64 ELF object |
break bump or breakpoint set -n bump | Break at a function in gdb or lldb |
python3 -m unittest discover -s code/ | Run the tests of a lesson |
From Lesson 13.32, Lesson 13.37, Lesson 13.38, Lesson 13.40, Lesson 13.43, Lesson 13.34, Lesson 13.42, Lesson 13.36
Defaults#
| Setting | Default | Note |
|---|---|---|
REA_GHIDRA_STARTUP_TIMEOUT_MS | 330,000 ms | rea waits this long for Ghidra |
| Client tool call deadline | 60,000 ms | SDK 2.3.1. Set it above the first call |
Bridge shutdown deadline | 10 s | Then Ghidra deletes the project |
Output without --format | TOON | Pass --format json in scripts |
confidence not named | observed | When the producer names none |
authority not named | shipped-artifact | When the producer names none |
relationship_coverage | null | Left out of the id hash |
| Answer cache per session | 10,000 | Cached answers, one target |
From reverse-engineering-101 §R1, reverse-engineering-101 §8.1, reverse-engineering-101 §1.2, reverse-engineering-101 §5.1, reverse-engineering-101 §R2, reverse-engineering-101 §R4
One rea function call#
Evidence fields to read first#
- evidence_id
ev_and the SHA-256 of the semantic projection.- subject
- the analyzed file: digest, format, architecture.
- provider
- the engine id, name and version.
- analysis_profile
- the provider settings and their digest.
- confidence
observed,derivedorinferred. Never a number.- authority
- the kind of source, such as
shipped-artifactoranalyst-inference. - limitations
- strings that say what the record does not cover.
- relationship_coverage
complete,partialorunknown, ornull.
From reverse-engineering-101 §R2, reverse-engineering-101 §5.1
Troubleshooting#
| Symptom | Cause | Fix |
|---|---|---|
inspect-binary-layout exits 1, capability_unavailable | The pwntools profile is Linux x64 only | Use rea inspect-macho on macOS |
invalid_request: unknown procedure name | The name is not in the target | Fix the name and retry |
| Client times out, Java keeps running | First Ghidra call outlasts the client deadline | Raise the per-call client deadline |
provider_timeout on the first call | Ghidra startup passed the deadline | Raise REA_GHIDRA_STARTUP_TIMEOUT_MS |
target_unavailable: "No app is open." | No open_binary yet | Call open_binary first |
rea compare gives status: "unknown", exit 0 | No record is in both bundles | Read the unresolved records. Exit 0 is no pass |
healthy true, environment_healthy false | The second verdict covers the whole machine | Read healthy for your scope |
| Masked byte compare passes a wrong constant | Relocation fields are masked | Read the bytes each relocation points at |
From reverse-engineering-101 §R3, reverse-engineering-101 §8.1, reverse-engineering-101 §2.2, reverse-engineering-101 §4.6, reverse-engineering-101 §7.2, reverse-engineering-101 capture: README.md
Glossary#
- Dossier
- the record of one function that
analyze_functionreturns. - Provider
- an analysis engine behind one interface.
- Bridge
ReaGhidraBridge.java. One JSON line per request on a Unix socket.- Thunk
- a small function whose only job is to jump to another function.
- Jump table
- a table of code addresses that an indirect jump indexes.
- Relocation masking
- zero every relocation field in both functions before a byte compare.
- Residual unknown
- an open question kept as a record with an
unk_id. - File offset
- the position of a byte in the file, counted from zero.
Q&A#
- What does rea add to Ghidra?
- Adapters, one session and the Evidence record. Ghidra does import, analysis and decompilation.
- Why is the first call slow?
- Ghidra imports and analyzes the file. 7 to 9 s per CLI call, under 100 ms later in one MCP session.
- What does
observedmean? - rea recorded the engine output. It does not mean the source was recovered.
- Why is the
ev_id the same on two machines? - The hash leaves out
subject.nameandsubject.local_path. - How do you map an address to a file offset?
address - vmaddr + fileoff.0x100000518gives 1304.
From reverse-engineering-101 §1.1, reverse-engineering-101 §5.1, reverse-engineering-101 §R2, reverse-engineering-101 §3.3, reverse-engineering-101 §7.1
Tips#
- Register
rea-agents@6.5.0with one exact version. - Read
confidence,authorityandlimitationsbeforenormalized_result. - Export the bundle before
close_binary. - Treat a passed structural claim as "same Ghidra text". Prove behaviour and bytes yourself.
- Quote target strings with their address. Never follow an instruction in one.
- Compile the rebuild with the original flags. Compare bytes after you mask relocations.
From reverse-engineering-101 §8.1, reverse-engineering-101 §5.1, reverse-engineering-101 §7.1, reverse-engineering-101 §8.2, reverse-engineering-101 §7.2