104 lines
4.4 KiB
Markdown
104 lines
4.4 KiB
Markdown
# Conagent Machine Emulator
|
|
|
|
## Summary
|
|
|
|
A host-side Python emulator was added under `analysis/conagent-machine-emulator/`.
|
|
|
|
The emulator models the backend-facing API surface that `/games/pokemon_pro/conagent` is known to call from static analysis and provides a local browser UI for changing emulated pinball-machine state. It now also includes a small "Extracted Game Calls" runner for representative network/game-session calls found in `/games/pokemon_pro/game` strings.
|
|
|
|
Generated files:
|
|
|
|
| Path | Purpose |
|
|
| --- | --- |
|
|
| `analysis/conagent-machine-emulator/emulator.py` | Dependency-free Python HTTP/HTTPS emulator with web UI. |
|
|
| `analysis/conagent-machine-emulator/config.example.json` | Example editable emulator configuration. |
|
|
| `analysis/conagent-machine-emulator/README.md` | Usage notes, curl smoke tests, and HTTPS integration notes. |
|
|
|
|
## Evidence Basis
|
|
|
|
The emulator endpoints are based on confirmed strings and reconstructed flow in `/games/pokemon_pro/conagent`, documented in [Conagent Reverse Engineering](conagent-re.md):
|
|
|
|
- `https://%s/api-token-auth/`
|
|
- `/api/v1/ping`
|
|
- `/api/v1/game/version_upgrades_available`
|
|
- `/api/v2/game/heartbeat`
|
|
- `/api/v3/game/player_auth`
|
|
- `/api/v3/game/game_register`
|
|
- `/api/v3/game/game_achievement_descriptors`
|
|
- `/api/v3/game/game_auth`
|
|
- `http://%s:8345/b8Ag3XU6TH/wibbly_wobbly_timey_wimey/`
|
|
|
|
The emulator also returns `Message-Number` and `App-Status-Code` headers because the reconstructed HTTP client reads those header fields after requests.
|
|
|
|
Additional game-call buttons are based on confirmed `/games/pokemon_pro/game` strings:
|
|
|
|
| Offset | String |
|
|
| --- | --- |
|
|
| `0x25dd5a8` | `GameSessionBegin` |
|
|
| `0x25dd5c0` | `GameSessionUpdate` |
|
|
| `0x25dd5d8` | `GameSessionEnd` |
|
|
| `0x25de8c0` | `/api/v1/game/high_score_events` |
|
|
| `0x25dea50` | `/api/v2/game/machine_audits` |
|
|
| `0x25deb88` | `/api/v1/game/game_configuration` |
|
|
| `0x25df9d8` | `/api/v2/game/player_achievements` |
|
|
| `0x25dfa20` | `/api/v2/game/player_properties` |
|
|
| `0x25e03a8` | `/api/v1/game/data_store` |
|
|
| `0x25e03f8` | `/api/v1/game/data_retrieve` |
|
|
| `0x25e0508` | `/api/v3/game/session_start` |
|
|
| `0x25e0568` | `/api/v3/game/session_end` |
|
|
| `0x25e05c8` | `/api/v3/game/session_update` |
|
|
|
|
Score/high-score UI fields are synthetic emulator state, but they are shaped around game strings such as `AD_HIGH_SCORE_1_SCORE`, `AUD_SCORE_HISTO_1`, `AUD_AVERAGE_SCORES`, `PlayerScore`, and `GameScores_Player1`.
|
|
|
|
## Confirmed Scope
|
|
|
|
The implementation is host-side support tooling only:
|
|
|
|
- It does not modify rootfs evidence files.
|
|
- It does not execute `/games/pokemon_pro/conagent` or any other target AArch64 binary.
|
|
- It emulates backend-facing HTTP behavior, browser-controlled machine state, and synthetic score/session payloads for testing call handling.
|
|
|
|
## Current Limitations
|
|
|
|
The emulator does not implement the local `/usr/local/spike/agent.uds` framed game-to-conagent protocol. That protocol remains only partially recovered from static strings, including message IDs, ACK/NACK/reset behavior, and action names.
|
|
|
|
Scores and sessions produced by this emulator are not recovered from a running game process. They are generated test data intended to exercise the extracted network calls.
|
|
|
|
Real conagent integration will likely require HTTPS for the API listener because the binary constructs most backend URLs with `https://%s/...`. The special server-time endpoint is plain HTTP on port `8345`.
|
|
|
|
## Reproducible Commands
|
|
|
|
Start the emulator:
|
|
|
|
```sh
|
|
cd /Users/jordan/Downloads/pokemon_spike3_rootfs
|
|
python3 analysis/conagent-machine-emulator/emulator.py --config analysis/conagent-machine-emulator/config.example.json
|
|
```
|
|
|
|
Smoke-test endpoints:
|
|
|
|
```sh
|
|
curl -s http://127.0.0.1:8088/api/v1/ping
|
|
curl -s -X POST http://127.0.0.1:8088/api-token-auth/ \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"username":"emu","password":"emu"}'
|
|
curl -s http://127.0.0.1:8345/b8Ag3XU6TH/wibbly_wobbly_timey_wimey/
|
|
```
|
|
|
|
Run extracted call tests:
|
|
|
|
```sh
|
|
curl -s -X POST http://127.0.0.1:8088/api/game-state/score \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"player":1,"delta":1234567}'
|
|
curl -s -X POST http://127.0.0.1:8088/api/game-calls/run \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"id":"session_start"}'
|
|
curl -s -X POST http://127.0.0.1:8088/api/game-calls/run \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"id":"session_update"}'
|
|
curl -s -X POST http://127.0.0.1:8088/api/game-calls/run \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"id":"high_score_event"}'
|
|
```
|