server-re/AGENTS.md
2026-10-15 09:08:48 -04:00

130 lines
7.4 KiB
Markdown

# AGENTS.md
## Project overview
Reverse-engineering project for the Rusty Hearts game server/client binaries
(Windows PE32+ x86-64). Analysis is performed with **Ghidra** (headless or GUI)
driven through **REA** (`reverse-engineer-anything` skill + `rea-agents` MCP
server). There is no application source code here — the binaries are the
primary evidence.
The server binaries are **C++** (MSVC 2010, x64). See
[`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the evidence and what is known
about their structure.
All servers share one in-house framework (`Magi*`): server-kind enum,
startup modes, XML option files and DB access via DBC servers. See
[`docs/SHARED_FRAMEWORK.md`](docs/SHARED_FRAMEWORK.md) and check each new
binary against it instead of re-deriving it.
Config file definitions: [`docs/CONFIG.md`](docs/CONFIG.md). Database access
path, RMI→stored-procedure map and schema: [`docs/DATABASE.md`](docs/DATABASE.md)
(catalog dump in `decomp/schema/`, regenerate with `decomp/scripts/dump_schema.sh`).
## Target runtime environment
The analyzed binaries are expected to run in the following environment. Use
this when interpreting imports, API usage, and database access in decompiled
code.
- **OS**: Windows Server — exact version unknown; assume **2008 or 2012**.
- **Runtime dependencies** (winetricks-style identifiers):
- `dotnet7` — .NET 7 runtime
- `dotnetdesktop7` — .NET 7 Desktop runtime
- `vcrun2010` — Visual C++ 2010 redistributable
- `d3dx9` — DirectX 9 D3DX libraries
- `d3dx10` — DirectX 10 D3DX libraries
- **Database**: Microsoft SQL Server, supported up to **SQL Server 2019**.
Schema files for the backing databases are in `schema/`. Note: the shipped
`.mdf` files are in SQL Server 2022 format (db version 957) and only attach
to 2022+.
## Directory layout
| Path | Contents | Mutability |
|------|----------|------------|
| `binaries/` | Original shipped binaries: server EXEs (`GameServer_Release_USA_x64.exe`, `DungeonServer_...`, etc.), DLLs, and game data (maps, Lua scripts, tables, item/character assets) | **Read-only.** Never modify, move, or delete. Gitignored. |
| `schema/` | SQL Server database schema/log files (`.mdf` / `.ldf`) for `RustyHearts`, `RustyHearts_Account`, `RustyHearts_Auth`, `RustyHearts_Log`, `GMRustyHearts` | **Read-only.** Never modify. Gitignored. |
| `decomp/` | Raw decompilation objects exported from Ghidra/REA (pseudocode, listings, function metadata) | Derived output. Regenerable; created on demand. |
| `.agents/skills/` | Installed agent skills, notably `reverse-engineer-anything` (REA) | Agent configuration. |
| `docs/` | Project documentation, e.g. `ARCHITECTURE.md` (language/toolchain, libraries, code conventions) | Hand-maintained; update as findings are confirmed. |
| `third-party/` | Upstream sources/headers matched to the shipped support DLLs (OpenSSL 1.0.0d, curl 7.21.4, BugTrap ~1.3, mingw-w64 `dbghelp.h`, TinyXML 2.5.x) | Reference only, not build inputs. Do not edit upstream files; record provenance changes in the doc below. |
**Third-party libraries:** see [`third-party/README.md`](third-party/README.md)
for each support DLL's observed version, matched source and checksums, match
quality (exact vs. closest), libraries with no public source, and acquisition
routes. Consult it before decompiling any support DLL, and use the matched
headers for symbol/struct recovery instead of re-deriving known APIs.
The servers also statically link **ProudNet** (Nettention, proprietary). Its
headers live only in gitignored `third-party/_local/`; never commit them or any
other licence-restricted vendor files.
## Tooling
- **Ghidra**: installed at `/opt/ghidra`; headless entrypoint
`/opt/ghidra/support/analyzeHeadless`. `GHIDRA_INSTALL_DIR=/opt/ghidra`.
- **REA MCP**: registered in `opencode.json` via `npx -y rea-agents@6.5.0 mcp`
with `GHIDRA_INSTALL_DIR` and `JAVA_HOME` set in its environment.
- **Runtime versions**: managed by `mise.toml` — Java 21, Node 26.
- **REA skill**: `.agents/skills/reverse-engineer-anything/SKILL.md`. Read the
relevant reference under `.agents/skills/reverse-engineer-anything/references/`
before non-trivial workflows (native binaries → `native-and-artifacts.md`).
## Analysis workflow
The full reproducible procedure, with commands, is in
[`docs/WORKFLOW.md`](docs/WORKFLOW.md). Follow it for every binary. In summary:
1. Route the target first: native executables/libraries go through REA
`open_binary` (never pass a Ghidra project file as the target — pass the
original binary path under `binaries/`).
2. Work summary-first: `binary_overview` / summary detail before drilling into
`analyze_function` or pseudocode. Reuse retained Evidence IDs instead of
re-running identical analysis.
3. **Third-party libraries: every time one is discovered** (an imported DLL, a
version string, RTTI class prefix, library error strings, or a PDB path),
do the following before continuing analysis:
- pin its version;
- **search online for its source or headers** (official releases, git tags,
vendor repos, clean-room equivalents);
- download it into `third-party/`, or into the gitignored
`third-party/_local/` if its licence forbids redistribution;
- record it in `third-party/README.md`.
If no source exists, record that and the acquisition routes. See
`docs/WORKFLOW.md` §3.
4. Export raw decompilation artifacts (pseudocode, listings) into `decomp/`
using per-binary subdirectories, e.g. `decomp/GameServer_Release_USA_x64/`.
Keep filenames stable and function-address-based so results are reproducible.
For full coverage, use the headless scripts in `decomp/scripts/`.
5. Track targets, artifact SHA-256 identities, and per-binary status in
`decomp/INVENTORY.md`; keep a per-binary finding ledger in
`decomp/<name>/evidence.md`.
6. Close the REA session (`close_binary`) when the investigation is complete.
## Evidence and claims
- Every conclusion must distinguish **observation** (from evidence),
**inference**, and **unknown**. Cite Evidence IDs or `file:line`-style
references to decomp output.
- Static analysis never establishes runtime behavior — say so explicitly.
- Do not infer behavior from filenames, strings, or binary layout alone;
corroborate with decompilation or data from `schema/`.
- Keep a finding ledger for multi-step investigations (conclusion → evidence →
remaining gaps).
## Ground rules
- Treat `binaries/` and `schema/` as immutable inputs; all outputs go to
`decomp/` or a new file, never beside the originals.
- Do not install Ghidra, Java, Node, or REA prerequisites ad hoc — they are
provisioned via `mise.toml` and `/opt/ghidra`; repair configuration instead.
- Version-pin REA at `rea-agents@6.5.0` as declared in `opencode.json`.
- Do not add npm `devEngines`/`packageManager` constraints to `package.json` —
they make `npx` exit `EBADDEVENGINES` in this directory and break the REA MCP
launch (this happened once; `devEngines` was removed).
- Keep the REA registration **project-local**: `opencode.json` in this repo is
the source of truth. Do not write global client config
(`~/.config/opencode/…`) or run `rea setup` against global paths —
`rea doctor` may report global registration drift; that is accepted here.
- When tooling is missing or an MCP call is blocked, diagnose the specific
blocker (registration vs. restart vs. provider) rather than re-running setup
wholesale — see the REA skill's connection-and-recovery reference.