Files
pokemon_pinball_wiki/next-analysis-targets.md
2026-07-07 00:25:38 -05:00

12 KiB

Next Analysis Targets

Priority 1: Main Game Binary

Status: first-pass static strings, dependency review, targeted Ghidra decompilation, topper serial-key recovery, a MicroPython emulator artifact, and a Docker/QEMU emulation scaffold are complete; see main-game-behavior.md, topper-serial-key-emulator.md, and docker-qemu-emulation.md.

Target:

  • /games/pokemon_pro/game

Why:

  • It is the real machine application started by game_monitor.
  • It interprets hardware state, controls gameplay, and likely talks to SPIKE node hardware.
  • Exit codes are meaningful and documented in game_monitor.

Suggested first passes:

  • Extract strings with offsets. Done: analysis/static-triage/game.strings.
  • Identify linked libraries with an AArch64-aware ELF parser. Done with objdump -p; see analysis/static-triage/game.objdump-p.txt.
  • Load into Ghidra/IDA/rizin as AArch64 PIE. Done for targeted paths.
  • Search for paths from the init scripts: /connectivity, /data, /games, /dev, UPDATE_REQUESTED, UPDATE_COMPLETED, and node firmware filenames.
  • Search for exit-code constants matching the monitor script: 0 through 6, plus signal paths.

Follow-up passes:

  • Continue from emulation/: QEMU now boots the generated rootfs, exposes noVNC/dashboard, loads virtio_gpu, creates /dev/dri/card0, and reaches /games/spike3/bin/boot_display. The current blocker is boot_display create_window retries plus shader compile/link failures, so the next pass should focus on Mesa/GBM/EGL userspace compatibility or a targeted display interposer before moving to spike-menu and /games/game.
  • Validate analysis/topper-emulator/topper_emulator.py on live hardware or a nodebus capture.
  • Recover the exact Magikarp topper IDENTITY_BOARD_PART_ID expected by command 0xfe.
  • Confirm physical UART pins, baud, voltage level, and any netbridge timing/break behavior required for a MicroPython node.

Priority 2: image.bin / Radium Runtime Image

Status: first-pass static comparison, whole-rootfs audio search, targeted Ghidra xrefs for the sound path, main-game section 8 PCM table reversal, full main-game section 5 sound command-stream scan, generic section 5 opcode stream decode with payload-field summaries, native opcode length/handler table dumps, section 3 bitmap-record preview extraction, SPIKE menu section 8 PCM parse, SPIKE menu section 5 command-stream scan, Godot .gdc string decoding, full main-game WAV export, 54 SPIKE menu WAV exports, 25 Ghidra-confirmed native sound-name aliases, catalog-order offset candidate audit and preview page, 1,137 aligned Pokedex voice aliases, 1,705 draft ASR transcript labels, 169 low-confidence ASR review candidates, complete best-available named alias export, game-asset spoiler/unreleased-feature inventory, and wiki preview pages are complete; see package-image-firmware.md, audio-asset-search.md, radium-image-format.md, sound-export.md, sound-catalog-offset-candidates.md, sound-pokedex-voice.md, sound-spike-menu.md, sound-native-names.md, sound-native-sound-test.md, sound-asr-draft-labels.md, sound-asr-review-candidates.md, sound-best-named-export.md, asset-previews.md, radium-section3-bitmaps.md, and game-asset-spoilers-unreleased.md.

Targets:

  • /games/pokemon_pro/image.bin
  • /games/pokemon_pro/spike3/spike_menu/image.bin

Why:

  • image.bin is larger than the executable and is probably a resource pack, filesystem image, or application asset bundle used by the game.
  • The SPIKE menu explicitly copies its image.bin to tmpfs because updates may overwrite it while mmap-ed.
  • main.pck has already been extracted into workspace-local assets/; see godot-and-radium-assets.md.

Suggested first passes:

  • Run file, binwalk, entropy analysis, and magic-number scans. file, binwalk, header dump, and first strings completed.
  • Search for embedded filenames, JSON, SQLite, compression headers, and Godot pack headers. First strings show Stern EULA text; no standard archive signature found by binwalk.
  • Compare structure between game image.bin and spike-menu image.bin. First 0xb0-byte header shape and early EULA structure are similar, with different size/table values.
  • Reverse the Radium/cereal mmap image table used by /games/pokemon_pro/game strings such as Flash memory init mmap failed, /lcd/demand_loaded, and /lcd/auto_loaded.
  • Map the remaining Radium sound object IDs and section 8 chunk indices to higher-level script/gameplay names and call sites. Section 8 is decoded as headerless 16-bit PCM chunks, the parser resolves section 5 opcode 0x0b command-stream references for all chunks, and all chunks are exported as WAVs. A native Godot bridge table confirms names for 25 IDs; Ghidra xrefs to its registration helper are exhausted at those 25 direct calls. Catalog-order comparison now identifies two native anchor offsets, +69 for EOB Pokedex FX and +78 for attack-type FX, and writes 199 neighboring unpromoted candidate labels plus one sound-test-candidate disagreement to analysis/radium-image/catalog_offset_candidate_labels.tsv. Of those candidates, 196 non-conflicting rows are now used as explicitly marked catalog_offset_candidate best-name aliases for sounds that previously had only structural object references. The Pokedex voice stream now maps objects 409 through 1545 to 1,137 semantic Pokemon voice labels. The current ASR pass adds 1,705 draft content labels for bounded voice-like clips, including 220 catalog-matched SE_PK_VO_* inferred names across 90 catalog constants, plus 34 low-confidence ASR review aliases for rows that would otherwise remain structural. ASR labels and catalog-offset candidates still need native/script confirmation.
  • Maintain analysis/all-sound-best-name-manifest.tsv as the complete named-export surface. It currently has 2,545 rows: 25 confirmed native names, 1,137 Pokedex voice alignments, 220 catalog-matched ASR aliases, 583 raw ASR draft aliases after stronger-name priority, 196 explicitly marked catalog-offset candidate aliases, 34 low-confidence ASR review aliases, 1 main-image duplicate hash match inheriting a confirmed native name, 295 main structural object fallbacks, 4 SPIKE menu exact-payload matches inheriting stronger main-image names, and 50 SPIKE menu structural fallbacks. The remaining 345 structural rows are also grouped for review in sound-unresolved-review.md by bank and duration/channel bucket. Four sound-test-adjacent native label rows are retained for audit, but are not promoted as confirmed best-name labels because their numeric field conflicts with ASR/Pokedex cross-checks.
  • Continue section 3 image-record recovery. Ghidra xrefs identify section 3 as a 1,477-entry qword pointer table; the current static exporter renders 1,449 raw indexed bitmap records and leaves 28 compact payload records undecoded in analysis/radium-image/section3_bitmap_manifest.tsv. Next steps are recovering the compact subtype, confirming palette/alpha semantics, and correlating section 3 records with section 4 or runtime display callers.
  • Recover SPIKE menu object metadata and higher-level menu names in /games/pokemon_pro/spike3/spike_menu/game. The current menu export resolves all 54 section 8 PCM chunks through 300 section 5 opcode 0x0b references, but only to local object IDs.
  • Continue decoding compiled GDScript bytecode beyond string recovery if broader script call-site reconstruction is needed. Current static .gdc string decoding recovers the 760-name sound catalog and 12 direct Pokedex EOB scene references, but not a general name-to-Radium-object map.
  • Assign semantics to the non-sound section 5 opcodes now summarized in analysis/radium-image/command_opcode_payload_summary.tsv, analysis/radium-spike-menu-image/command_opcode_payload_summary.tsv, analysis/radium-image/opcode_handler_table.tsv, and analysis/radium-spike-menu-image/opcode_handler_table.tsv. The current generic decode confirms clean 0x00-terminated streams, observed opcodes, fixed payload sizes, common payload values, native handler-address table entries, and that opcode 0x0b is the sound-reference command, but most non-0x0b opcode names still need confirmation from runtime consumers.
  • Validate the unreleased/deep-feature candidates from game-asset-spoilers-unreleased.md: Team Rocket Multiball 3, Pikachu vs. Lucario / Story Wizard 2, Pikachu vs. Magikarp, Eevee Evolution Combos, and Cave/Mountain Top backgrounds. The current evidence is static strings, extracted assets, and candidate sound labels; reachability still needs code-path or runtime confirmation.

Priority 3: conagent

Status: first-pass reverse engineering complete in conagent-re.md; non-compilable C-like flow export is in conagent-pseudocode.c; host-side backend/machine emulator added under analysis/conagent-machine-emulator/ and documented in conagent-machine-emulator.md.

Target:

  • /games/pokemon_pro/conagent

Why:

  • It is separately supervised and restarted forever.
  • Name and /connectivity paths suggest Stern Insider Connected or connectivity agent behavior.

Suggested first passes:

  • Strings and URL/domain extraction.
  • Network syscall/import review.
  • Trace references to /connectivity/cache, /connectivity/files, /connectivity/update, and hostname handling.

Follow-up passes:

  • Force Ghidra function creation for the stripped text region and rerun decompilation.
  • Audit ifup/ifdown command construction and interface-name validation.
  • Audit direct Game-to-Server endpoint validation.
  • Audit file-transfer local path validation and update handoff.
  • Recover enough of the /usr/local/spike/agent.uds framed protocol to add a local game-process emulator mode.

Priority 4: Netbridge Debug Path

Status: first-pass strings and ELF program-header review complete; see package-image-firmware.md.

Targets:

  • /games/pokemon_pro/spike3/netbridge/netbridge.elf
  • /games/pokemon_pro/spike3/netbridge/spike3-swd.cfg
  • /games/pokemon_pro/spike3/netbridge/rp2040.cfg

Why:

  • netbridge.elf is not stripped and has debug info.
  • OpenOCD config maps SWD onto Raspberry Pi GPIOs 10 and 11.
  • This may be the clearest path to understanding lower-level board communication and programming/debug pathways.

Findings:

  • netbridge.elf is a 32-bit ARM static executable with code mapped at 0x10000000 and RAM at 0x20000000/0x20040000.
  • Strings include uart_node.c, NODEBUS_Poll, NODEUART_Write, UART_NodeRxIrq, and WS2812_NodeSetLED.

Priority 5: Node Firmware

Status: first-pass Intel HEX range parsing complete for top-level node firmware; see package-image-firmware.md.

Targets:

  • All *-LPC*.hex files under /games/pokemon_pro.
  • /games/pokemon_pro/spike3/powerdist/powerdist_ext.hex.

Why:

  • These likely define behavior for distributed playfield nodes: coils, LEDs, LCD, magnet sensors, HDMI, TMC drivers, power distribution.
  • Firmware names expose node families and MCU types.

Suggested first passes:

  • Parse Intel HEX metadata and address ranges. Done for 17 top-level HEX files in analysis/static-triage/node-firmware-ranges.md.
  • Group by MCU family. Initial grouping by filename identifies LPC1112, LPC1113, LPC1124, LPC1313, and LPC812 families.
  • Disassemble with the correct Cortex-M profile per chip.
  • Correlate firmware names with harnesses, playfield devices, and game binary strings.

Priority 6: Update Format

Status: first-pass .sidx strings/header review complete; see package-image-firmware.md.

Targets:

  • /games/spk/index/pokemon_pro-0_83_0.sidx
  • Any available .spk update packages outside this rootfs.

Why:

  • /etc/init.d/update and update_monitor make .spk the software update format.
  • The index file may describe package contents, hashes, versions, or install paths.

Suggested first passes:

  • Inspect .sidx with file, strings, hexdump, and structured parsers. Done with file, xxd, and strings; 686 package paths were identified.
  • Compare with any .spk available from machine update media or connectivity cache.