
Plugins y scripts de IDA para analizar el marco de uso de registros

"""
¿Para qué se usa este registro?
Mmm.. Mejor lo renombro a nombre_muy_único, hago una búsqueda textual y encuentro todas las referencias.
Ok.. Esperando a que termine la búsqueda.. ya casi.. ¡Hecho!
Ahora solo necesito entender cuál de los resultados de búsqueda es relevante para el marco de uso actual del registro.
No debería ser tan difícil, ¿verdad?
"""
Si esto te ha pasado (quizás más de una vez), ¡te espera una sorpresa!
¡Solo presiona Shift-X y tus problemas desaparecerán!
También puedes renombrar (o re(g)istrar) el registro en el marco de uso. ¡Solo presiona Shift-N y sigue las instrucciones!
Además, en lugar de cambiar los tipos de todos los usos a un tipo determinado, presiona Shift-T una sola vez.
Y por último, pero no menos importante, si deseas establecer un desplazamiento (como hacer Ctrl-R) para todos los usos de este registro, solo presiona Shift-R.
Nota: A veces ya hay otro plugin que usa Shift-T. Elimina ese plugin, de todas formas nunca lo usaste antes :-).
Este plugin usa sark para interactuar con los scripts de IDA de manera cómoda, y cachetools para almacenar en caché el escaneo del marco, lo que lo hace mucho más rápido.
Oregami es compatible tanto con IDA 7.x/8.x como con IDA 9.0+.
Si estás usando IDA 9, asegúrate de tener una versión actualizada de sark que sea compatible con IDA 9.
Nota: IDA 9 introdujo su propia funcionalidad Shift-X. Si necesitas usar el Shift-X integrado de IDA en lugar del de oregami, debes cambiar el acceso directo de oregami en el archivo del plugin.
[Para python3]
pip3 install sark
[Para python2]
Si usas la variante python2 de IDA, debes ejecutar en su lugar:
pip2 install -U git+https://github.com/tmr232/[email protected]#egg=Sark
Ten en cuenta que python2 no tiene soporte activo (ya que IDA se ha movido mayoritariamente a python3, y yo también), por lo que esto puede no funcionar.
git clone https://github.com/shemesh999/oregami
El código base de sark ofrece muchos plugins. Uno de ellos es: https://github.com/tmr232/Sark/blob/master/plugins/plugin_loader.py
Recomendamos copiarlo a tu directorio de plugins y luego ejecutar IDA una vez con privilegios de administrador (para que pueda crear los archivos plugins.list).
Después de hacer esto, puedes agregar nuevos plugins añadiendo la ruta a ellos en uno de los archivos plugins.list creados (por ejemplo, se crea uno en la carpeta cfg de IDA).
Ahora, agrega a uno de los archivos plugins.list:
RUTACOMPLETA\oregami\oregami_plugin.py
RUTACOMPLETA\oregami\regname_plugin.py
RUTACOMPLETA\oregami\typeregter_plugin.py
RUTACOMPLETA\oregami\offreg_plugin.py
Reinicia IDA y los plugins deberían funcionar.
Alternativamente:
Copia todos los archivos (incluyendo la carpeta interna oregami, excluyendo setup.py) al directorio de plugins de IDA.
Además de usarse como plugins, ¡oregami también se puede usar para escribir tus propios scripts!
Para ello, primero debes instalar usando el archivo setup.py incluido. Es decir, debes ejecutar:
'python setup.py develop', y a partir de entonces puedes usar las clases y funciones internas.
Ten en cuenta que recomendamos usar 'develop' y no 'install', para que si descargas una nueva versión de oregami, funcione sin problemas.
Por ejemplo:
-- script.py --
def find_func_usage(func_ea, reg='r0'):
"""
Encuentra e imprime todos los usos de un registro, incluyendo la información de los operandos específicos
en los que se encuentra y qué operación realiza en el operando.
"""
import oregami
rf = oregami.RegFrame(func_ea, reg)
for insn in rf.get_instructions():
print('Addr:{:x}'.format(insn.ea))
for opnd in insn.operands:
if opnd.uf_is_external:
continue
print('--opnd_idx:{} - {}'.format(opnd.n, oregami.UsageBits(opnd.op_flags)))
Supongamos la siguiente secuencia de opcodes:
ROM:01000010 e_lis r10, 0x4004 # 0x40040000 # Carga Inmediata Desplazada
ROM:01000014 e_add16i r10, r10, 0x1337 # 0x40041337 # Suma Inmediata
ROM:01000020 se_mr r30, r31 # Mover Registro
ROM:01000022 cmplw r11, r10 # Comparar Lógica Word
ROM:01000026 se_bge loc_1000036 # Saltar si mayor o igual
ROM:01000028
ROM:01000028 loc_1000028: # CODE XREF: sub_0100000+144↓j
ROM:01000028 e_stmw r30, 0(r11) # Almacenar Múltiples Words
ROM:0100002C e_add16i r11, r11, 8 # Suma Inmediata
ROM:01000030 cmplw r11, r10 # Comparar Lógica Word
ROM:01000034 se_blt loc_1000028 # Saltar si menor que
ROM:01000036
ROM:01000036 loc_1000036: # CODE XREF: sub_0100000+136↑j
ROM:01000036 e_add16i r10, r10, 8 # Suma Inmediata
ROM:0100003A e_li r11, 0 # Carga Inmediata
Si escaneamos el marco de uso del registro r10, comenzando desde la dirección 01000022, encontraremos tres tipos de usos incluidos en el marco de uso.
Esto incluirá las instrucciones que inicializan el valor del registro.
Podemos querer incluir solo la última instrucción que cambió el valor del registro (dirección 01000014 en el ejemplo), o una secuencia de operaciones utilizadas para establecer el valor inicial del registro (direcciones 01000010 y 01000014 en el ejemplo).
La secuencia de operaciones utilizada en la inicialización del registro puede denominarse "etapa de inicialización".
Puedes optar por admitir una etapa de inicialización o no, dependiendo del parámetro init_stage_bool en la inicialización de RegFrame.
Esto incluirá las instrucciones que utilizan el valor del registro y no lo modifican de ninguna manera. Estas corresponden a las líneas 01000022 y 01000030 en el ejemplo.
Esto incluirá las instrucciones que utilizan el valor del registro pero luego cambian su valor. Estas instrucciones pueden considerarse incluidas en dos marcos de uso distintos: el que conduce a ellas y el que se origina a partir de ellas.
Esto corresponde a la línea 01000036.
Al escanear el registro de uso, al llegar a una operación de inicialización o una operación de ruptura, dejaremos de escanear en una dirección determinada.
Pero también podemos detener el escaneo debido a instrucciones fuera del marco de uso.
Por ejemplo, escanear el marco de uso del registro r11 desde la dirección 01000030 se detendrá en la línea 0100003A.
Esta es la clase básica utilizada en oregami. Al inicializarla en una dirección y un registro específico, escaneará el marco de uso del registro y creará un UFIntruction para todas las instrucciones relevantes.
get_instruction - obtiene la instrucción de la dirección dada
get_instructions - un generador que devuelve las instrucciones en el marco de uso.