
Émulateur natif de Pcode
Ce plugin expérimental pour Ghidra vous permet de gérer facilement l'émulation native de pcode. Plus aucun script n'est nécessaire, utilisez-le simplement directement depuis Ghidra. Il peut être particulièrement utile pour travailler avec une variété de processeurs exotiques qui ne sont pas pris en charge par les émulateurs courants.
Si le processeur/la VM est pris en charge par Ghidra pour la rétro-ingénierie, il peut être émulé ! Par exemple, l'émulation d'instructions eBPF est démontrée ci-dessous :

En substance, le plugin est un wrapper étendu autour des classes du package ghidra.app.emulator. Voici ce qui a été implémenté :
Bien que l'émulation PCode implique idéalement une unification, la plupart des processeurs nécessitent leur propre approche. N'hésitez pas à signaler tout problème rencontré. J'aimerais vraiment tester tous les processeurs, mais c'est difficilement possible.

Contient toutes les fenêtres du plugin : Stack view, Registers, Breakpoints view et Main Window.

Contient les raccourcis clavier pour définir le début et la fin de l'émulation, les points d'arrêt, et appliquer les octets modifiés à l'état de l'émulateur.
Modifiez les registres comme vous le souhaitez. Définir le registre de liaison (flèche verte) aidera l'émulateur à comprendre quel registre contient l'adresse de retour. Le plugin sait comment cela fonctionne via la pile, le registre lr et les registres AARCH64 et MIPS. Si vous en avez un exotique, sélectionnez le registre de liaison et appuyez sur le bouton.
Lorsque vous ouvrez votre programme dans le CodeBrowser, GhidraEmu mappera automatiquement l'espace de la pile. Le pointeur de pile sera placé au milieu de la plage de pile. Cela vous permet de définir des valeurs en haut ou en bas des cadres de pile. Faites-la défiler si vous rencontrez des blocages lors de la mise à jour ou de la réinitialisation. Pendant le processus d'émulation, si le programme a besoin de plus d'espace pour la pile, le plugin l'allouera automatiquement.
Si des octets changent pendant l'émulation, vous les verrez dans le ByteViewer classique. Ne vous inquiétez pas, ils seront réinitialisés à leurs valeurs d'origine après avoir appuyé sur le bouton « Reset ».
Si vous avez effectué des modifications, informez l'émulateur des octets modifiés (la pile se met à jour automatiquement, pas besoin de le faire). Après modification, sélectionnez-les (ils seront en vert), puis utilisez cette option (ou utilisez le raccourci « M »).

Ici, le plugin affiche des informations de sortie. Par exemple, des messages d'erreur d'émulation comme celui-ci :

La fonctionnalité « Jump Over » vous permet de sauter une instruction si vous ne souhaitez pas émuler celle en cours pour une raison quelconque. Étant donné que le processus d'émulation sera interrompu si une tentative de lecture de mémoire non initialisée est détectée, cette fonctionnalité vous permet de contourner ce problème. Regardez un exemple. Voici l'une des premières instructions de nombreux programmes x86_64, la sauvegarde du canari de pile :
MOV RAX, qword ptr FS:[0x28]
Nous allons simplement essayer de tricher un peu et de sauter par-dessus en augmentant la valeur du PC. Pour ce faire, arrêtez-vous sur l'instruction que vous ne voulez pas émuler et appuyez sur la touche J. Sinon, continuer à avancer pas à pas entraînerait une erreur de lecture de mémoire non initialisée.

Si vous vous arrêtez sur une instruction qui mène à une sous-routine (appel interne) et que vous souhaitez émuler tout le code jusqu'à l'instruction suivante (« step over » classique), appuyez sur la touche F6, et cela se produira certainement :

Quelques points importants à prendre en compte :
Utilisez gradle pour compiler l'extension : GHIDRA_INSTALL_DIR=${GHIDRA_HOME} gradle puis utilisez Ghidra pour l'installer : File → Install Extensions...
Dans le CodeBrowser, allez dans File → Configure → Miscellaneous et cochez la case du plugin GhidraEmu.
Vous avez rencontré des bogues en utilisant le plugin ou vous avez des idées d'amélioration ? N'hésitez pas à ouvrir un nouveau ticket et je m'en occuperai.
Les restrictions d'EmulatorHelper ne permettent pas d'utiliser l'espace programme dans un autre. Ainsi, votre bibliothèque partagée externe, par exemple, ne connaîtra jamais l'espace mémoire du programme, et vice versa. Vous ne pouvez donc pas l'émuler comme un seul processus avec un seul espace mémoire. Dites-moi si quelque chose m'échappe ici.