Un complemento de BinaryNinja para graficar un árbol de instrucciones BNIL y comparadores de instrucciones de Python de metaprograma.
La instalación se admite de dos formas: la primera mediante el nuevo administrador de complementos y la segunda mediante instalación manual.
Utilice el nuevo administrador de complementos seleccionando "Administrar complementos" en el menú "Editar". Busque en la lista de complementos "BNIL Institution Graph", haga clic derecho sobre él y haga clic en "Instalar", luego haga clic derecho nuevamente y seleccione "Activar".
$ git clone https://github.com/withzombies/bnil-graph.git
$ cd ~/Library/Application Support/Binary Ninja/plugins
$ ln -s ~/git/bnil-graph .
Para usar bnil-graph, haga clic derecho en una instrucción y seleccione "Gráfico de instrucciones BNIL". Esto grafica las instrucciones BNIL asociadas con esa dirección y las muestra como un formulario HTML.
Binary Ninja agrega dinámicamente accesores de operandos, debido a esto, los accesos convenientes no aparecen en las llamadas dir()
ni en la documentación de la API. bnil-graph muestra la estructura de la instrucción IL, incluidos sus bonitos nombres de acceso (como insn.src
para el registro de origen o la memoria)
Gráfico de ejemplo:
Además del complemento gráfico, bnil-graph también generará una función de comparación que coincidirá exactamente con las instrucciones seleccionadas. Esta característica permitirá a los nuevos desarrolladores de complementos combinar rápidamente las instrucciones. El uso previsto es encontrar una instrucción similar a la que desea comparar, generar una función de comparación y luego modificar la función generada para satisfacer mejor sus necesidades.
Un ejemplo sería intentar encontrar todas las instrucciones MediumLevelILSSA MLIL_CALL_SSA que toman 3 parámetros. Generé un comparador contra una función no relacionada con 0 parámetros:
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
Podemos modificar esto para eliminar algunas restricciones específicas:
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
Eliminamos el destino de la llamada y las restricciones de versiones de memoria. A continuación, actualice la verificación de parámetros para verificar 3 parámetros:
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
¡Ahora tenemos un comparador que identificará las instrucciones MLIL_CALL_SSA con 3 parámetros! Ahora repita las instrucciones de MLIL SSA, llame al comparador y listo:
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 )
Comparador de ejemplo:
Este proyecto tiene derechos de autor de Ryan Stortz (@withzombies) y está disponible bajo la LICENCIA Apache 2.0.