Ce plugin expérimental Ghidra vous permet de gérer facilement l'émulation pcode native. Aucun script n'est plus nécessaire, utilisez-le simplement directement depuis Ghidra. Cela 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/VM est pris en charge par Ghidra pour l'ingénierie inverse, il peut être émulé ! Par exemple, l’émulation des instructions eBPF est illustrée ci-dessous :
Essentiellement, le plugin est un wrapper étendu autour des classes du package ghidra.app.emulator
. Voici ce qui a été mis en œuvre :
Bien que l’émulation PCode implique idéalement une unification, la plupart des processeurs ont besoin de leur propre approche. N'hésitez pas à signaler tout problème que vous rencontrez. J'aimerais vraiment tester tous les processeurs, mais ce n'est guère possible.
Contient toutes les fenêtres du plugin : vue Pile, Registres, vue Points d'arrêt et fenêtre principale.
Contient des 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.
Changez de registre comme vous le souhaitez. La définition du registre de lien (flèche verte) aidera l'émulateur à comprendre quel registre contient l'adresse de retour. Le plugin sait comment il fonctionne via la pile, le registre lr, AARCH64 et les registres MIPS. Si vous en avez un exotique, sélectionnez le lien s'inscrire et appuyez sur le bouton.
Lorsque vous ouvrez votre programme dans le СodeBrowser, 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-le 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'attribuera 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 "Réinitialiser" .
Si vous avez apporté des modifications, informez l'émulateur des octets modifiés (la pile se met à jour automatiquement - ce n'est pas nécessaire). Après les modifications, sélectionnez-les (ils seront verts) et appuyez sur cette option (ou utilisez la touche de raccourci "M").
Ici, le plugin imprime les informations de sortie. Par exemple, des messages d'erreur d'émulation comme celui-ci :
La fonction "Saut par-dessus" vous permet d'avancer d'une instruction si vous ne souhaitez pas émuler l'instruction actuelle 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 la contourner. Regardez un exemple. Voici l'une des premières instructions de nombreux programmes x86_64, sauvegarde de la pile Canary :
MOV RAX, qword ptr FS:[0x28]
Nous allons juste essayer de tricher un peu et de sauter par-dessus en augmentant la valeur du PC. Pour ce faire, arrêtez-vous à l'instruction que vous ne souhaitez pas émuler et appuyez sur la touche de raccourci J
Sinon, aller plus loin entraînerait une erreur de lecture de mémoire non initialisée.
Si vous vous arrêtez à une instruction qui mène à un sous-programme (appel interne) et que vous souhaitez tout émuler jusqu'à l'instruction suivante (classique "step over"), appuyez sur la touche de raccourci F6
, et cela se produira certainement :
Quelques points importants à considérer :
Utilisez gradle pour construire l'extension : GHIDRA_INSTALL_DIR=${GHIDRA_HOME} gradle
et utilisez Ghidra pour l'installer : File → Install Extensions...
Dans le CodeBrowser, accédez à File → Configure → Miscellaneous
et cochez la case du plugin GhidraEmu.
Vous avez rencontré des bugs lors de l’utilisation du plugin ou vous avez des idées d’améliorations ? N'hésitez pas à ouvrir un nouveau numéro et je le découvrirai.
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. Faites-moi savoir si je manque quelque chose ici.