Deterministische PyGhidra-Extraktion, Triage und lokale LLM-Compiler-Backend-Pipeline für die C-Reimplementierung.
Vielen Dank, dass Sie meine Ghidra + LLM-Pipeline heruntergeladen haben.
Dies ist meine erste README. ASL (American Sign Language) ist meine Erstsprache, daher ist mein Englisch nicht perfekt. Ich habe mein Bestes gegeben.
Ich liebe eine alte PC-Simulation, die ich seit meiner Kindheit spiele, und ich möchte sie unter der Haube verbessern.
Wenn ich mir Open-Source-Spiele wie OpenRA und OpenTTD ansehe, habe ich Folgendes gelernt: Bei einer Hobby-Reimplementierung geht es nicht darum, den Originalquellcode zu bekommen. Es geht darum, eine neue Open-Source-Version des Spiels zu bauen, die die Assets des Originals laden kann. Dann kann jeder es erweitern oder dazu beitragen.
Für die Arbeit nutze ich zwei Arten von KI zusammen:
Jede Funktion bekommt ein Label. Das spart viel Zeit, weil ich keine Mühe auf den großen Haufen von OS- und Runtime-Müll verschwende.
|-----------|------------------------------------------------------------------------------------------------------------------
| Label | Bedeutung |
|---|---|
| KEEP | Die eigene Logik des Spiels (zum Beispiel das Flugmodell, das Schadensmodell, TrackIR) |
| WRAP | Java-seitiger Klebstoff, der OS- oder Input-APIs aufruft: Signatur behalten, neuen Body schreiben. |
| (IL-2 1946 ist eine interessante Engine: C++ und Java zusammen.) | |
| REPLACE | Alte C-Runtime, Allocator, Thunks: Der Compiler oder das OS stellt sie bereit, daher braucht eine neue 64-Bit-Version sie nicht |
| UNKNOWN | Unklar: von Hand ansehen |
| ----------- | ------------------------------------------------------------------------------------------------------------------ |
In meinem Testprogramm waren etwa 44 % der Funktionen REPLACE, sie mussten also nie konvertiert werden.
Am Anfang habe ich dem C-Pseudocode vertraut, dass er alle Antworten enthält. Das war naiv. Er ist Ghidras Interpretation des Assemblys und er rät (Variablentypen, verlorene Argumente).
Das Assembly ist die rohe Wahrheit. Es hat keine Variablentypen, aber es enthält das exakte Verhalten jeder Funktion. Die Skripte lesen also das Assembly und verwandeln es in einen Blueprint in C-ähnlicher Form. Ghidras C wird nur als Hinweis behalten.
Meine frühen Tests nutzten die lokalen LLMs (Qwen 2.5 Coder, DeepSeek Coder V2 Lite, Mellum 2), um das Assembly direkt zu lesen. Es funktionierte nie zuverlässig. Sie halluzinierten, weil sie dafür gemacht sind, Code zu schreiben, nicht rohen Maschinencode zu lesen.
Nach vielen fehlgeschlagenen Experimenten habe ich die Arbeit aufgeteilt:
HINWEIS: Wie Python die Antwort prüft
Textprüfungen: der Funktionsname, jeder Aufruf, jedes Global und jeder String aus dem Blueprint, die Schleifen, die Schrittgrößen, die verglichenen Konstanten, der Rückgabewert und dass keine Registernamen oder erfundenen Namen übrig bleiben.
gcc-Kompilierungsprüfung: Der Code wird mit gcc kompiliert (nur Syntax, nichts wird ausgeführt). Das hat sehr geholfen. In einem frühen Durchlauf bestanden die Textprüfungen die Antworten von Mellum 2, aber keine davon ließ sich kompilieren, wegen eines Header-Kommentars, der außerhalb eines Kommentars geschrieben wurde. gcc erkennt, was Textprüfungen nicht sehen können: nicht deklarierte oder neu deklarierte Variablen, falsche Typen und fehlerhafte Klammern oder Semikolons. Eine Funktion gilt nur dann als PASS, wenn sowohl die Textprüfungen als auch die Kompilierung in Ordnung sind. gcc beweist nicht, dass die Logik korrekt ist, daher lese ich den Code weiterhin gegen den Blueprint.
Wenn eine Prüfung fehlschlägt, erhält das LLM die Liste der fehlgeschlagenen Punkte und versucht es noch einmal.
Python behebt kleine Fehler von selbst, ohne das LLM: Es deklariert jede Variable einmal, schließt lose Header-Zeilen in einen Kommentar ein, sorgt dafür, dass das letzte return das richtige Ergebnis zurückgibt, und fügt die Includes und Deklarationen hinzu.
Die Checkliste entstand, nachdem ich gesehen hatte, dass die LLMs bei sehr langen Funktionen scheiterten. Sie funktioniert wie die Checkliste, die ein Pilot vor dem Start und der Landung verwendet. Python schreibt sie aus der Funktion und prüft die Antwort dagegen. In meinen Tests begannen die langen Funktionen zu bestehen, und die Durchläufe wurden schneller.
|-------------------|---------------------------------------|---------------------------------------------
| Ordner | Was er tut | Lesen |
|---|---|---|
ghidra_pipeline | Dump, Gruppierung, Triage, Rollen | ghidra_pipeline/INSTRUCTION.txt |
llm_pipeline | Blueprints und der LLM-Runner (v3) | llm_pipeline/INSTRUCTION_BLUEPRINT_LLM.txt |
| ------------------- | --------------------------------------- | --------------------------------------------- |
Beginne mit ghidra_pipeline und wechsle dann zu llm_pipeline, wenn du bereit bist, deine lokalen LLMs zu verwenden.
Analysiere zunächst dein Programm in PyGhidra und führe PyGhidra Scripts/decompile_full_dump.py aus.
Die beiden INSTRUCTION-Dateien erklären die Ordnerstruktur. Dann:
Analysiere zunächst dein Programm in PyGhidra und führe PyGhidra Scripts/decompile_full_dump.py aus.
Die beiden INSTRUCTION-Dateien erklären die Ordnerstruktur. Dann:
python .\make_full_lite_v2.py --in . --out .\OUT
python .\triage_evidence_v2.py --lite .\OUT\LITE_AC
python .\build_roles_v2.py --triage .\OUT\TRIAGE
python .\blueprint_v3.py --group ".\SOURCE\LITE_AC\<GroupName>" --out ".\G_<GroupName>\BLUEPRINT_v3"
python .\run_blueprint_llm_v3.py --bp ".\G_<GroupName>\BLUEPRINT_v3" --out ".\G_<GroupName>\RUN1_v3_<model>" --model <model name>
Du benötigst Ghidra mit PyGhidra, Python 3, LM Studio (ein geladenes Modell) und gcc (empfohlen, wird als Kompilierprüfung verwendet).