Avanzadoensambladorida-proreverse-engineeringmalwareherramientas

IDA Pro: Analisis Avanzado de Ensamblador

Guia avanzada de IDA Pro para analisis de malware. Navegacion de vistas, grafo de funciones, scripts IDAPython, FLIRT signatures, plugins esenciales y tecnicas para desensamblado complejo.

MalwareIntel Research··9 min lectura
Serie: Lenguaje Ensamblador — Parte 11

IDA Pro en el ecosistema de analisis

IDA Pro (Interactive Disassembler Professional) lleva mas de tres decadas siendo la herramienta de referencia para ingenieria inversa. Donde Ghidra democratizo el acceso al RE, IDA mantiene su posicion en equipos profesionales de threat intelligence por su madurez, ecosistema de plugins y la calidad de Hex-Rays decompiler.

Este articulo asume familiaridad con conceptos de desensamblado (cubiertos en el articulo de Ghidra) y se centra en las capacidades avanzadas que IDA ofrece para analisis de malware.

Vistas y navegacion

IDA View (desensamblado)

La vista principal tiene dos modos:

Text view: lista lineal de instrucciones, similar al Listing de Ghidra. Muestra direcciones, bytes, instrucciones y comentarios automaticos.

Graph view: muestra la funcion actual como grafo de bloques basicos. Cada bloque es un nodo con instrucciones. Las flechas verdes indican salto tomado (condicion verdadera), las rojas no tomado. Pulsa Space para alternar entre ambos modos.

La vista de grafo de IDA es notablemente mas rapida que la de Ghidra en funciones grandes (miles de instrucciones). Para malware ofuscado con grafos enormes, esta diferencia importa.

Hex View

Muestra los bytes crudos del binario. Sincronizada con IDA View: al navegar en una vista, la otra se actualiza. Util para ver datos que no se desensamblan (configuraciones cifradas, shellcode embebido).

Pseudocode (Hex-Rays)

El decompilador Hex-Rays (licencia separada) produce pseudo-C de alta calidad. Comparado con el decompilador de Ghidra, Hex-Rays generalmente:

  • Maneja mejor las optimizaciones del compilador
  • Reconstruye estructuras con mas precision
  • Produce codigo mas legible para funciones complejas
  • Soporta mejor C++ con vtables

Atajo: F5 para decompila la funcion actual.

Proximiy View y Function Calls

Proximity View: grafo de relaciones entre funciones y datos. Muestra como se conectan funciones, variables globales y strings. Util para tener una vision de alto nivel del malware.

Function Calls: View, Open Subviews, Function Calls. Muestra el arbol completo de llamadas de la funcion seleccionada, con profundidad configurable.

FLIRT Signatures: separar libreria de malware

El problema

Cuando el malware enlaza librerias estaticamente (OpenSSL, zlib, CRT, Boost), el binario contiene miles de funciones de libreria junto con el codigo malicioso. Sin firmas, todo aparece como funciones sin nombre: sub_401000, sub_401050, sub_401100...

La solucion

FLIRT (Fast Library Identification and Recognition Technology) aplica firmas que identifican funciones de libreria conocidas. Tras aplicar las firmas adecuadas:

sub_401000 → _malloc
sub_401050 → _free
sub_401100 → _memcpy
sub_401200 → SSL_CTX_new
sub_401350 → SSL_connect

Ahora puedes ignorar todas las funciones de libreria y concentrarte en las que IDA no reconocio: esas son el codigo del malware.

Aplicar firmas

  1. File, Load File, FLIRT Signature File
  2. Seleccionar la firma apropiada (vc32rtf para Visual C++ runtime, libssl para OpenSSL)
  3. IDA aplica las firmas y renombra las funciones identificadas

Crear firmas propias

Si analizas variantes de la misma familia de malware repetidamente, puedes crear firmas FLIRT propias:

# Extraer patrones de un .obj o .lib
pelf libreria.lib output.pat

# Compilar patrones en firma FLIRT
sigmake output.pat output.sig

Esto es especialmente util para familias como Cobalt Strike, donde el beacon tiene funciones internas reconocibles entre versiones.

IDAPython: automatizacion del analisis

IDAPython da acceso completo a la API de IDA desde Python. Para analisis de malware, los scripts mas productivos automatizan tareas que de otra forma consumirian horas.

Acceso basico a la base de datos

import idaapi
import idautils
import idc

# Obtener la direccion actual del cursor
ea = idc.get_screen_ea()
print(f"Direccion actual: 0x{ea:08X}")

# Leer bytes en una direccion
byte_val = idc.get_wide_byte(0x00401000)
dword_val = idc.get_wide_dword(0x00401000)

# Obtener el nombre de una funcion
func_name = idc.get_func_name(ea)

# Listar todas las funciones
for func_ea in idautils.Functions():
    name = idc.get_func_name(func_ea)
    size = idc.get_func_attr(func_ea, idc.FUNCATTR_END) - func_ea
    print(f"0x{func_ea:08X}: {name} ({size} bytes)")

Script: resolver imports por hash

El malware frecuentemente resuelve APIs calculando un hash del nombre de la funcion (CRC32, DJB2, ROR13) en lugar de importarlas directamente. IDAPython puede resolver estos hashes:

import idc
import idautils

# Diccionario de hashes ROR13 pre-calculados
api_hashes = dict(
    CreateProcessA=0x16B3FE72,
    VirtualAlloc=0x91AFCA54,
    LoadLibraryA=0x0726774C,
    GetProcAddress=0x7802F749,
    WriteProcessMemory=0xE7BDD8C5,
    CreateRemoteThread=0x72BD9CDD,
)

# Invertir: hash -> nombre
hash_to_name = dict()
for name, h in api_hashes.items():
    hash_to_name[h] = name

# Buscar patrones de PUSH imm32 seguido de CALL funcion_resolver
for func_ea in idautils.Functions():
    for head in idautils.Heads(func_ea, idc.get_func_attr(func_ea, idc.FUNCATTR_END)):
        if idc.print_insn_mnem(head) == "push":
            operand = idc.get_operand_value(head, 0)
            if operand in hash_to_name:
                api_name = hash_to_name[operand]
                idc.set_cmt(head, f"API Hash -> {api_name}", 0)
                print(f"0x{head:08X}: Hash 0x{operand:08X} -> {api_name}")

Script: extraer configuracion cifrada con XOR

import idc

def xor_decrypt(addr, size, key):
    """Descifra datos XOR en la direccion dada."""
    result = bytearray()
    for i in range(size):
        byte_val = idc.get_wide_byte(addr + i)
        if isinstance(key, int):
            decrypted = byte_val ^ key
        else:
            decrypted = byte_val ^ key[i % len(key)]
        result.append(decrypted)
    return result

# Ejemplo: descifrar un bloque de configuracion
config_addr = 0x00403000
config_size = 256
xor_key = 0x5A

decrypted = xor_decrypt(config_addr, config_size, xor_key)
print(f"Config descifrada: {decrypted}")

# Parchear en IDA para ver el texto claro
for i, byte_val in enumerate(decrypted):
    idc.patch_byte(config_addr + i, byte_val)

# Forzar re-analisis de la zona parcheada
idc.create_strlit(config_addr, config_addr + config_size)

Script: renombrar funciones en masa por patron

import idc
import idautils

# Renombrar funciones que solo llaman a una API conocida (wrappers)
for func_ea in idautils.Functions():
    func_name = idc.get_func_name(func_ea)
    if not func_name.startswith("sub_"):
        continue

    # Contar instrucciones en la funcion
    func_end = idc.get_func_attr(func_ea, idc.FUNCATTR_END)
    instructions = list(idautils.Heads(func_ea, func_end))

    # Funciones muy cortas (wrapper de una API)
    if len(instructions) > 5:
        continue

    # Buscar la unica CALL en la funcion
    for head in instructions:
        if idc.print_insn_mnem(head) == "call":
            target = idc.get_operand_value(head, 0)
            target_name = idc.get_func_name(target)
            if target_name and not target_name.startswith("sub_"):
                new_name = f"wrap_{target_name}"
                idc.set_name(func_ea, new_name, idc.SN_NOWARN)
                print(f"Renamed {func_name} -> {new_name}")

Plugins esenciales para analisis de malware

Plugins de analisis

BinDiff: comparacion de binarios. Compara dos versiones de malware para identificar cambios entre variantes. Integrado en IDA como plugin.

Capa (Mandiant): identifica capacidades del malware automaticamente. Analiza el binario y reporta: "This program can create a service", "This program can inject into another process". Basado en reglas que mapean combinaciones de APIs y patrones de codigo a capacidades.

FindCrypt: identifica algoritmos criptograficos por constantes conocidas. Detecta AES (S-box), RC4, MD5, SHA1, SHA256, DES, Blowfish y otros por sus tablas de constantes embebidas.

YARA IDA Plugin: ejecuta reglas YARA directamente sobre el binario cargado en IDA. Util para verificar si una muestra coincide con firmas conocidas de familias de malware.

Plugins de depuracion

x64dbg integration: sincroniza IDA con x64dbg para analisis dinamico. Los breakpoints y comentarios se comparten entre ambas herramientas.

Lighthouse: cobertura de codigo. Importa trazas de cobertura de ejecucion (de un sandbox o debugger) y las visualiza en IDA, coloreando las instrucciones ejecutadas. Esto muestra exactamente que codigo se ejecuto en una ejecucion particular del malware.

Plugins de decompilacion

HexRaysPyTools: mejora la experiencia con Hex-Rays. Reconstruccion automatica de estructuras, propagacion de tipos, renombrado inteligente.

Lucid: mejora la legibilidad del pseudo-C de Hex-Rays con formateo, coloreado de sintaxis mejorado y anotaciones.

Tecnicas avanzadas

Parcheo de binarios (patching)

IDA permite parchear bytes directamente. Util para:

  • Evadir checks anti-analisis: NOP (0x90) sobre instrucciones de deteccion de debugger.
  • Forzar rutas de ejecucion: cambiar un JZ por JNZ (74 a 75) para tomar la rama opuesta.
  • Descifrar datos in-place: aplicar XOR sobre bloques cifrados.
Edit -> Patch program -> Change byte...
Edit -> Patch program -> Apply patches to input file

Precaucion: siempre trabaja sobre una copia del binario. Nunca parches la muestra original.

Segments y bases de carga

El malware a veces carga modulos adicionales en memoria. Para analizarlos en IDA:

  1. Extraer el modulo en memoria (desde un dump de proceso).
  2. File, Load File, Additional Binary File.
  3. Especificar la base de carga correcta.
  4. IDA analiza el nuevo segmento manteniendo las referencias cruzadas con el binario principal.

Snapshots

IDA permite guardar snapshots del estado de la base de datos. Antes de hacer cambios destructivos (parcheo masivo, re-analisis), guarda un snapshot:

File, Take Database Snapshot.

Debugging integrado

IDA incluye un debugger que puede ejecutar el binario directamente. Para malware, esto es peligroso y debe hacerse en una VM aislada. El debugger de IDA permite:

  • Breakpoints condicionales con expresiones IDAPython
  • Tracing de ejecucion (trace over/into)
  • Watchpoints en memoria (alertar cuando se lee/escribe una direccion)
  • Scripting en tiempo de ejecucion
# Breakpoint condicional: parar cuando EAX contenga un valor especifico
def bp_condition():
    eax = idc.get_reg_value("eax")
    if eax == 0x12345678:
        print(f"Target value found at 0x{idc.get_reg_value('eip'):08X}")
        return True
    return False

Comparacion IDA Pro vs Ghidra para malware

AspectoIDA ProGhidra
CosteLicencia comercial (miles de EUR)Gratuito (NSA)
DecompiladorHex-Rays (excelente, licencia extra)Integrado (bueno)
VelocidadRapido en binarios grandesMas lento en grafos grandes
FLIRTMaduro, miles de firmasLimitado
PluginsEcosistema enorme (30 anos)Creciendo rapidamente
ScriptingIDAPython (completo)GhidraScript Java/Python
ColaboracionIDB compartibleGhidra Server (multiusuario)
ARM/MIPSExcelenteExcelente
SoporteComercial de Hex-RaysComunidad

Para un equipo profesional de malware analysis, IDA Pro sigue justificando su coste por productividad. Para analistas individuales o equipos con presupuesto limitado, Ghidra cubre el 90% de las necesidades.

Flujo de trabajo IDA para malisis de malware

Primer analisis (triage)

  1. Abrir binario, aceptar opciones por defecto.
  2. Esperar a que termine el auto-analisis.
  3. Aplicar FLIRT signatures (File, Load File, FLIRT Signature).
  4. Revisar Imports (View, Open Subviews, Imports).
  5. Revisar Strings (View, Open Subviews, Strings).
  6. Ejecutar Capa si esta instalado: capa -f malware.exe.
  7. Ejecutar FindCrypt para detectar criptografia.

Analisis profundo

  1. Navegar a funciones con APIs sospechosas (xrefs desde imports).
  2. F5 para decompila. Leer pseudo-C.
  3. Renombrar todo lo identificable (N para funciones, variables en decompilador).
  4. Aplicar tipos de datos y estructuras.
  5. Documentar con comentarios (;) y bookmarks.
  6. Si hay cifrado: identificar algoritmo, escribir script IDAPython para descifrar.

Documentacion y IOCs

  1. Exportar la base de datos IDA (archivo .idb/.i64) con todas las anotaciones.
  2. Generar lista de IOCs: strings descifrados, URLs de C2, mutex, registry keys.
  3. Mapear TTPs a MITRE ATT&CK basandote en las APIs y comportamientos identificados.

IDA Pro no es solo una herramienta. Es un entorno de analisis completo que, combinado con IDAPython y su ecosistema de plugins, permite automatizar y escalar el analisis de malware a nivel profesional.

En el siguiente articulo profundizamos en el cifrado que encontraras en malware real: XOR, RC4, AES y como detectarlos e identificarlos en ensamblador.

Preguntas frecuentes

Artículos relacionados

Este contenido tiene fines exclusivamente educativos y de investigación en ciberseguridad defensiva. No se proporcionan binarios maliciosos ni payloads ejecutables. El uso indebido de esta información es responsabilidad exclusiva del usuario. Leer disclaimer completo.