
Scripts Ghidra pour récupérer les définitions de chaînes dans les binaires Go
Scripts pour récupérer les définitions de chaînes dans les binaires Go avec l'analyse P-Code. Testé avec x86, x86-64, ARM et ARM64.
Ils se trouvent dans la catégorie Golang du Script Manager.
GoDynamicStrings.java
GoFuncCallStrings.java
GoStaticStrings.java
GoKnownStrings.java
data/known_strings.json.GoStringFiller.java
go.string.* après l'analyse initiale, en se basant sur l'ordre croissant de longueur des données de chaînes.Il existe également quelques variantes spéciales du script d'analyse dynamique des chaînes :
GoDynamicStringsSingle.java
GoDynamicStrings.java, mais utilise un seul processus de décompilateur. Utilisez-le si l'analyse d'un binaire amène les processus de décompilateur parallèles à épuiser la mémoire système.GoDynamicStringsHigh.java
Il se trouve dans la catégorie PCode du Script Manager.
PrintHighPCode.java
Voici le processus général pour utiliser ces scripts afin de récupérer les définitions de chaînes dans un binaire Go :
.rodata, .rdata ou __rodata. Cliquez ensuite avec le bouton droit dans le listing du code et choisissez « Clear Code Bytes ».GoKnownStrings.java pour détecter certaines chaînes standard.GoStaticStrings.java.GoFuncCallStrings.java (si la version du binaire Golang est prise en charge par les fonctionnalités Golang intégrées de Ghidra).GoDynamicStrings.java.GoStringFiller.java.
go.string.* sur la première chaîne d'un octet.Dans Ghidra :
Pour Eclipse avec le plugin GhidraDev :
Compiler avec Eclipse :
Compiler directement avec Gradle :
$ cd Ghostrings
$ gradle -PGHIDRA_INSTALL_DIR=<ghidra_install_dir>
Un problème bien connu de la rétro-ingénierie des programmes Go est que l'absence de terminateurs nuls dans les chaînes Go rend difficile la récupération des définitions de chaînes à partir des binaires compilés. De nombreuses valeurs de chaînes constantes d'un programme Go sont stockées ensemble dans un énorme bloc du binaire compilé, sans caractères de terminaison intégrés aux données de chaînes pour marquer où une chaîne se termine et où une autre commence. Même un programme simple qui se contente d'afficher « Hello world! » contient plus de 1 500 chaînes liées au runtime Go et à d'autres bibliothèques standard. Cela peut amener les implémentations typiques de découverte de chaînes ASCII, comme celle fournie par Ghidra, à créer des définitions de chaînes faussement positives de dizaines de milliers de caractères.
Au lieu de chaînes terminées par un octet nul, Go utilise une structure de chaîne composée d'un pointeur et d'une valeur de longueur. De nombreuses structures de chaînes sont créées sur la pile du programme à l'exécution, de sorte que la récupération des emplacements de début et des valeurs de longueur de chaque chaîne nécessite l'analyse du code machine compilé. Il existe quelques scripts qui effectuent cette analyse en recherchant certains modèles d'instructions x86-64, mais ils ne détectent pas les structures créées avec des variantes d'instructions non traitées qui ont finalement le même effet sur la pile, et ils sont également limités à une ISA spécifique.
Ghostrings évite ces deux problèmes en travaillant avec les opérations P-Code simplifiées et indépendantes de l'architecture produites par l'analyse du décompilateur de Ghidra.
Copyright 2022 NCC Group. Publié sous licence GPLv3 (voir LICENSE).
Auteur principal du projet : James Chambers [email protected]
go.string.* et définissez toutes les chaînes dont les points de début et de fin sont évidents.
GoStringFiller.java, identifiez où les longueurs de chaînes changent dans les données de chaînes non définies et définissez les chaînes les plus proches de cette limite. Réexécutez ensuite GoStringFiller.java pour combler automatiquement les emplacements où il peut déterminer correctement la longueur des chaînes restantes non définies.