
Reconstrói binários legados do Windows em código-fonte C ao combinar exportações do decompilador Ghidra com LLMs locais, produzindo candidatos verificados por compilação e relatórios baseados em similaridade.
Este repositório é uma reconstrução em andamento do código-fonte do RATS.EXE, a versão original para Windows de Rats! (1994) de Sean O'Connor. Ele compila um executável Win32 com Microsoft Visual C++ 4.1 sob wibo e pode ser testado no DREAMM.
O experimento explora até onde LLMs locais podem levar a reconstrução de código-fonte em uma base de código pequena, porém realista, em vez de um exemplo de brinquedo. A fidelidade da correspondência permanece desigual, o que é útil aqui: o objetivo é apresentar uma visão realista do processo e de suas limitações atuais, e não esconder funções difíceis.
A reconstrução de funções é restrita a LLMs locais. Codex e Claude são usados para a configuração do repositório e a orquestração de benchmarks, mas não têm permissão para escrever ou editar o código-fonte reconstruído.
Salvo indicação em contrário, todos os experimentos usaram o Qwen3.8 27B BF16 em um MacBook Pro de 2024 com Apple M4 Max (CPU de 16 núcleos, GPU de 40 núcleos) e 128 GB de memória. A abordagem funciona — de forma imperfeita, mas útil: as 36 funções mantidas levaram, cada uma, um tempo médio registrado de 2m 32.1s para reconstruir.
Clone com submódulos ou inicialize-os após o clone:
git submodule update --init --recursive
O executável original não está incluído. Baixe a versão gratuita para Windows da página oficial de Rats! e coloque o RATS.EXE na raiz do repositório para usar os alvos original-executable e binary-comparison.
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
O arquivo MSVC 4.1 com checksum fixado, as bibliotecas MSVC 4.1 necessárias, o msvcrt40.dll compatível com o wibo e o DREAMM 4.0x21 são baixados sob demanda. Eles permanecem como dependências locais de build ignoradas e não são commitados.
O diretório ghidra/ versionado contém exportações de assembly e do decompilador para todas as 177 funções internas. O assembly é a autoridade de comparação; o C descompilado é apenas uma semente semântica.
Instale o binary-recons uma vez e execute-o a partir da raiz do repositório:
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
A ferramenta descobre o Qwen automaticamente no cache padrão do Hugging Face; BINARY_RECONS_MODEL_PATH pode substituí-lo. O binary-recons.toml mantém a seleção automática dentro dos intervalos de código do jogo, inicia e encerra o llama.cpp e define os arquivos transacionais e o comando binary-comp. Cada execução limitada semeia uma função a partir do Ghidra, pede ao Qwen reparos focados de compilação ou diff de assembly e retém o melhor candidato seguro que compila. Use --target-score 95 para uma passagem mais profunda ou --dry-run-prompt para inspecionar o prompt sem carregar o Qwen.
Execuções medidas com modelo local são registradas em docs/MODEL_RESULTS.md.
A maioria dos candidatos mantidos foi gerada com o Qwen3.8 27B GGUF da Unsloth em BF16 (Qwen3.8-27B-BF16, servido como qwen3.8-27b-bf16) por meio do llama.cpp com contexto de 32.768 tokens e o preset de modelo qwen. O fluxo de trabalho atual usa a descompilação do Ghidra como semente mecânica, pede ao Qwen apenas um contrato significativo e edições limitadas de código-fonte, segue edições válidas como uma trajetória de reparo e retém o melhor resultado medido por binary-comp. O Gemma 4 31B IT BF16 também foi avaliado, mas nenhum de seus candidatos foi mantido na árvore de código-fonte.
As pontuações abaixo foram remedidas na árvore de código-fonte atual com MSVC 4.1 e binary-comp em 2026-08-16. O tempo registrado inclui a inicialização do servidor gerenciado, a geração ou o reparo, a compilação e a comparação do candidato mantido. Ele exclui execuções exploratórias sem sucesso e turnos de reparo feitos após um candidato retomável já ter sido produzido; esses permanecem disponíveis nos logs de execução.
Agradecimentos especiais a:
| Endereço | Função | Similaridade atual | Tempo registrado |
|---|
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 |
As tentativas de reconstrução dos seguintes endereços foram esgotadas sem reter uma implementação em código-fonte. O tempo gasto é cumulativo em todas as tentativas registradas.
| Endereço adiado | Tempo gasto | Resultado |
|---|---|---|
0x00401000 | 10m 29.7s | Função grande demais para uma primeira passagem limitada; esqueleto original de 1.13% mantido |
0x00403840 | 13m 10.0s | Nenhum candidato compilável; grande demais para uma passagem limitada rápida |
0x00406674 | — | Ignorado: grande demais para uma passagem limitada rápida |