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
Un servidor MCP local para ingeniería inversa de binarios Atari de 8 bits e imágenes de disco ATR. Admite análisis de desensamblado de múltiples pasadas, separación de código/datos, salida consciente de segmentos, inyección de archivos ATR, scripting por lotes y una tabla de símbolos completa del hardware Atari.
Requisitos
- .NET SDK 10.0+
- Linux, macOS o Windows
Compilación
Restaurar paquetes y compilar:
dotnet build
Publicar una compilación de lanzamiento si es necesario:
dotnet publish -c Release -o publish
Ejecución
Este servidor utiliza el transporte stdio de MCP, por lo que normalmente lo lanza un cliente MCP en lugar de ejecutarse de forma interactiva.
Para pruebas locales:
dotnet run --no-build
O ejecutar el ejecutable publicado:
./publish/AtariHackerMCP
Configuración del Cliente MCP
Ejemplo de entrada de servidor stdio:
{
"mcpServers": {
"atari-hacker": {
"command": "dotnet",
"args": [
"run",
"--project",
"/absolute/path/to/AtariHackerMCP/AtariHackerMCP.csproj",
"--no-build"
]
}
}
}
Si prefieres usar una compilación publicada:
{
"mcpServers": {
"atari-hacker": {
"command": "/absolute/path/to/AtariHackerMCP/publish/AtariHackerMCP",
"args": []
}
}
}
Herramientas Disponibles
Herramientas de archivos y discos
load_rom— Cargar un binario ROM/XEX en la sesión actualrom_info— Mostrar información estructural sobre el binario cargadoatr_info— Mostrar información estructural sobre una imagen de disco ATRatr_header— Mostrar los campos de cabecera ATR de una imagen de discoload_atr_file— Extraer un archivo de un ATR y cargarlo en la sesiónload_atr_boot— Extraer sectores de arranque de un ATR y cargarlos en $0700list_atr_directory— Listar el directorio DOS de una imagen de disco ATRanalyze_boot_sector— Decodificar la cabecera del sector de arranque de un ATRsector_dump— Volcado hexadecimal de sectores de un ATR por número de sector lógicosearch_boot_sector— Escanear sectores de arranque en múltiples ATR para patrones/diferenciasextract_atr_file— Extraer un archivo de un ATR y guardarlo en discoinject_atr_file— Inyectar un archivo en un ATR (copiar al escribir)create_atr— Crear una nueva imagen de disco ATR desde cerowrite_atr_sector— Escribir datos sin procesar en un sector específico de un ATRwrite_atr_file— Escribir un archivo en un ATR con creación de entrada de directoriodefine_filesystem— Definir un diseño de sistema de archivos personalizado para ATR que no sean DOS
Inspección y desensamblado
hex_dump— Producir un volcado hexadecimal con desplazamientos de archivo, direcciones de memoria y ASCIIdisassemble— Desensamblar código 6502 con análisis opcional de múltiples pasadas (analyze=true)- Admite formatos:
listing,ca65,atasm,mac65 - Cuando
analyze=true: genera etiquetas significativas (sub_XXXX,data_XXXX,jmp_XXXX), separación de código/datos, salida.segment/.proc/.endprocconsciente de segmentos, formato de cadenas ATASCII, comentarios de cabecera de procedimiento
- Admite formatos:
analyze_disassembly— Análisis de múltiples pasadas que construye un grafo de referencias e identifica regiones de código/datos- Formatos:
summary,graph,labels,full
- Formatos:
define_segment— Definir un segmento de memoria por tipo (código, datos, gráficos, texto, zero_page)remove_segment— Eliminar un segmento definido por nombrelist_segments— Listar todos los segmentos de memoria definidos (muestra huecos)clear_segments— Borrar todos los segmentos definidosgenerate_linker_config— Generar una configuración de enlazador cc65 a partir de los segmentos actuales
Herramientas de análisis
x_ref— Encontrar referencias cruzadas a una dirección en la ROMfind_pattern— Buscar un patrón de bytes con comodinesfind_strings— Buscar secuencias de caracteres ASCII o ATASCII imprimiblestrace_control_flow— Trazar estáticamente la ejecución desde una dirección inicialprobe_data— Analizar un rango de memoria para identificar el tipo de datos (texto, gráficos, tabla, charset, lista de visualización, datos de sprite, datos de mapa) con puntuación de confianzagenerate_callgraph— Generar un grafo de llamadas que muestre las relaciones entre subrutinas (formato Mermaid o texto)analyze_coverage— Analizar la cobertura de código: qué bytes se ejecutan frente a datosdiff_roms— Comparar dos archivos ROM o ATR (formato resumen, detallado o diff hexadecimal)
Herramientas de símbolos y página cero
define_symbol— Añadir o actualizar una etiqueta con nombre para una dirección de memoriaremove_symbol— Eliminar un símbolo definido por el usuariolookup_symbol— Buscar la entrada de símbolo para una direcciónlist_symbols— Listar símbolos en la tabla de símbolosset_symbols— Habilitar/deshabilitar grupos de símbolos (hardware, variables del SO, ROM del SO, etiquetas de usuario) para controlar qué nombres aparecen en el desensambladoload_labels— Cargar etiquetas y segmentos desde un archivo sidecarsave_labels— Guardar etiquetas y segmentos actuales en un archivo sidecarannotate_zero_page— Añadir o actualizar una anotación de página ceroshow_zero_page_map— Mostrar anotaciones actuales de página cero
Herramientas de scripting
run_script— Ejecutar una secuencia de comandos desde un archivo de script (admite 33 comandos)
Herramientas de utilidad
calculate— Evaluar expresiones matemáticas con literales hexadecimales (prefijo$)hex_to_decimal— Convertir hexadecimal a decimaldecimal_to_hex— Convertir decimal a hexadecimal
Desensamblado de Múltiples Pasadas
Cuando se pasa analyze=true a disassemble, el motor realiza tres pasadas:
- Pasada 1 — Recopilación de Referencias: Escanea todos los límites de instrucciones en la ROM, registrando destinos JSR, destinos JMP, destinos de ramas, destinos de saltos indirectos y referencias de datos absolutas/indirectas en un
ReferenceGraph. - Pasada 2 — Trazado de Regiones de Código: Desde cada punto de entrada de código, traza el flujo de ejecución (siguiendo JSR, JMP, ramas, deteniéndose en RTS/RTI/BRK) para marcar bytes como código o datos.
- Pasada 3 — Generación de Etiquetas: Produce etiquetas significativas (
sub_XXXX,jmp_XXXX,data_XXXX,L_XXXX) con un orden de prioridad adecuado (usuario > subrutina > datos > hardware > SO > rama).
Ejemplo
; --------------------------------------------------
; 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
Tabla de Símbolos del Hardware Atari
La tabla de símbolos integrada cubre más de 200 entradas en todos los componentes principales de Atari:
| Grupo | Rango | Entradas |
|---|---|---|
| GTIA | $D000–$D01F | 22 registros (gráficos de jugador/proyectil, color, control) |
| POKEY | $D200–$D21F | 32 registros (sonido, E/S, reservados, alias de lectura/escritura) |
| PIA | $D300–$D303 | 4 registros (E/S paralela) |
| ANTIC | $D400–$D41F | 20 registros (DMA, lista de visualización, NMI, reservados) |
| OS ROM | $C000–$FFFF | 13 puntos de entrada (SIO, CIO, vectores) |
| Página cero del SO | $00–$FF | ~220 variables (temporizadores, control de E/S, punto flotante, pantalla, paddles, joysticks) |
Los grupos de símbolos se pueden alternar con set_symbols para evitar conflictos cuando el código de usuario se superpone con los rangos de direcciones del SO.
Operaciones de Escritura ATR
El subsistema de escritura ATR proporciona modificación de imágenes de disco con copia al escribir:
| Operación | Descripción |
|---|---|
extract_atr_file | Extraer un archivo DOS de un ATR al sistema de archivos del host |
inject_atr_file | Reemplazar los datos de una entrada de archivo en un ATR (crea una copia .modified) |
create_atr | Crear un ATR en blanco con un número de sectores y densidad especificados |
write_atr_sector | Escribir datos binarios sin procesar en un sector específico |
write_atr_file | Crear una nueva entrada de archivo DOS con asignación de sectores |
define_filesystem | Describir un diseño de sistema de archivos no DOS para discos de formato personalizado |
Scripting por Lotes
La herramienta run_script ejecuta secuencias de comandos desde archivos de texto:
# 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
Sondeo de Datos
probe_data utiliza 7 heurísticas para identificar tipos de datos en rangos de memoria:
- Detección de cadenas — Secuencias imprimibles ATASCII/ASCII, terminadas en
$9B, terminadas en nulo - Detección de relleno — Secuencias de
$00,$FF,$1A(EOL ATASCII) - Detección de conjuntos de caracteres — Bloques de 1024 bytes (128×8) y 512 bytes (64×8)
- Detección de tablas — Tablas de direcciones de 2 bytes, tablas de búsqueda de 1 byte
- Detección de listas de visualización — Opcodes de lista de visualización ANTIC con extracción LMS
- Detección de datos de sprite — Bloques alineados de 8/16/32 bytes con análisis de variedad de bytes
- Detección de datos de mapa — Patrones de cuadrícula 2D con longitudes de fila consistentes
Cada resultado incluye un nivel de confianza (Alto/Medio/Bajo) y detalles de respaldo.
Flujo de Trabajo Típico
Exploración básica
- Cargar un archivo con
load_rom,load_atr_fileoload_atr_boot. - Inspeccionar la estructura con
rom_infooatr_info. - Usar
hex_dumppara examinar bytes sin procesar,find_stringspara localizar texto. - Desensamblar con
disassemble(modo básico).
Desensamblado guiado por análisis
load_rom→ Cargar el binario.analyze_disassembly format=summary→ Obtener una visión general de código/datos.analyze_disassembly format=labels→ Ver todas las etiquetas generadas automáticamente.probe_data start=$1712 end=$1AD4→ Identificar regiones de datos.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→ Salida consciente de segmentos.generate_callgraph start=$1540 depth=5 format=mermaid→ Visualizar la estructura.- Iterar:
define_symbol→disassemble analyze=true→ revisar.
Flujo de trabajo de refinamiento iterativo
load_rom→ desensamblado inicial con etiquetas automáticas.analyze_disassembly→ identificar regiones de código/datos.define_symbol→ anotar direcciones clave.define_segment→ marcar regiones de código/datos.save_labels→ persistir anotaciones.disassemble analyze=true→ volver a desensamblar con anotaciones.- Revisar, repetir los pasos 3-6 según sea necesario.
Flujo de trabajo de modificación ATR
create_atr output=build/disk.atr sectors=720 density=sd→ disco en blanco.write_atr_sector filePath=build/disk.atr sector=1 input=boot.bin→ escribir sector de arranque.write_atr_file filePath=build/disk.atr name=AGENT.OBJ input=build/AGENT.OBJ→ añadir archivo.extract_atr_file filePath=game.atr name=AGENT.OBJ output=extracted/AGENT.OBJ→ extraer archivo.inject_atr_file filePath=game.atr name=AGENT.OBJ input=build/AGENT.OBJ→ reemplazar archivo.
Persistencia
Los símbolos definidos por el usuario, las anotaciones de página cero y las definiciones de segmentos se guardan automáticamente en un archivo JSON sidecar junto al objetivo cargado:
<rom-or-synthetic-path>.atarihacker.json
El formato sidecar v4 incluye:
- Campo de versión para compatibilidad futura
- Hash SHA-256 de la ROM para verificación de integridad
- Segmentos (nombre, tipo, inicio, fin, comentario)
- Definiciones de sistema de archivos personalizadas
Los archivos sidecar v3 (sin campo de versión) se leen de forma transparente y se actualizan al guardar.
Ejemplo de Prueba de Humo MCP
Esto envía initialize y tools/list directamente a través de 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
Notas
- Los registros se escriben en stderr para que stdout permanezca limpio para el tráfico JSON-RPC de MCP.
- La herramienta
disassembleconanalyze=false(predeterminado) se comporta exactamente como en v3: compatibilidad total hacia atrás. - El código automodificable y el despacho por tabla de saltos (
JMP (table,X)) no se pueden resolver estáticamente; usadefine_segmentpara marcar esas regiones manualmente. - Para detalles completos del diseño, consulta
docs/version4-design.mdy la especificación v4.
Licencia
Este proyecto está licenciado bajo la Licencia MIT. Consulta el archivo LICENSE para más detalles.