
Parst Go-Binaries, um Symbole, Funktionsmetadaten, Typen, Dateipfade und eingebettete Strings wiederherzustellen, einschließlich gestrippter oder UPX-gepackter Samples, mit Unterstützung für den Import in IDA Pro.

GoReSym ist ein Go-Symbolparser, der Programm-Metadaten (wie CPU-Architektur, Betriebssystem, Endianness, Compiler-Version usw.), Funktions-Metadaten (Start- und Endadressen, Namen, Quellen), Dateinamen- und Zeilennummern-Metadaten sowie eingebettete Strukturen und Typen extrahiert. Dieses plattformübergreifende Programm basiert direkt auf dem Open-Source-Go-Compiler und dem Runtime-Code.
Der Upstream-Go-Runtime-Code wurde erweitert, um Folgendes zu behandeln:
moduledata-StrukturReverse-Engineering-Details und Anwendungsbeispiele finden Sie unter https://www.mandiant.com/resources/blog/golang-internals-symbol-recovery.
Vorgefertigte GoReSym-Binärdateien für linux, macos und windows können Sie über den Releases-Tab herunterladen.
Um aus dem Quellcode mit einem aktuellen Go-Compiler zu bauen, rufen Sie den Go-Compiler auf:
go build
Sobald es gebaut ist, rufe GoReSym so auf:
GoReSym.exe -t -d -p /path/to/input.exe
In diesem Beispiel bitten wir GoReSym, Typnamen (-t), Benutzerpaketnamen, Standard-Go-Paketnamen (-d) und in der Datei /path/to/input.exe eingebettete Eingabedateipfade (-p) wiederherzustellen. Die Ausgabe sieht folgendermaßen aus:
{
"Version": "1.14.15",
"BuildId": "Zb9QmokKTiOUgHKmaIwz/wd2rtE3W9PN-um1Ocdzh/qTdqcTY_jVajHy_-TtYv/Z_kJu9M77OjfijEiHMcF",
"Arch": "amd64",
"TabMeta": {
"VA": 5174784,
"Version": "1.2",
"Endianess": "LittleEndian",
"CpuQuantum": 1,
"CpuQuantumStr": "x86/x64",
"PointerSize": 8
},
"ModuleMeta": {
"VA": 5678816,
"Types": 4845568,
"ETypes": 5171904,
"Typelinks": {
"Data": 5171904,
"Len": 695,
"Capacity": 695
},
"ITablinks": {
"Data": 5174688,
"Len": 11,
"Capacity": 11
},
"LegacyTypes": {
"Data": 0,
"Len": 0,
"Capacity": 0
}
},
"Types": [ ... ],
"Files": [ ... ],
"Strings": [ ... ],
"UserFunctions": [ ... ],
"StdFunctions": [ ... ]
}
Hier sind alle verfügbaren Flags:
-d ("default", optional) Flag gibt zusätzlich zu den Benutzerpaketen auch Standard-Go-Pakete aus.-p ("paths", optional) Flag gibt alle im pclntab eingebetteten Dateipfade aus.-t ("types", optional) Flag gibt Go-Typnamen aus.-strings (optional) Flag extrahiert eingebettete Go-Strings aus der Binärdatei durch Analyse der String-Internment-Tabelle.-m <virtual address> ("manual", optional) Flag gibt die RTYPE-Struktur rekursiv an der angegebenen virtuellen Adresse aus-v <version string> ("version", optional) Flag überschreibt die automatische Versionserkennung und verwendet die angegebene Version. Dies ist für einige gestrippte Binärdateien erforderlich. Die Typanalyse schlägt fehl, wenn die Version nicht korrekt ist.-human (optional) Flag gibt eine flache Textauflistung anstelle von JSON aus. Besonders nützlich bei der Ausgabe von Struktur- und Interface-Typen.-about (optional) Flag gibt Lizenzinformationen ausUm diese Informationen in IDA Pro zu importieren, können Sie das Skript unter https://github.com/mandiant/GoReSym/blob/master/IDAPython/goresym_rename.py ausführen. Es liest eine von GoReSym erzeugte JSON-Datei und setzt Symbole/Labels in IDA.
Da sich der Go-Compiler und die Runtime geändert haben, haben sich auch die eingebetteten Metadatenstrukturen geändert. GoReSym unterstützt die folgenden Kombinationen von Go-Releases und Metadaten:
pclntab-Parsing: >= Go 1.2moduledata-Lokalisierung: >= Go 1.2moduledata-Typanalyse: >= Go 1.5Die moduledata-Tabelle, die zur Extraktion von Typen verwendet wird, existiert vor Go 1.5 nicht, daher wird diese Bibliothek niemals die Extraktion von Typen aus sehr alten Go-Versionen unterstützen.
Diese Bibliothek behandelt derzeit die pclntab-Layouts vor 1.2, 1.2, 1.16, 1.18 und 1.20. Beachten Sie, dass die pclntab-Version immer <= der Go-Runtime-Version ist (z. B. verwendet Go-Runtime 1.19 das 1.18-pclntab-Layout); wir streben an, immer die neuesten Runtime-Versionen zu unterstützen.
Ein Großteil des Quellcodes von GoReSym ist aus dem Upstream-Go-Compiler-Quellverzeichnis /internal kopiert. Um dies zum Laufen zu bringen, mussten wir den Quellcode etwas anpassen. Wenn Sie zu GoReSym beitragen möchten, lesen Sie weiter, damit wir diesen Importprozess erklären können.
Aufgrund der Funktionsweise von Go-Paketen mussten wir den Pfad /internal aus dem Quellcodedateibaum entfernen. Dies führte zu umfangreichem Kopieren interner Go-Dateien, wobei der Verzeichnisbaum größtenteils intakt bleibt, aber kleine Änderungen an den Imports vieler Dateien vorgenommen wurden: Verweise auf /internal-Pfade wurden durch github.com/mandiant/GoReSym/ ersetzt.
Wir haben außerdem viele interne Strukturen geändert, um Felder und Methoden zu exportieren. Diese werden von Go upstream nicht exportiert, da Benutzer sich nicht darauf verlassen sollten. Der Zweck dieses Tools besteht jedoch darin, interne Informationen zu extrahieren, daher übernehmen wir die Aufgabe, diese Strukturen zu pflegen. Es ist keine großartige Situation, aber sie lässt sich nicht leicht vermeiden. Wenn Sie dieses Repository aktualisieren, müssen Sie darauf achten, diese Änderungen intakt zu halten. Es ist wahrscheinlich besser, Commits von Upstream manuell zusammenzuführen, anstatt Upstream-Dateien vollständig zu kopieren.
Ich bin offen für Vorschläge, wie dieses Projekt besser strukturiert werden kann, um diese Probleme zu vermeiden und trotzdem mit dem üblichen go build zu kompilieren. Es gibt eine frühere Diskussion mit Go-Maintainern hier.
Abgesehen von einigen trivialen Änderungen befindet sich der Großteil der neuen Logik in /objfile. Beispielsweise definiert die Datei objfile/internals die umgekehrten internen Go-Strukturen, die GoReSym parst.
pclntab-Spezifikation: golang.org/s/go12symtabpclntab-Magics: pclntab.go#L169objfile-Bug(s):
buildID-Legacy-Bug: golang/go#50809