AtariHackerMCP
เครื่องมือที่อาจจำเป็นสำหรับการแฮ็กโค้ด Atari 8 บิต (ไฟล์ .atr) รวมถึง hex dump, ดีแอสเซมเบลอร์, ตารางสัญลักษณ์ และอื่นๆ
เอกสาร
AtariHackerMCP
A local MCP server for reverse-engineering Atari 8-bit binaries and ATR disk images. Supports multi-pass disassembly analysis, code/data separation, segment-aware output, ATR file injection, batch scripting, and a comprehensive Atari hardware symbol table.
Requirements
- .NET SDK 10.0+
- Linux, macOS, or Windows
Build
Restore packages and compile:
dotnet build
Publish a release build if needed:
dotnet publish -c Release -o publish
Run
This server uses MCP stdio transport, so it is normally launched by an MCP client rather than run interactively.
For local testing:
dotnet run --no-build
Or run the published executable:
./publish/AtariHackerMCP
MCP Client Configuration
Example stdio server entry:
{
"mcpServers": {
"atari-hacker": {
"command": "dotnet",
"args": [
"run",
"--project",
"/absolute/path/to/AtariHackerMCP/AtariHackerMCP.csproj",
"--no-build"
]
}
}
}
If you prefer using a published build:
{
"mcpServers": {
"atari-hacker": {
"command": "/absolute/path/to/AtariHackerMCP/publish/AtariHackerMCP",
"args": []
}
}
}
Available Tools
File and disk tools
load_rom— Load a ROM/XEX binary into the current sessionrom_info— Display structural info about the loaded binaryatr_info— Display structural info about an ATR disk imageatr_header— Display the ATR header fields for a disk imageload_atr_file— Extract a file from an ATR and load it into the sessionload_atr_boot— Extract boot sectors from an ATR and load them at $0700list_atr_directory— List the DOS directory of an ATR disk imageanalyze_boot_sector— Decode the boot sector header from an ATRsector_dump— Hex dump sectors from an ATR by logical sector numbersearch_boot_sector— Scan boot sectors across multiple ATRs for patterns/differencesextract_atr_file— Extract a file from an ATR and save it to diskinject_atr_file— Inject a file into an ATR (copy-on-write)create_atr— Create a new ATR disk image from scratchwrite_atr_sector— Write raw data to a specific sector of an ATRwrite_atr_file— Write a file to an ATR with directory entry creationdefine_filesystem— Define a custom filesystem layout for non-DOS ATRs
Inspection and disassembly
hex_dump— Produce a hex dump with file offsets, memory addresses, and ASCIIdisassemble— Disassemble 6502 code with optional multi-pass analysis (analyze=true)- Supports formats:
listing,ca65,atasm,mac65 - When
analyze=true: generates meaningful labels (sub_XXXX,data_XXXX,jmp_XXXX), code/data separation, segment-aware.segment/.proc/.endprocoutput, ATASCII string formatting, procedure header comments
- Supports formats:
analyze_disassembly— Multi-pass analysis building a reference graph and identifying code/data regions- Formats:
summary,graph,labels,full
- Formats:
define_segment— Define a memory segment by type (code, data, graphics, text, zero_page)remove_segment— Remove a defined segment by namelist_segments— List all defined memory segments (shows gaps)clear_segments— Clear all defined segmentsgenerate_linker_config— Generate a cc65 linker configuration from current segments
Analysis tools
x_ref— Find cross-references to an address in the ROMfind_pattern— Search for a byte pattern with wildcardsfind_strings— Search for runs of printable ASCII or ATASCII characterstrace_control_flow— Statically trace execution from a starting addressprobe_data— Analyze a memory range to identify data type (text, graphics, table, charset, display list, sprite data, map data) with confidence scoringgenerate_callgraph— Generate a call graph showing subroutine relationships (Mermaid or text format)analyze_coverage— Analyze code coverage: which bytes are executed vs. datadiff_roms— Compare two ROM or ATR files (summary, verbose, or hex diff format)
Symbol and zero-page tools
define_symbol— Add or update a named label for a memory addressremove_symbol— Remove a user-defined symbollookup_symbol— Look up the symbol entry for an addresslist_symbols— List symbols in the symbol tableset_symbols— Enable/disable symbol groups (hardware, OS variables, OS ROM, user labels) to control which names appear in disassemblyload_labels— Load labels and segments from a sidecar filesave_labels— Save current labels and segments to a sidecar fileannotate_zero_page— Add or update a zero-page annotationshow_zero_page_map— Display current zero-page annotations
Scripting tools
run_script— Execute a sequence of commands from a script file (supports 33 commands)
Utility tools
calculate— Evaluate mathematical expressions with hex literals ($prefix)hex_to_decimal— Convert hex to decimaldecimal_to_hex— Convert decimal to hex
Multi-Pass Disassembly
When analyze=true is passed to disassemble, the engine performs three passes:
- Pass 1 — Reference Collection: Scans all instruction boundaries across the ROM, recording JSR targets, JMP targets, branch targets, indirect jump targets, and absolute/indirect data references into a
ReferenceGraph. - Pass 2 — Code Region Tracing: Starting from each code entry point, traces execution flow (following JSR, JMP, branches, stopping at RTS/RTI/BRK) to mark bytes as code or data.
- Pass 3 — Label Generation: Produces meaningful labels (
sub_XXXX,jmp_XXXX,data_XXXX,L_XXXX) with proper priority ordering (user > subroutine > data > hardware > OS > branch).
Example
; --------------------------------------------------
; Generated by Atari Hacker MCP v4
; --------------------------------------------------
.segment "MAIN_CODE"
.org $0C00
; --------------------------------------------------
; Subroutine: game_init
; Calls: load_ag_obj, load_ag_dat, main_loop
; --------------------------------------------------
.proc game_init
LDA #$00
STA $D400 ; DMACTL
...
.endproc
; String table at $1712
credits_text:
.byte "Scholastic", $9B ; $9B = ATASCII EOL
.byte "Wizware", $9B
.byte $00
Atari Hardware Symbol Table
The built-in symbol table covers over 200 entries across all major Atari components:
| Group | Range | Entries |
|---|---|---|
| GTIA | $D000–$D01F | 22 registers (player/missile graphics, color, control) |
| POKEY | $D200–$D21F | 32 registers (sound, I/O, reserved, read/write aliasing) |
| PIA | $D300–$D303 | 4 registers (parallel I/O) |
| ANTIC | $D400–$D41F | 20 registers (DMA, display list, NMI, reserved) |
| OS ROM | $C000–$FFFF | 13 entry points (SIO, CIO, vectors) |
| Zero page OS | $00–$FF | ~220 variables (timers, I/O control, floating point, screen, paddles, joysticks) |
Symbol groups can be toggled with set_symbols to avoid conflicts when user code overlaps OS address ranges.
ATR Write Operations
The ATR write subsystem provides copy-on-write disk image modification:
| Operation | Description |
|---|---|
extract_atr_file | Extract a DOS file from an ATR to the host filesystem |
inject_atr_file | Replace a file entry's data in an ATR (creates .modified copy) |
create_atr | Create a blank ATR with specified sector count and density |
write_atr_sector | Write raw binary data to a specific sector |
write_atr_file | Create a new DOS file entry with sector allocation |
define_filesystem | Describe a non-DOS filesystem layout for custom-format disks |
Batch Scripting
The run_script tool executes sequences of commands from text files:
# disassemble_all.txt
load_rom filePath=game.xex
define_symbol address=$1540 label=game_init
define_segment name=boot_loader start=$0700 end=$087F type=code
define_segment name=main_code start=$0C00 end=$1CFF type=code
disassemble offset=$0700 numBytes=384 format=ca65 analyze=true
generate_linker_config output=game.cfg
save_labels filePath=game.annotations.json
Data Probing
probe_data uses 7 heuristics to identify data types in memory ranges:
- String detection — ATASCII/ASCII printable runs,
$9B-terminated, null-terminated - Padding detection — Runs of
$00,$FF,$1A(ATASCII EOL) - Character set detection — 1024-byte (128×8) and 512-byte (64×8) blocks
- Table detection — 2-byte address tables, 1-byte lookup tables
- Display list detection — ANTIC display list opcodes with LMS extraction
- Sprite data detection — 8/16/32-byte aligned blocks with byte variety analysis
- Map data detection — 2D grid patterns with consistent row lengths
Each result includes a confidence level (High/Medium/Low) and supporting details.
Typical Workflow
Basic exploration
- Load a file with
load_rom,load_atr_file, orload_atr_boot. - Inspect structure with
rom_infooratr_info. - Use
hex_dumpto examine raw bytes,find_stringsto locate text. - Disassemble with
disassemble(basic mode).
Analysis-driven disassembly
load_rom→ Load the binary.analyze_disassembly format=summary→ Get code/data overview.analyze_disassembly format=labels→ View all auto-generated labels.probe_data start=$1712 end=$1AD4→ Identify data regions.define_segment name=main_code start=$0C00 end=$1CFF type=codedefine_segment name=game_data start=$1D00 end=$BBA4 type=datadisassemble offset=$0C00 numBytes=5376 format=ca65 analyze=true→ Segment-aware output.generate_callgraph start=$1540 depth=5 format=mermaid→ Visualize structure.- Iterate:
define_symbol→disassemble analyze=true→ review.
Iterative refinement workflow
load_rom→ initial disassembly with auto-labels.analyze_disassembly→ identify code/data regions.define_symbol→ annotate key addresses.define_segment→ mark code/data regions.save_labels→ persist annotations.disassemble analyze=true→ re-disassemble with annotations.- Review, repeat steps 3-6 as needed.
ATR modification workflow
create_atr output=build/disk.atr sectors=720 density=sd→ blank disk.write_atr_sector filePath=build/disk.atr sector=1 input=boot.bin→ write boot sector.write_atr_file filePath=build/disk.atr name=AGENT.OBJ input=build/AGENT.OBJ→ add file.extract_atr_file filePath=game.atr name=AGENT.OBJ output=extracted/AGENT.OBJ→ extract file.inject_atr_file filePath=game.atr name=AGENT.OBJ input=build/AGENT.OBJ→ replace file.
Persistence
User-defined symbols, zero-page annotations, and segment definitions are saved automatically to a sidecar JSON file next to the loaded target:
<rom-or-synthetic-path>.atarihacker.json
The v4 sidecar format includes:
- Version field for forward compatibility
- SHA-256 ROM hash for integrity checking
- Segments (name, type, start, end, comment)
- Custom filesystem definitions
v3 sidecar files (without version field) are read transparently and upgraded on save.
Example MCP Smoke Test
This sends initialize and tools/list directly over stdio:
(
printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test-client","version":"1.0"}}}\n'
sleep 0.2
printf '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}\n'
sleep 1
) | dotnet run --no-build
Notes
- Logs are written to stderr so stdout remains clean for MCP JSON-RPC traffic.
- The
disassembletool withanalyze=false(default) behaves exactly as in v3 — full backward compatibility. - Self-modifying code and jump table dispatch (
JMP (table,X)) cannot be resolved statically; usedefine_segmentto mark those regions manually. - For full design details, see
docs/version4-design.mdand the v4 specification.
License
This project is licensed under the MIT License. See the LICENSE file for details.