pi: generic-ize ghidra skill (drop game-specific examples)

This commit is contained in:
2026-05-04 20:30:07 -04:00
parent feae0f8002
commit 05b2741ec0

View File

@@ -152,7 +152,8 @@ in
# OMP discovers servers from this file at startup. The ghidra entry below # OMP discovers servers from this file at startup. The ghidra entry below
# spawns pyghidra-mcp on stdio when the agent invokes any of its tools. # spawns pyghidra-mcp on stdio when the agent invokes any of its tools.
".omp/agent/mcp.json".text = builtins.toJSON { ".omp/agent/mcp.json".text = builtins.toJSON {
"$schema" = "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/config/mcp-schema.json"; "$schema" =
"https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/config/mcp-schema.json";
mcpServers = { mcpServers = {
ghidra = { ghidra = {
command = lib.getExe pyghidra-mcp; command = lib.getExe pyghidra-mcp;
@@ -297,57 +298,55 @@ in
A headless MCP server is configured at `mcpServers.ghidra` in A headless MCP server is configured at `mcpServers.ghidra` in
`~/.omp/agent/mcp.json` and binds Ghidra's analysis engine to MCP tools `~/.omp/agent/mcp.json` and binds Ghidra's analysis engine to MCP tools
you can call directly. The Ghidra install lives at you can call directly. The Ghidra install lives at
`${pkgs.ghidra}/lib/ghidra`; pyghidra-mcp picks it up via the `''${pkgs.ghidra}/lib/ghidra`; pyghidra-mcp picks it up via the
GHIDRA_INSTALL_DIR env var that's wired into the binary's wrapper. GHIDRA_INSTALL_DIR env var that's wired into the binary's wrapper.
## When to use this ## When to use this
- Static analysis of any compiled binary you have on disk (or extract - Static analysis of any compiled binary you have on disk.
from a game install, container image, firmware dump, etc.). - Finding the decision logic behind an observed runtime behavior, when
- Finding the decision logic behind a runtime behavior. E.g. where in the source isn't available.
F1 23's executable the adaptive-trigger code lives and what params - Extracting embedded tables/constants from `.rdata`/`.data` sections.
it passes. - Discovering which APIs (libc, OS, vendor SDKs) a binary imports and
- Extracting embedded tuning tables from `.rdata`/`.data` sections. where it calls them.
- Discovering which Sony / Steam / Windows HID APIs a game calls. - Recovering structures, function signatures, and type information
from a stripped binary.
## Workflow ## Workflow
The first invocation imports a binary into a fresh Ghidra project and The first invocation imports a binary into a fresh Ghidra project and
runs auto-analysis (10-90 minutes depending on size). Subsequent calls runs auto-analysis (10-90 minutes depending on size). Subsequent calls
are fast. hit the cached project and are fast.
Typical exploration sequence for a stripped C++ game binary: Typical exploration sequence for a stripped binary:
1. `list_strings(filter="DualSense")` (or other relevant substring) to 1. `list_strings(filter="<substring>")` to find string literals
find string literals; Codemasters/Ubisoft typically don't strip these. related to the behavior you're investigating.
2. `list_imports()` filtered for HID / Sony / Steam APIs to find the 2. `list_imports()` filtered for the API surface you care about
haptic call surface. (e.g. HID, networking, crypto) to find call sites.
3. `get_xrefs_to(<address-of-string-or-import>)` to surface call sites. 3. `get_xrefs_to(<address-of-string-or-import>)` to surface every
function that touches the symbol.
4. `decompile_function_by_address(<addr>)` to read C-pseudocode. 4. `decompile_function_by_address(<addr>)` to read C-pseudocode.
5. `set_decompiler_comment` and `rename_function` as you identify 5. `set_decompiler_comment` and `rename_function` as you identify
components, so the database remembers your findings across calls. components, so the database remembers your findings across calls.
## Loading a binary ## Loading a binary
Drop the binary somewhere readable (don't commit to git license + size) Drop the binary somewhere readable (don't commit to git size + often
and pass the absolute path to pyghidra-mcp's import tool: proprietary) and pass the absolute path to pyghidra-mcp's import tool.
Auto-analysis runs once; the project database persists in
```
/tmp/games/f1_23/F1_23_dx12.exe
/tmp/games/cyberpunk/Cyberpunk2077.exe
```
Auto-analysis runs once per binary; the project database persists in
`~/.cache/pyghidra-mcp/` so re-invocations are fast. `~/.cache/pyghidra-mcp/` so re-invocations are fast.
## What this is NOT for ## What this is NOT for
- Dynamic capture use usbmon + Wireshark for live HID traffic. - Dynamic / runtime analysis use a debugger, usbmon/strace, or a
- PS5 binaries encrypted, out of scope. protocol sniffer for that.
- Decoding live network traffic separate tooling. - Encrypted/DRM-protected binaries out of scope without the keys.
- Network-traffic decoding on the wire separate tooling.
Reverse engineering for interoperability is permitted under DMCA §1201(f) Reverse engineering for interoperability, security research, and
and analogous EU provisions. Don't share decrypted/cracked binaries. bug-fix purposes is permitted under DMCA §1201(f) and analogous EU
provisions. Don't share decrypted or cracked binaries.
''; '';
}; };