
Native Pcode emulator
Dieses experimentelle Ghidra-Plugin ermöglicht es Ihnen, einfach mit nativer Pcode-Emulation zu arbeiten. Skripte werden nicht mehr benötigt, verwenden Sie es einfach direkt aus Ghidra. Es kann besonders nützlich sein, wenn Sie mit einer Vielzahl exotischer Prozessoren arbeiten, die von gängigen Emulatoren nicht unterstützt werden.
Wenn der Prozessor/die VM von Ghidra für das Reverse Engineering unterstützt wird, kann er emuliert werden! Zum Beispiel wird unten die Emulation von eBPF-Anweisungen demonstriert:

Im Wesentlichen ist das Plugin ein erweiterter Wrapper um die Klassen im Paket ghidra.app.emulator. Folgendes wurde implementiert:
Obwohl PCode-Emulation idealerweise eine Vereinheitlichung bedeutet, benötigen die meisten Prozessoren ihren eigenen Ansatz. Zögern Sie nicht, alle Probleme zu melden, auf die Sie stoßen. Ich würde wirklich gerne alle Prozessoren testen, aber das ist kaum möglich.

Enthält alle Plugin-Fenster: Stack-Ansicht, Register, Haltepunkt-Ansicht und Hauptfenster.

Enthält Hotkeys zum Festlegen von Start und Ende der Emulation, von Haltepunkten und zum Anwenden geänderter Bytes auf den Emulatorzustand.
Ändern Sie die Register nach Belieben. Das Setzen des Link-Registers (grüner Pfeil) hilft dem Emulator zu verstehen, welches Register die Rücksprungadresse enthält. Das Plugin weiß, wie das über den Stack, das LR-Register sowie AARCH64- und MIPS-Register funktioniert. Wenn Sie ein exotisches Register haben, wählen Sie das Link-Register aus und drücken Sie die Schaltfläche.
Wenn Sie Ihr Programm im CodeBrowser öffnen, bildet GhidraEmu den Stack-Speicherplatz automatisch ab. Der Stack-Pointer wird in der Mitte des Stack-Bereichs gesetzt. Dadurch können Sie Werte am oberen oder unteren Ende der Stack-Frames setzen. Scrollen Sie, wenn es beim Aktualisieren oder Zurücksetzen zu Aussetzern kommt. Während der Emulation weist das Plugin automatisch mehr Speicherplatz für den Stack zu, falls das Programm diesen benötigt.
Wenn sich während der Emulation Bytes ändern, sehen Sie diese im klassischen ByteViewer. Keine Sorge, nach dem Drücken der „Reset“-Schaltfläche werden sie auf ihre ursprünglichen Werte zurückgesetzt.
Wenn Sie Änderungen vorgenommen haben, teilen Sie dem Emulator die geänderten Bytes mit (der Stack wird automatisch aktualisiert – nicht nötig). Wählen Sie sie nach dem Ändern aus (sie werden grün) und drücken Sie diese Option (oder verwenden Sie den Hotkey „M“).

Hier gibt das Plugin Ausgabeinformationen aus. Zum Beispiel Emulationsfehlermeldungen wie diese:

Die Funktion „Jump Over“ ermöglicht es Ihnen, eine Anweisung zu überspringen, wenn Sie die aktuelle aus irgendeinem Grund nicht emulieren möchten. Da der Emulationsprozess abgebrochen wird, wenn ein Versuch erkannt wird, nicht initialisierten Speicher zu lesen, können Sie ihn mit dieser Funktion umgehen. Sehen Sie sich ein Beispiel an. Hier ist eine der ersten Anweisungen in vielen x86_64-Programmen, das Sichern des Canary-Werts auf dem Stack:
MOV RAX, qword ptr FS:[0x28]
Wir versuchen einfach, ein wenig zu schummeln und darüber zu springen, indem wir den PC-Wert erhöhen. Halten Sie dazu an der Anweisung an, die Sie nicht emulieren möchten, und drücken Sie die J-Taste. Andernfalls würde ein weiterer Schritt zu einem Fehler beim Lesen nicht initialisierten Speichers führen.

Wenn Sie an einer Anweisung anhalten, die zu einer Unterroutine (internem Aufruf) führt, und Sie alles bis zur nächsten Anweisung emulieren möchten (klassisches „Step Over“), drücken Sie die F6-Taste, und genau das wird passieren:

Einige wichtige Punkte, die Sie beachten sollten:
Verwenden Sie Gradle, um die Erweiterung zu bauen: GHIDRA_INSTALL_DIR=${GHIDRA_HOME} gradle und verwenden Sie Ghidra, um sie zu installieren: File → Install Extensions...
Gehen Sie im CodeBrowser zu File → Configure → Miscellaneous und aktivieren Sie das Kontrollkästchen für das GhidraEmu-Plugin.
Sind Ihnen bei der Verwendung des Plugins Fehler begegnet oder haben Sie Ideen für Verbesserungen? Scheuen Sie sich nicht, ein neues Issue zu eröffnen, und ich werde mich darum kümmern.
Die Einschränkungen des EmulatorHelper erlauben nicht, den Programm-Adressraum in einem anderen zu verwenden. Ihre externe Shared Library wird zum Beispiel also nie etwas über den Programm-Adressraum erfahren und umgekehrt. Sie können das also nicht als einen Prozess mit einem Adressraum emulieren. Lassen Sie mich wissen, falls ich hier etwas übersehe.