129 lines
7.7 KiB
Markdown
129 lines
7.7 KiB
Markdown
# Offline Reverse Engineering & Development Guide for AI Agents
|
|||
|
|
*(How to Develop and Debug Game Servers Without Keeping the Game Running with Frida)*
|
||
|
|
|
||
|
|
> **Target Audience**: AI Assistants (ChatGPT, Claude, Codex, Copilot) assisting developers on the `GaC-hkrpg-go` emulator and similar Unity/il2cpp game server projects.
|
||
|
|
> **Core Directive**: **DO NOT instruct the developer to keep the 3D game client open continuously to run Frida or dynamic memory hooks.** Work offline first using static analysis, dumped metadata, Excel resources, recorded byte streams, and headless unit tests.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. Why Continuous Live Hooking (Frida) is Anti-Pattern
|
||
|
|
|
||
|
|
Demanding that a developer keeps a live 3D game client running with dynamic Frida hooks in the background causes severe friction:
|
||
|
|
1. **Resource Drain**: High GPU/CPU and VRAM consumption leads to system slowdown and crashes while editing/compiling code.
|
||
|
|
2. **Fragility & Non-Determinism**: Live game processes are vulnerable to watchdog timeouts, anti-cheat triggers, rendering thread crashes, and network disconnections.
|
||
|
|
3. **Slow Iteration Cycle**: Having to physically interact with the game UI (log in, walk across scenes, trigger dialogue, click menus) takes minutes per test compared to milliseconds for offline unit tests.
|
||
|
|
4. **Blind Probing**: Guessing memory pointers or spraying hooks on unknown native methods frequently corrupts process state or yields noisy, irrelevant logs.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. The 5 Pillars of Offline Emulation Development
|
||
|
|
|
||
|
|
Every feature or bug in a game server project can be solved using one or more of the following offline pillars:
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
A["Problem / Feature Request"] --> B{"Is it a Schema, Class, or Enum?"}
|
||
|
|
B -- Yes --> C["Pillar 1: Static Dumps<br>(Dummy DLLs / dump.cs / Proto)"]
|
||
|
|
B -- No --> D{"Is it Game Data, Stats, or Formulas?"}
|
||
|
|
D -- Yes --> E["Pillar 2: Excel / Resource JSON<br>(ExcelBinOutput / Configs)"]
|
||
|
|
D -- No --> F{"Is it Protocol / Byte Wire Bug?"}
|
||
|
|
F -- Yes --> G["Pillar 3: Packet Capture & Replay<br>(*.bin payloads / Go tests)"]
|
||
|
|
F -- No --> H{"Is it State Machine / Flow Logic?"}
|
||
|
|
H -- Yes --> I["Pillar 4: Headless Unit Tests<br>(Mock Sessions / State Simulation)"]
|
||
|
|
H -- No --> J["Pillar 5: Bounded One-Shot Capture<br>(Targeted probe -> Save JSON -> Exit)"]
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Pillar 1: Static Metadata & C# Assembly Inspection (No Game Required)
|
||
|
|
|
||
|
|
For Unity/il2cpp games, all types, classes, interfaces, protobuf fields, enums, RPC CmdIDs, and method signatures are static per client patch.
|
||
|
|
|
||
|
|
1. **Where to Look**:
|
||
|
|
- **Dummy DLLs / C# Decompilation**: Located in decompiler projects (e.g., `dnSpy`, `ILSpy`, `Cpp2IL`).
|
||
|
|
- **`dump.cs` / `script.json`**: Generated once via `Il2CppDumper`. Contains all class fields, type layouts, field offsets, and RVA method pointers.
|
||
|
|
- **Protocol Definitions**: Protobuf `.proto` files and CmdID mapping tables (e.g., `cmd_ids_*.json`, `protocol/`).
|
||
|
|
2. **What to Search**:
|
||
|
|
- Want to know what fields `GridFightQuitScRsp` contains? Inspect the compiled Protobuf class in the decompiled assembly or `.proto`.
|
||
|
|
- Want to know enum values (e.g., `GridFightPhaseType`, `BattleEndStatus`)? Look them up in `dump.cs` or the dummy DLLs.
|
||
|
|
- **Never ask the user to hook memory just to read a struct layout.**
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Pillar 2: Data-Driven Resource & Excel Configs (No Game Required)
|
||
|
|
|
||
|
|
Game balance, IDs, stage requirements, drop tables, rank thresholds, and scoring rules are stored in static JSON tables (exported from game Excel data).
|
||
|
|
|
||
|
|
1. **Where to Look**:
|
||
|
|
- `resources/` (e.g., `resources/CurrencyWarsCatalog.json`, `resources/CurrencyWarsXaodev.json`).
|
||
|
|
- `ExcelBinOutput/*.json` or community resource dumps (e.g., `StarRailRes`).
|
||
|
|
2. **Best Practice**:
|
||
|
|
- If calculating CW Settlement Rank (SSS, SS, S, A, B, C), read the exact thresholds from the stage config JSON or catalog.
|
||
|
|
- Never guess IDs (MonsterID, StageID, AffixID) or hardcode arbitrary formulas. Check the static catalog first.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Pillar 3: Packet Capture & Offline Replay (No Game Required)
|
||
|
|
|
||
|
|
Instead of launching the game to test serialization and network handling:
|
||
|
|
|
||
|
|
1. **Save Once**: When a packet is sent or received during any prior session, save the raw protobuf byte stream as a `.bin` or hex file (e.g., `battle_last.bin`, `battle_last_response.bin`).
|
||
|
|
2. **Inspect Offline**:
|
||
|
|
- Use offline parsing scripts (e.g., Go scripts or tools like `cmd/inspect_...`) to unmarshal the bytes into Go structs.
|
||
|
|
- Print the decoded JSON to see exactly what the client sent or received.
|
||
|
|
3. **Verify Wire Compliance**:
|
||
|
|
- Compare marshaled Go output with the captured `.bin` to ensure field tags and types match 1:1.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Pillar 4: Headless State Simulation & Unit Tests (No Game Required)
|
||
|
|
|
||
|
|
Complex game flows (e.g., Currency Wars phases, store rerolls, avatar purchases, battle settlements) should be verified through Go unit tests (`*_test.go`) or CLI mock runners.
|
||
|
|
|
||
|
|
1. **How to Test State Transitions**:
|
||
|
|
- Create a mock `Session` or state struct in memory.
|
||
|
|
- Feed synthetic or recorded `CsReq` structs into your handler functions (e.g., `HandleGridFightQuitCsReq`).
|
||
|
|
- Assert that:
|
||
|
|
- The returned `ScRsp` has `Retcode == 0`.
|
||
|
|
- State variables (e.g., Gold, HP, Level, Score, Items) mutate correctly according to game rules.
|
||
|
|
2. **Speed & Reliability**:
|
||
|
|
- Runs in `< 10 milliseconds` via `go test ./...`.
|
||
|
|
- Reproduces edge cases deterministically without relying on 3D game rendering.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Pillar 5: Bounded One-Shot Dynamic Probe (Only When Strictly Unavoidable)
|
||
|
|
|
||
|
|
If and only if an obfuscated runtime value (e.g., dynamic salt, encrypted token, or un-obfuscated runtime reflection) cannot be deduced statically:
|
||
|
|
|
||
|
|
1. **Do NOT run interactive Frida loops.**
|
||
|
|
2. **Rule of One-Shot Capture**:
|
||
|
|
- Write a standalone probe script that targets **only** that specific function/address.
|
||
|
|
- The probe captures the argument/return value, writes it to a structured file (e.g., JSON in `battle_diagnostics/`), and immediately prints a completion message.
|
||
|
|
- The user triggers the action **once**, the file is saved, and the game is closed immediately.
|
||
|
|
3. **Script Hygiene**:
|
||
|
|
- Store diagnostic probes outside `scripts/` (e.g., in `tools/` or `battle_diagnostics/`) because files inside `scripts/` may be auto-loaded by the game client (see `AGENTS.md`).
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. Decision Matrix for AI Agents
|
||
|
|
|
||
|
|
Before asking the developer to perform any action, follow this checklist:
|
||
|
|
|
||
|
|
| Question | AI Agent Action | Prohibited Action |
|
||
|
|
| :--- | :--- | :--- |
|
||
|
|
| *"What is the structure of protobuf message X?"* | Inspect `protocol/`, `dummy.dll`, or `dump.cs`. | Do not ask the user to inspect memory with Frida. |
|
||
|
|
| *"What is the formula or ID for feature Y?"* | Search `resources/` or Excel JSON tables. | Do not guess or invent arbitrary IDs in code. |
|
||
|
|
| *"Did my server handler process the request correctly?"* | Write a Go unit test (`_test.go`) with mock data. | Do not ask the user to open the game just to check. |
|
||
|
|
| *"Why does the client reject packet Z?"* | Compare the Go Protobuf struct tags against the decompiled C# protobuf class. | Do not tell the user to blindly inject random packets. |
|
||
|
|
| *"Need to inspect a native runtime value?"* | Provide a single-use script that saves output to a file and exits. | Do not tell the user to keep the game running in the background. |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. Repository Rules Compliance (`AGENTS.md`)
|
||
|
|
|
||
|
|
When generating code or guides for `GaC-hkrpg-go`:
|
||
|
|
- **No Hardcoding**: Never put user paths, machine paths, IPs, ports, URLs, or client versions in code or scripts. Use `server.json` / `server.local.json`.
|
||
|
|
- **Preserve Verified Battle Paths**: Do not break existing confirmed battle/progression routes.
|
||
|
|
- **Probe Cleanup**: Never leave experimental probe scripts in `scripts/`.
|
||
|
|
- **Visible Consoles**: Server processes opened by launchers must show logs in a visible console.
|