AtariHackerMCP

Herramientas que uno podría necesitar para hackear código Atari de 8 bits (archivos .atr), incluyendo volcado hexadecimal, desensamblador, tablas de símbolos, etc.

Documentación

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 session
  • rom_info — Display structural info about the loaded binary
  • atr_info — Display structural info about an ATR disk image
  • atr_header — Display the ATR header fields for a disk image
  • load_atr_file — Extract a file from an ATR and load it into the session
  • load_atr_boot — Extract boot sectors from an ATR and load them at $0700
  • list_atr_directory — List the DOS directory of an ATR disk image
  • analyze_boot_sector — Decode the boot sector header from an ATR
  • sector_dump — Hex dump sectors from an ATR by logical sector number
  • search_boot_sector — Scan boot sectors across multiple ATRs for patterns/differences
  • extract_atr_file — Extract a file from an ATR and save it to disk
  • inject_atr_file — Inject a file into an ATR (copy-on-write)
  • create_atr — Create a new ATR disk image from scratch
  • write_atr_sector — Write raw data to a specific sector of an ATR
  • write_atr_file — Write a file to an ATR with directory entry creation
  • define_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 ASCII
  • disassemble — 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/.endproc output, ATASCII string formatting, procedure header comments
  • analyze_disassembly — Multi-pass analysis building a reference graph and identifying code/data regions
    • Formats: summary, graph, labels, full
  • define_segment — Define a memory segment by type (code, data, graphics, text, zero_page)
  • remove_segment — Remove a defined segment by name
  • list_segments — List all defined memory segments (shows gaps)
  • clear_segments — Clear all defined segments
  • generate_linker_config — Generate a cc65 linker configuration from current segments

Analysis tools

  • x_ref — Find cross-references to an address in the ROM
  • find_pattern — Search for a byte pattern with wildcards
  • find_strings — Search for runs of printable ASCII or ATASCII characters
  • trace_control_flow — Statically trace execution from a starting address
  • probe_data — Analyze a memory range to identify data type (text, graphics, table, charset, display list, sprite data, map data) with confidence scoring
  • generate_callgraph — Generate a call graph showing subroutine relationships (Mermaid or text format)
  • analyze_coverage — Analyze code coverage: which bytes are executed vs. data
  • diff_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 address
  • remove_symbol — Remove a user-defined symbol
  • lookup_symbol — Look up the symbol entry for an address
  • list_symbols — List symbols in the symbol table
  • set_symbols — Enable/disable symbol groups (hardware, OS variables, OS ROM, user labels) to control which names appear in disassembly
  • load_labels — Load labels and segments from a sidecar file
  • save_labels — Save current labels and segments to a sidecar file
  • annotate_zero_page — Add or update a zero-page annotation
  • show_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 decimal
  • decimal_to_hex — Convert decimal to hex

Multi-Pass Disassembly

When analyze=true is passed to disassemble, the engine performs three passes:

  1. 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.
  2. 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.
  3. 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:

GroupRangeEntries
GTIA$D000–$D01F22 registers (player/missile graphics, color, control)
POKEY$D200–$D21F32 registers (sound, I/O, reserved, read/write aliasing)
PIA$D300–$D3034 registers (parallel I/O)
ANTIC$D400–$D41F20 registers (DMA, display list, NMI, reserved)
OS ROM$C000–$FFFF13 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:

OperationDescription
extract_atr_fileExtract a DOS file from an ATR to the host filesystem
inject_atr_fileReplace a file entry's data in an ATR (creates .modified copy)
create_atrCreate a blank ATR with specified sector count and density
write_atr_sectorWrite raw binary data to a specific sector
write_atr_fileCreate a new DOS file entry with sector allocation
define_filesystemDescribe 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

  1. Load a file with load_rom, load_atr_file, or load_atr_boot.
  2. Inspect structure with rom_info or atr_info.
  3. Use hex_dump to examine raw bytes, find_strings to locate text.
  4. Disassemble with disassemble (basic mode).

Analysis-driven disassembly

  1. load_rom → Load the binary.
  2. analyze_disassembly format=summary → Get code/data overview.
  3. analyze_disassembly format=labels → View all auto-generated labels.
  4. probe_data start=$1712 end=$1AD4 → Identify data regions.
  5. define_segment name=main_code start=$0C00 end=$1CFF type=code
  6. define_segment name=game_data start=$1D00 end=$BBA4 type=data
  7. disassemble offset=$0C00 numBytes=5376 format=ca65 analyze=true → Segment-aware output.
  8. generate_callgraph start=$1540 depth=5 format=mermaid → Visualize structure.
  9. Iterate: define_symboldisassemble analyze=true → review.

Iterative refinement workflow

  1. load_rom → initial disassembly with auto-labels.
  2. analyze_disassembly → identify code/data regions.
  3. define_symbol → annotate key addresses.
  4. define_segment → mark code/data regions.
  5. save_labels → persist annotations.
  6. disassemble analyze=true → re-disassemble with annotations.
  7. Review, repeat steps 3-6 as needed.

ATR modification workflow

  1. create_atr output=build/disk.atr sectors=720 density=sd → blank disk.
  2. write_atr_sector filePath=build/disk.atr sector=1 input=boot.bin → write boot sector.
  3. write_atr_file filePath=build/disk.atr name=AGENT.OBJ input=build/AGENT.OBJ → add file.
  4. extract_atr_file filePath=game.atr name=AGENT.OBJ output=extracted/AGENT.OBJ → extract file.
  5. 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 disassemble tool with analyze=false (default) behaves exactly as in v3 — full backward compatibility.
  • Self-modifying code and jump table dispatch (JMP (table,X)) cannot be resolved statically; use define_segment to mark those regions manually.
  • For full design details, see docs/version4-design.md and the v4 specification.

License

This project is licensed under the MIT License. See the LICENSE file for details.