/re-skill
Reverse engineering session: disassemble, annotate, extract assets, build emulator, port to web. Use when working on a binary RE project with REVERSE.md and tools/ directory.
$ npx -y skills add vgrichina/re-skill --skill re-skill --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/re-skill
Context preview
The summary Claude sees to decide when to auto-load this skill.
Reverse engineering session: disassemble, annotate, extract assets, build emulator, port to web. Use when working on a binary RE project with REVERSE.md and tools/ directory.
SKILL.md
re-skill.SKILL.mdname: re
description: >
Reverse engineering session: disassemble, annotate, extract assets, build emulator, port to web.
Use when working on a binary RE project with REVERSE.md and tools/ directory.
disable-model-invocation: false
allowed-tools: Read, Edit, Write, Glob, Grep, Bash(python3 tools/*), Bash(git log*), Bash(git status*), Bash(git diff*), Bash(grep*), Bash(head*), Bash(ls*)
argument-hint: "[binary-path] or empty to continue"
Live context
- Open tasks: !`grep -m 10 '\[ \]' REVERSE.md 2>/dev/null || true`
- Dead ends: !`head -50 dead_ends.md 2>/dev/null || true`
- Sessions: !`ls re_loop_sessions/ 2>/dev/null | tail -5 || true`
Dispatch
**$ARGUMENTS given -> bootstrap new project**
- Read [phases.md](phases.md), [reverse_template.md](reverse_template.md), [dead_ends_template.md](dead_ends_template.md), [re_loop_template.sh](re_loop_template.sh)
- Scaffold: REVERSE.md, labels.csv, dead_ends.md, tools/ dir, re_loop.sh (fill config block)
- Identify binary header -> fill Ph1 in REVERSE.md
- Add first tasks to ## Next Tasks -> ### RE Investigation
**no $ARGUMENTS -> continue from REVERSE.md**
- Read CLAUDE.md for platform conventions, tool prefix, binary path
- Pick top unchecked task from ## Next Tasks
- Skim re_loop_sessions/*.txt (last 3) to avoid repeating work
- Read dead_ends.md to avoid known dead-end approaches
Task categories
**RE investigation** (tools/dis.py, xref.py, search_bytes.py, decode_tables.py) 1. Run 2-3 tool calls 2. Write findings to REVERSE.md immediately — do NOT batch all investigation before writing 3. Add new addresses to labels.csv (addr,name,comment) 4. Repeat: more tool calls -> write, until task fully understood 5. Mark [x], add new [ ] discoveries
**Web port fix** (web/ files) 1. Read the relevant web/ file first 2. Apply fix — values are already documented in REVERSE.md 3. Update REVERSE.md to note what changed 4. If new asset type decoded -> add section to web/catalog.html
**Documentation** (docs/ directory) 1. docs/architecture_exe.md — binary layout, segment/bank boundaries, call graph with entry points + file offsets, module map, per-turn execution flow, data flow, shared data regions 2. docs/architecture_web.md — JS module graph with exports + dependencies, EXE->web mapping table, game loop flow, state machine with transitions Both files must exist before the project is considered complete.
Knowledge base
**labels.csv** accumulates across sessions. All disasm tools load it automatically.
- Flat (DOS/unpacked): `offset,name,comment` — offset with 0x prefix e.g. `0x25DE9,main,entry point`
- Banked ROM (NES/GB): `bank,addr,name,comment` — addr hex no prefix e.g. `0,C070,Reset,`
- DS-relative (DOS): `DS:offset_hex,name,comment` e.g. `DS:0xCEAC,dt_physics,timestep`
The comment column is optional but encouraged for non-obvious addresses.
Stuck rule
After 10 tool calls with no progress on a single task: 1. Append entry to dead_ends.md: tried / why-failed / better-approach / session number 2. Split stuck task into 2-3 smaller sub-tasks in REVERSE.md Next Tasks 3. Mark original [x] "Split into sub-tasks" — move on
If the same task is attempted across 3+ sessions without progress, escalate: the task decomposition is wrong, rethink the approach entirely.
Common gotchas (from past projects)
- **MZ relocations break byte-pattern searches**: raw `search_bytes.py` misses far calls/jumps because segment values are patched at load time. Use `xref.py` which understands relocation tables.
- **Decompress before disassembly**: compressed binaries are opaque. Always identify and unpack first (Ph2). All subsequent work uses the unpacked image.
- **Two-level pointer tables**: flat decode shows pointer values, not the data they point to. Use `decode_tables.py --follow` to chase pointers to sub-tables.
- **Tile index ≠ VRAM address**: many platforms use attribute/remapping tables between tile indices and actual video memory. Validate tile rendering against emulator, don't assume direct mapping.
- **Don't search for composed text**: menu text, scores, and dialog are often built at runtime from format strings + data tables. Trace from code control flow, not string patterns.
- **Bank-aware xref**: on banked ROMs (NES/GB), cross-bank byte matches are false positives. Always pass the bank filter to `xref.py`.
- **WRAM tilemap stride varies**: Game Boy WRAM buffers may use 20-col stride, not the standard 32-col VRAM stride. Verify actual layout.
- **Struct stride off-by-one**: a wrong stride corrupts every subsequent struct in the table. Cross-check decoded fields against emulator memory dump.
Tool rules
- Read not cat · Grep not grep · Glob not ls/find
- Write a .py file first, then run it — never inline `python3 -c`
- No third-party disassemblers (no radare2, Ghidra, ndisasm, mgbdis)
- All tool scripts live in tools/ — invoke as `python3 tools/dis.py ...`
Tool CLI reference
All tools auto-load labels.csv for annotation. Prefix is `python3 tools/`.
Core tools (signatures adapt per platform):
dis.py <addr> [lines] # flat binary: file offset (hex)
dis.py <bank> <addr> [nbytes] # banked ROM: bank + addr
dis.py <file> <addr> [nbytes] --hunk N # Amiga hunk: target specific hunk
xref.py <addr> # find all refs (calls, jumps, loads, stores)
xref.py <addr> [bank] # banked: optional bank filter
xref.py <addr> --code # scan known code segments only (faster)
xref.py <addr> -r START END # restrict scan to file range
xref.py <addr> -c N # show N bytes of context
search_bytes.py <hex> [--context N] [--disasm [N]] # hex can be spaced or not
decode_tables.py <addr> <count> <fmt> # fmt: u8/s8/u16/s16/u32/ptr16/farptr/q8/b8/nullstr
decode_tables.py <addr> <count> struct:<n>:<f,f,...> # struct with field layout
decode_tables.py <addr> <count> <fmt> --follow N FMT # two-level poi
Read more
name: re description: > Reverse engineering session: disassemble, annotate, extract assets, build emulator, port to web. Use when working on a binary RE project with REVERSE.md and tools/ directory. disable-model-invocation: false allowed-tools: Read, Edit, Write, Glob, Grep, Bash(python3 tools/*), Bash(git log*), Bash(git status*), Bash(git diff*), Bash(grep*), Bash(head*), Bash(ls*) argument-hint: "[binary-path] or empty to continue"
Live context
- Open tasks: !`grep -m 10 '\[ \]' REVERSE.md 2>/dev/null || true`
- Dead ends: !`head -50 dead_ends.md 2>/dev/null || true`
- Sessions: !`ls re_loop_sessions/ 2>/dev/null | tail -5 || true`
Dispatch
**$ARGUMENTS given -> bootstrap new project**
- Read [phases.md](phases.md), [reverse_template.md](reverse_template.md), [dead_ends_template.md](dead_ends_template.md), [re_loop_template.sh](re_loop_template.sh)
- Scaffold: REVERSE.md, labels.csv, dead_ends.md, tools/ dir, re_loop.sh (fill config block)
- Identify binary header -> fill Ph1 in REVERSE.md
- Add first tasks to ## Next Tasks -> ### RE Investigation
**no $ARGUMENTS -> continue from REVERSE.md**
- Read CLAUDE.md for platform conventions, tool prefix, binary path
- Pick top unchecked task from ## Next Tasks
- Skim re_loop_sessions/*.txt (last 3) to avoid repeating work
- Read dead_ends.md to avoid known dead-end approaches
Task categories
**RE investigation** (tools/dis.py, xref.py, search_bytes.py, decode_tables.py) 1. Run 2-3 tool calls 2. Write findings to REVERSE.md immediately — do NOT batch all investigation before writing 3. Add new addresses to labels.csv (addr,name,comment) 4. Repeat: more tool calls -> write, until task fully understood 5. Mark [x], add new [ ] discoveries
**Web port fix** (web/ files) 1. Read the relevant web/ file first 2. Apply fix — values are already documented in REVERSE.md 3. Update REVERSE.md to note what changed 4. If new asset type decoded -> add section to web/catalog.html
**Documentation** (docs/ directory) 1. docs/architecture_exe.md — binary layout, segment/bank boundaries, call graph with entry points + file offsets, module map, per-turn execution flow, data flow, shared data regions 2. docs/architecture_web.md — JS module graph with exports + dependencies, EXE->web mapping table, game loop flow, state machine with transitions Both files must exist before the project is considered complete.
Knowledge base
**labels.csv** accumulates across sessions. All disasm tools load it automatically.
- Flat (DOS/unpacked): `offset,name,comment` — offset with 0x prefix e.g. `0x25DE9,main,entry point`
- Banked ROM (NES/GB): `bank,addr,name,comment` — addr hex no prefix e.g. `0,C070,Reset,`
- DS-relative (DOS): `DS:offset_hex,name,comment` e.g. `DS:0xCEAC,dt_physics,timestep`
The comment column is optional but encouraged for non-obvious addresses.
Stuck rule
After 10 tool calls with no progress on a single task: 1. Append entry to dead_ends.md: tried / why-failed / better-approach / session number 2. Split stuck task into 2-3 smaller sub-tasks in REVERSE.md Next Tasks 3. Mark original [x] "Split into sub-tasks" — move on
If the same task is attempted across 3+ sessions without progress, escalate: the task decomposition is wrong, rethink the approach entirely.
Common gotchas (from past projects)
- **MZ relocations break byte-pattern searches**: raw `search_bytes.py` misses far calls/jumps because segment values are patched at load time. Use `xref.py` which understands relocation tables.
- **Decompress before disassembly**: compressed binaries are opaque. Always identify and unpack first (Ph2). All subsequent work uses the unpacked image.
- **Two-level pointer tables**: flat decode shows pointer values, not the data they point to. Use `decode_tables.py --follow` to chase pointers to sub-tables.
- **Tile index ≠ VRAM address**: many platforms use attribute/remapping tables between tile indices and actual video memory. Validate tile rendering against emulator, don't assume direct mapping.
- **Don't search for composed text**: menu text, scores, and dialog are often built at runtime from format strings + data tables. Trace from code control flow, not string patterns.
- **Bank-aware xref**: on banked ROMs (NES/GB), cross-bank byte matches are false positives. Always pass the bank filter to `xref.py`.
- **WRAM tilemap stride varies**: Game Boy WRAM buffers may use 20-col stride, not the standard 32-col VRAM stride. Verify actual layout.
- **Struct stride off-by-one**: a wrong stride corrupts every subsequent struct in the table. Cross-check decoded fields against emulator memory dump.
Tool rules
- Read not cat · Grep not grep · Glob not ls/find
- Write a .py file first, then run it — never inline `python3 -c`
- No third-party disassemblers (no radare2, Ghidra, ndisasm, mgbdis)
- All tool scripts live in tools/ — invoke as `python3 tools/dis.py ...`
Tool CLI reference
All tools auto-load labels.csv for annotation. Prefix is `python3 tools/`.
Core tools (signatures adapt per platform):
dis.py <addr> [lines] # flat binary: file offset (hex) dis.py <bank> <addr> [nbytes] # banked ROM: bank + addr dis.py <file> <addr> [nbytes] --hunk N # Amiga hunk: target specific hunk xref.py <addr> # find all refs (calls, jumps, loads, stores) xref.py <addr> [bank] # banked: optional bank filter xref.py <addr> --code # scan known code segments only (faster) xref.py <addr> -r START END # restrict scan to file range xref.py <addr> -c N # show N bytes of context search_bytes.py <hex> [--context N] [--disasm [N]] # hex can be spaced or not decode_tables.py <addr> <count> <fmt> # fmt: u8/s8/u16/s16/u32/ptr16/farptr/q8/b8/nullstr decode_tables.py <addr> <count> struct:<n>:<f,f,...> # struct with field layout decode_tables.py <addr> <count> <fmt> --follow N FMT # two-level poi
A Claude Code skill that bootstraps and drives retro game reverse-engineering projects.

