Un plugin BinaryNinja pour représenter graphiquement un arbre d'instructions BNIL et des matchers d'instructions python de méta-programme.
L'installation est prise en charge de deux manières, la première à l'aide du nouveau gestionnaire de plugins et la seconde étant une installation manuelle.
Utilisez le nouveau gestionnaire de plugins en sélectionnant "Gérer les plugins" dans le menu "Modifier". Recherchez dans la liste des plugins "BNIL Instruction Graph", faites un clic droit dessus et cliquez sur "Installer", puis cliquez à nouveau avec le bouton droit et sélectionnez "Activer".
$ git clone https://github.com/withzombies/bnil-graph.git
$ cd ~/Library/Application Support/Binary Ninja/plugins
$ ln -s ~/git/bnil-graph .
Pour utiliser bnil-graph, faites un clic droit sur une instruction et sélectionnez "BNIL Instruction Graph". Cela représente graphiquement les instructions BNIL associées à cette adresse et les affiche sous forme de formulaire HTML.
Binary Ninja ajoute des accesseurs d'opérandes de manière dynamique, de ce fait, les accessoires pratiques n'apparaissent pas dans les appels dir()
ou dans la documentation de l'API. bnil-graph montre la structure de l'instruction IL, y compris ses jolis noms d'accesseurs (tels que insn.src
pour le registre source ou la mémoire)
Exemple de graphique :
En plus du plugin graph, bnil-graph générera également une fonction de correspondance qui correspondra exactement aux instructions sélectionnées. Cette fonctionnalité permettra aux nouveaux développeurs de plugins de faire correspondre rapidement les instructions. L'utilisation prévue est de trouver une instruction similaire à celle que vous souhaitez faire correspondre, de générer une fonction matcher, puis de modifier la fonction générée pour mieux répondre à vos besoins.
Un exemple serait d'essayer de trouver toutes les instructions MediumLevelILSSA MLIL_CALL_SSA qui prennent 3 paramètres. J'ai généré un matcher avec une fonction sans rapport avec 0 paramètre :
def match_MediumLevelILSSA_140001194_0 ( insn ):
# mem#1 = 0x14000d49c() @ mem#0
if insn . operation != MediumLevelILOperation . MLIL_CALL_SSA :
return False
# invalid
if insn . output . operation != MediumLevelILOperation . MLIL_CALL_OUTPUT_SSA :
return False
if insn . output . dest_memory != 0x1 :
return False
if len ( insn . output . dest ) != 0 :
return False
# 0x14000d49c
if insn . dest . operation != MediumLevelILOperation . MLIL_CONST_PTR :
return False
if insn . dest . constant != 0x14000d49c :
return False
if len ( insn . params ) != 0 :
return False
if insn . src_memory != 0x0 :
return False
return True
Nous pouvons modifier cela pour supprimer certaines contraintes spécifiques :
def match_MediumLevelILSSA_140001194_0 ( insn ):
# mem#1 = 0x14000d49c() @ mem#0
if insn . operation != MediumLevelILOperation . MLIL_CALL_SSA :
return False
# invalid
if insn . output . operation != MediumLevelILOperation . MLIL_CALL_OUTPUT_SSA :
return False
# 0x14000d49c
if insn . dest . operation != MediumLevelILOperation . MLIL_CONST_PTR :
return False
if len ( insn . params ) != 0 :
return False
return True
Nous avons supprimé la destination de l'appel et les contraintes de versionnage de la mémoire. Ensuite, mettez à jour la vérification des paramètres pour vérifier 3 paramètres :
def match_3_param_MLIL_CALL_SSA ( insn ):
if insn . operation != MediumLevelILOperation . MLIL_CALL_SSA :
return False
if insn . output . operation != MediumLevelILOperation . MLIL_CALL_OUTPUT_SSA :
return False
if insn . dest . operation != MediumLevelILOperation . MLIL_CONST_PTR :
return False
if len ( insn . params ) != 3 :
return False
return True
Maintenant, nous avons un matcher qui identifiera les instructions MLIL_CALL_SSA avec 3 paramètres ! Parcourez maintenant les instructions MLIL SSA et appelez le matcher et nous avons terminé :
if __name__ == '__main__' :
bv = binaryninja . BinaryViewType . get_view_of_file ( sys . argv [ 1 ])
bv . update_analysis_and_wait ()
for func in bv . functions :
mlil = func . medium_level_il
for block in mlil . ssa_form :
for insn in block :
if match_3_param_MLIL_CALL_SSA ( insn ):
print "Match: {}" . format ( insn )
Exemple de correspondance :
Ce projet est protégé par Ryan Stortz (@withzombies) et est disponible sous la LICENCE Apache 2.0.