Fetch and verify the four MAME indy_4610 PROM dumps, wrap the newest dump in an ELF32 BE MIPS image for Ghidra/REA, and record the resulting structural map: image layout, exception vector table, boot flow, function anchors and firmware feature clusters.
90 lines
3.1 KiB
Markdown
90 lines
3.1 KiB
Markdown
# REA setup used for this project
|
|
|
|
[REA](https://github.com/morluto/rea) is the reverse-engineering MCP server and
|
|
CLI used to analyze the Indy PROM. This note records the exact environment so
|
|
the analysis can be reproduced.
|
|
|
|
## Installed components
|
|
|
|
| Component | Version | Location |
|
|
| --- | --- | --- |
|
|
| Node.js | 22.23.4 | `/opt/node-v22.23.4` (`node`, `npm`, `npx` symlinked into `/usr/local/bin`) |
|
|
| REA | 6.8.0 | global npm install; `rea` in `/usr/local/bin` |
|
|
| Ghidra | 12.1.2 | `/opt/ghidra` |
|
|
| JDK | OpenJDK 21.0.13 | `/usr/lib/jvm/java-21-openjdk-amd64` |
|
|
|
|
REA requires Node `^22.23.4 || ^24.22.1 || >=26.12.1`. Debian 13 ships
|
|
Node 20.19, so the official Node 22 tarball was installed under `/opt` instead
|
|
of the distribution package.
|
|
|
|
## Registration
|
|
|
|
The setup was applied for OpenCode only:
|
|
|
|
```bash
|
|
export GHIDRA_INSTALL_DIR=/opt/ghidra
|
|
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
|
|
|
|
rea setup --client opencode --dry-run --json # reviewed plan
|
|
rea setup --client opencode --yes
|
|
```
|
|
|
|
The plan had two actions and no provider installation:
|
|
|
|
- update `/home/arti/.config/opencode/opencode.json` with an MCP server entry
|
|
whose launcher is `/usr/local/bin/rea mcp`;
|
|
- install the bundled `reverse-engineer-anything` skill under
|
|
`~/.agents/skills/reverse-engineer-anything`.
|
|
|
|
Setup preserved the existing `kagi` MCP entry and wrote
|
|
`opencode.json.rea.backup`. OpenCode must be restarted before the MCP server is
|
|
available in a session; the CLI (`rea ...`) works immediately.
|
|
|
|
`rea doctor` after setup reports the Ghidra provider as available with
|
|
`GHIDRA_INSTALL_DIR=/opt/ghidra`.
|
|
|
|
The machine's SSH key is not authorized on the Gitea host, so the git remote
|
|
uses HTTPS with the configured `tea` credential helper:
|
|
|
|
```
|
|
https://git.wut.ee/opencode.energia.arti.ee/sgi-indy.git
|
|
```
|
|
|
|
## The MIPS problem
|
|
|
|
REA 6.8.0's `--target-format raw-binary` lane accepts `x86`, `x86_64`, `arm`,
|
|
`arm64`, `6502` and `m68k` only. There is no raw MIPS architecture. MIPS is
|
|
supported through the Ghidra ELF lane (`docs/ghidra-mips.md` upstream).
|
|
|
|
The Indy PROM is a headerless 512 KiB dump, so the analysis uses
|
|
`tools/make-elf-wrapper.py` to build a load-image-only ELF32 big-endian MIPS
|
|
file:
|
|
|
|
- `e_type = ET_EXEC`, `e_machine = EM_MIPS`;
|
|
- `e_flags = 0x50000000` (`EF_MIPS_ARCH_32`, no ABI bits);
|
|
- no `PT_MIPS_ABIFLAGS` record;
|
|
- one `PT_LOAD` mapping file offset `0x1000` to virtual address `0x1FC00000`;
|
|
- entry point `0x1FC00000`.
|
|
|
|
That combination hits REA's "recordless legacy" admission. REA records that o32
|
|
is an analysis assumption, not a declared ABI fact, and pins Ghidra to
|
|
`MIPS:BE:32:default`. The import log confirms:
|
|
|
|
```
|
|
Using Language/Compiler: MIPS:BE:32:default:default
|
|
```
|
|
|
|
## What was collected
|
|
|
|
The MCP session performed:
|
|
|
|
- `binary_overview` (segments, counts);
|
|
- `list_procedures` (1,074 functions);
|
|
- `list_strings` (1,418 defined strings);
|
|
- `batch_decompile` of the reset path, main entry and exception handlers;
|
|
- `read_function_instructions` for the reset handler and a cache/HPC3 stub;
|
|
- `export_evidence_bundle` to `evidence/rea-bundle.json`.
|
|
|
|
The bundle is a local, git-ignored artifact. `tools/rom-map.py` reads it to
|
|
produce the checked-in JSON map and CSV function index.
|