Ein BinaryNinja-Plugin zur grafischen Darstellung eines BNIL-Befehlsbaums und Metaprogramm-Python-Befehls-Matchern.
Die Installation wird auf zwei Arten unterstützt: die erste mit dem neuen Plugin-Manager und die zweite durch eine manuelle Installation.
Nutzen Sie den neuen Plugin-Manager, indem Sie im Menü „Bearbeiten“ die Option „Plugins verwalten“ auswählen. Durchsuchen Sie die Plugin-Liste nach „BNIL Instruction Graph“, klicken Sie mit der rechten Maustaste darauf und klicken Sie auf „Installieren“. Klicken Sie dann erneut mit der rechten Maustaste und wählen Sie „Aktivieren“.
$ git clone https://github.com/withzombies/bnil-graph.git
$ cd ~/Library/Application Support/Binary Ninja/plugins
$ ln -s ~/git/bnil-graph .
Um bnil-graph zu verwenden, klicken Sie mit der rechten Maustaste auf eine Anweisung und wählen Sie „BNIL Instruction Graph“. Dadurch werden die mit dieser Adresse verknüpften BNIL-Anweisungen grafisch dargestellt und als HTML-Formular angezeigt.
Binary Ninja fügt Operandenzugriffsfunktionen dynamisch hinzu. Aus diesem Grund werden die praktischen Zugriffsfunktionen nicht in dir()
-Aufrufen oder in der API-Dokumentation angezeigt. bnil-graph zeigt die Struktur des IL-Befehls einschließlich seiner netten Zugriffsnamen (z. B. insn.src
für das Quellregister oder den Speicher).
Beispielgrafik:
Zusätzlich zum Graph-Plugin generiert bnil-graph auch eine Matcher-Funktion, die die ausgewählten Anweisungen genau abgleicht. Diese Funktion ermöglicht es neuen Plugin-Entwicklern, Anweisungen schnell abzugleichen. Die beabsichtigte Verwendung besteht darin, eine Anweisung zu finden, die derjenigen ähnelt, die Sie abgleichen möchten, eine Matcher-Funktion zu generieren und dann die generierte Funktion zu ändern, um Ihre Anforderungen besser zu unterstützen.
Ein Beispiel wäre der Versuch, alle MediumLevelILSSA MLIL_CALL_SSA-Anweisungen zu finden, die drei Parameter benötigen. Ich habe einen Matcher für eine unabhängige Funktion mit 0 Parametern generiert:
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
Wir können dies ändern, um einige spezifische Einschränkungen zu entfernen:
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
Wir haben das Aufrufziel und die Einschränkungen bei der Speicherversionierung entfernt. Aktualisieren Sie als Nächstes die Parameterprüfung, um nach drei Parametern zu suchen:
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
Jetzt haben wir einen Matcher, der MLIL_CALL_SSA-Anweisungen mit 3 Parametern identifiziert! Nun iterieren Sie über die MLIL-SSA-Anweisungen und rufen den Matcher auf, und schon sind wir fertig:
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 )
Beispiel-Matcher:
Dieses Projekt unterliegt dem Urheberrecht von Ryan Stortz (@withzombies) und ist unter der Apache 2.0-LIZENZ verfügbar.