
Reconstruye binarios Windows heredados en código fuente C combinando exportaciones del descompilador de Ghidra con LLM locales, produciendo candidatos verificados por compilación e informes basados en similitud.
Este repositorio es una reconstrucción en curso del código fuente de
RATS.EXE, la versión original para Windows de
Rats! (1994) de Sean O'Connor. Compila
un ejecutable Win32 con Microsoft Visual C++ 4.1 bajo
wibo y puede probarse en
DREAMM.
El experimento explora hasta dónde pueden llegar los LLM locales en la reconstrucción de código fuente de una base de código pequeña pero realista, en lugar de un ejemplo de juguete. La fidelidad de las coincidencias sigue siendo desigual, lo cual resulta útil aquí: el objetivo es presentar una visión realista del proceso y sus limitaciones actuales, no ocultar funciones difíciles.
La reconstrucción de funciones está restringida a LLM locales. Codex y Claude se utilizan para la configuración del repositorio y la orquestación de puntos de referencia, pero no se les permite escribir o editar el código fuente reconstruido.
Salvo que se indique lo contrario, todos los experimentos utilizaron Qwen3.8 27B BF16 en un MacBook Pro de 2024 con un Apple M4 Max (CPU de 16 núcleos, GPU de 40 núcleos) y 128 GB de memoria. El enfoque funciona—de manera imperfecta, pero útil: las 36 funciones conservadas tardaron un tiempo medio registrado de 2m 32,1s cada una en reconstruirse.
Clona con submódulos, o inicialízalos después de clonar:
git submodule update --init --recursive
El ejecutable original no está incluido. Descarga la versión gratuita para Windows
desde la página oficial de Rats! y
coloca su RATS.EXE en la raíz del repositorio para usar los objetivos de ejecutable original y
comparación binaria.
make # build out/RATS_RE.EXE, .map, .obj, and .asm
make toolchain # download, extract, and verify Microsoft Visual C++ 4.1
make run # launch the rebuilt executable in DREAMM
make run-original # launch the preserved original RATS.EXE
make test # bounded DREAMM smoke test of the rebuilt executable
make test-original # bounded DREAMM smoke test of the original executable
make debug # start the rebuilt executable in DREAMM's debugger
make report # report similarity for every reconstructed function
make compare-func FUNC=SaveHighScores ADDR=00409092
El archivo MSVC 4.1
con suma de verificación fijada,
las bibliotecas MSVC 4.1 necesarias, el msvcrt40.dll compatible con wibo y DREAMM
4.0x21 se descargan bajo demanda. Siguen siendo dependencias de compilación locales ignoradas
y no se incluyen en el repositorio.
El directorio ghidra/ incluido en el repositorio contiene exportaciones de ensamblador y descompilador para
las 177 funciones internas. El ensamblador es la autoridad de comparación; el C descompilado
es solo una semilla semántica.
Instala binary-recons una vez, y luego
ejecútalo desde la raíz del repositorio:
python3 -m pip install -e /path/to/binary-recons
binary-recons --next-function # reconstruct the next safe missing target
binary-recons --address 0x409092 # reconstruct or improve a specific target
La herramienta descubre Qwen automáticamente en la caché estándar de Hugging Face;
BINARY_RECONS_MODEL_PATH puede sobrescribirla. binary-recons.toml mantiene la selección
automática dentro de los rangos de código del juego, inicia y detiene llama.cpp, y define
los archivos transaccionales y el comando binary-comp. Cada ejecución acotada siembra una
función desde Ghidra, pide a Qwen reparaciones centradas en compilación o diferencias de ensamblador,
y conserva el mejor candidato compilable y seguro. Usa --target-score 95 para una
pasada más profunda o --dry-run-prompt para inspeccionar el prompt sin cargar Qwen.
Las ejecuciones medidas con modelos locales se registran en docs/MODEL_RESULTS.md.
La mayoría de los candidatos conservados se generaron con el
Qwen3.8 27B GGUF de Unsloth en BF16
(Qwen3.8-27B-BF16, servido como qwen3.8-27b-bf16) mediante llama.cpp con un
contexto de 32.768 tokens y el ajuste preestablecido de modelo qwen. El flujo de trabajo actual usa
la descompilación de Ghidra como semilla mecánica, pide a Qwen solo un
contrato significativo y ediciones de código fuente acotadas, sigue las ediciones válidas como trayectoria de reparación,
y conserva el mejor resultado medido por binary-comp. Gemma 4 31B IT BF16 también fue
evaluada, pero ninguno de sus candidatos se conserva en el árbol de fuentes.
Las puntuaciones siguientes se volvieron a medir desde el árbol de fuentes actual con MSVC 4.1 y
binary-comp el 2026-08-16. El tiempo registrado incluye el arranque del servidor gestionado,
la generación o reparación, la compilación y la comparación del candidato conservado. Excluye
ejecuciones exploratorias fallidas y turnos de reparación realizados después de que ya se hubiera producido un
candidato reanudable; esos permanecen disponibles en los registros de ejecución.
| Address | Function | Current similarity | Logged time |
|---|---|---|---|
0x0040215C | IsLevelIndexInRange | 65.31% | 3m 06.4s |
0x00402205 | ShowLevelComplete | 93.96% | 5m 26.1s |
0x0040250C | SubmitHighScore | 97.37% | 1m 49.7s |
0x004026D0 | RenderScoreboard | 95.40% | 2m 30.9s |
0x00402BF3 | AddLevelToTable | 73.85% | 4m 04.6s |
0x00402DC6 | UpdateGameDisplay | 78.18% | 1m 36.4s |
0x00402EE7 | GetLevelDisplayInfo | 71.70% | 2m 15.9s |
0x00402FD5 | GetLevelIndex | 87.27% | 5m 48.3s |
0x00403430 | IsBombAtLevel | 80.62% | 27.3 s |
0x00403607 | PlaceLevel | 80.00% | 2m 32.6s |
0x00404764 | DrawLevelIndicator | 97.33% | 1m 35.6s |
0x0040499F | RenderCornerGlyph | 69.83% | 1m 50.9s |
0x00404D6E | DrawBitmapPair | 98.67% | 1m 04.6s |
0x00404E3B | RenderBitmapToWindow | 94.74% | 26.4 s |
0x00404ECE | DrawBitmapToWindow | 95.59% | 59.3 s |
0x00404F8B | DrawScore | 96.20% | 1m 32.4s |
0x0040507F | DrawScorePanel | 97.97% | 2m 45.0s |
0x0040525D | DrawScoreDigits | 94.20% | 2m 13.7s |
0x00405343 | RenderScoreOverlay | 77.78% | 1m 28.1s |
0x0040546B | DrawFrameBorder | 84.93% | 37.0 s |
0x0040552E | ExplodeBomb | 64.71% | 1m 50.9s |
0x0040560E | RenderExplosionWave | 85.07% | 5m 40.0s |
0x0040591A | DrawBombExplosion | 89.31% | 1m 45.8s |
0x00405AF5 | DrawPausedOverlay | 96.21% | 1m 05.1s |
0x00405C52 | HighScoreDialogProc | 79.82% | 41.5 s |
0x00405DB8 | ScorePanelDialogProc | 50.34% | 1m 53.1s |
0x00405F72 | DemoVersionDialogProc | 46.31% | 4m 18.5s |
0x004061D3 | OrderDialogProc | 53.16% | 10m 46.5s |
0x00408854 | DrawStartButton | 70.80% | 1m 35.6s |
0x00408A51 | UpdateMainMenuState | 97.56% | 28.9 s |
0x00408AD3 | InitializeGameLevel | 83.72% | 5m 35.7s |
0x00408E6A | LoadLevelData | 77.50% | 52.5 s |
0x00408F02 | LoadHighScores | 79.61% | 1m 15.0s |
0x00409092 | SaveHighScores | 94.12% | 1m 25.9s |
0x0040910C | LoadLevelBitmaps | 98.93% | 7m 08.4s |
0x00409DB6 | IsRatsHelpFile | 91.67% | 41.5 s |
Los intentos de reconstrucción de las siguientes direcciones se agotaron sin conservar una implementación en el código fuente. El tiempo invertido es acumulativo en todos los intentos registrados.