
Plugin de IDA Pro para filtrar funciones por patrones de ensamblador, secuencias de bytes, referencias a cadenas/nombres y restricciones de tamaño, con búsqueda basada en reglas y copia binaria avanzada.
FindFunc es un plugin de IDA Pro para encontrar funciones de código que contienen un cierto patrón de ensamblador o bytes, referencian un cierto nombre o cadena, o cumplen con varias otras restricciones.
FindFunc obtuvo el tercer lugar en el Concurso de Plugins de IDA Pro de HexRays 2022!

La funcionalidad principal de FindFunc es permitir al usuario especificar un conjunto de 'Reglas' o restricciones que una función de código en IDA Pro debe cumplir. FF entonces encontrará y listará todas las funciones que cumplan TODAS las reglas (por lo que actualmente todas las Reglas están en una conjunción AND). Excepción: las Reglas pueden ser 'invertidas' para ser coincidencias negativas. Dichas reglas se ajustan a 'AND NOT'.
FF programará las reglas en un orden inteligente para minimizar el tiempo de procesamiento. Resumen de características:
El botón 'Find Functions' (Buscar funciones) borra los resultados existentes e inicia una búsqueda nueva, 'Refine Results' (Refinar resultados) considera solo los resultados de la búsqueda anterior.
Una característica secundaria de FF es la opción de copiar la representación binaria de instrucciones con las siguientes opciones:
Consulte la sección 'copia avanzada' a continuación para más detalles. ¡Esta característica complementa muy bien la regla de Patrón de Bytes!
FindFunc es un plugin de Python para IDA Pro sin dependencias de paquetes externos. Se puede instalar descargando el repositorio y copiando el archivo 'findfuncmain.py' y la carpeta 'findfunc' a su directorio de plugins de IDA Pro. Para IDA 9.0+, el repositorio también se puede clonar directamente en el directorio de plugins. De cualquier manera, no se requiere compilación.
Requisitos: IDA Pro 8.x (8.3+) con entorno python3. FindFunc está diseñado solo para arquitectura x86/x64. Ha sido probado con IDA 8.3 - 9.2, python 3.11 en Windows 10 + 11
Actualmente, las siguientes seis reglas están disponibles. Están ordenadas de pesada a ligera en cuanto a impacto en el rendimiento. Con bases de datos grandes, es buena idea reducir primero las funciones candidatas con una regla barata, antes de realizar coincidencias pesadas mediante, por ejemplo, Reglas de Código. FF programará las reglas automáticamente de manera inteligente.
Regla para filtrar funciones basándose en que contengan un fragmento de código ensamblador dado. Esto NO es una búsqueda de texto de la representación textual de desensamblado de IDA, sino que realiza una coincidencia avanzada de la instrucción subyacente. El fragmento puede contener muchas instrucciones consecutivas, una por línea. Se soportan fragmentos de función. Soporta coincidencia con comodines especiales, además del ensamblador literal:
más ejemplos:
mov r64, [r32 * 8 + 0x100]
mov r, [r * 8 - 0x100]
mov r64, [r32 * 8 + imm]
pass
mov r, word [eax + r32 * 8 - 0x100]
any r64, r64
push imm
push any
Precauciones: Tenga cuidado al copiar ensamblador desde IDA. IDA mezcla nombres de variables locales y otra información en la instrucción, lo que lleva a fallos de coincidencia. Además, las etiquetas no son compatibles ("call sub_123456").
Tenga en cuenta que los Patrones de Código son la Regla más costosa, y si solo hay Reglas de Código presentes, FF no tiene más opción que desensamblar toda la base de datos. Esto puede llevar hasta varios minutos para binarios muy grandes. Consulte las notas sobre rendimiento más abajo.
La función debe contener el inmediato dado al menos una vez en cualquier posición. Un valor inmediato es un valor fijo en la representación binaria de la instrucción. Ejemplos de instrucciones que coinciden con el valor inmediato 0x100:
mov eax, 0x100
mov eax, [0x100]
and al, [eax + ebx*8 + 0x100]
push 0x100
Los inmediatos se pueden pegar directamente desde el portapapeles en la lista de reglas. Nota: IDA realiza una coincidencia exhaustiva de cualquier tamaño y cualquier posición del inmediato. Si sabe que es de un ancho específico de 4 u 8 bytes, un patrón de bytes puede ser más rápido (pero puede producir falsos positivos).
La función debe contener el patrón de bytes dado al menos una vez. El patrón tiene el mismo formato que la búsqueda binaria de IDA y, por lo tanto, admite comodines: ¡la combinación perfecta para la función de copia avanzada!
Ejemplos:
11 22 33 44 aa bb cc
11 22 33 ?? ?? bb cc -> ?? puede ser cualquier byte
Los patrones de bytes se pueden pegar directamente desde el portapapeles en la lista de reglas. Nota: La coincidencia de patrones es bastante rápida y una buena opción para reducir rápidamente las coincidencias.
La función debe referenciar la cadena dada al menos una vez. La cadena se compara según el módulo 'fnmatch' de Python y, por lo tanto, admite coincidencias tipo comodín. La comparación se realiza sin distinción de mayúsculas y minúsculas. Se consideran cadenas de los siguientes formatos: [idaapi.STRTYPE_C, idaapi.STRTYPE_C_16] (esto se puede cambiar en la clase Config).
Ejemplos:
Nota: La coincidencia de cadenas es rápida y una buena opción para reducir rápidamente los candidatos.
La función debe referenciar el nombre/etiqueta dado al menos una vez. El nombre/etiqueta se compara según el módulo 'fnmatch' de Python y, por lo tanto, admite coincidencias tipo comodín. La comparación se realiza sin distinción de mayúsculas y minúsculas.
Ejemplos:
Nota: La coincidencia de nombres es muy rápida e ideal para reducir rápidamente los candidatos.
El tamaño de la función debe estar dentro del límite dado: "min <= tamaño_funcion <= max". Los datos se ingresan como una cadena de la forma "min,max". El tamaño de una función incluye todos sus fragmentos.
Nota: La coincidencia por tamaño de función es muy rápida e ideal para reducir rápidamente los candidatos.
Para facilitar su uso, FF se puede utilizar mediante los siguientes atajos de teclado:
Uso adicional de la GUI
Frecuentemente queremos buscar patrones binarios de ensamblador, pero sin direcciones y valores codificados (inmediatos), o incluso solo los opcodes reales de la instrucción. FindFunc facilita esto agregando tres opciones de copia al menú emergente de desensamblado:
Copia todos los bytes de la instrucción como cadena hexadecimal al portapapeles, para usar en una Regla de Patrón de Bytes (o en la búsqueda binaria de IDA).
B8 44332211 mov eax,11223344
68 00000001 push 1000000
66:894424 70 mov word ptr ss:[esp+70],ax
se copiará como
b8 44 33 22 11 68 00 00 00 01 66 89 44 24 70
Copia los bytes de la instrucción para la instrucción dada, enmascarando cualquier valor inmediato. Ejemplo:
B8 44332211 mov eax,11223344
68 00000001 push 1000000
66:894424 70 mov word ptr ss:[esp+70],ax
se copiará como
b8 ?? ?? ?? ?? 68 ?? ?? ?? ?? 66 89 44 24 ??
Copia todos los bytes de la instrucción como cadena hexadecimal al portapapeles, enmascarando cualquier byte que no sea el opcode real (incluyendo sib, modrm, pero manteniendo los prefijos heredados).
B8 44332211 mov eax,11223344
68 00000001 push 1000000
66:894424 70 mov word ptr ss:[esp+70],ax
se copiará como
b8 ?? ?? ?? ?? 68 ?? ?? ?? ?? 66 89 ?? ?? ??
Una combinación que mantiene el opcode y los inmediatos, pero enmascara, por ejemplo, mod r/m. Note que esto mantiene los opcodes incluso si mandan registros específicos, por ejemplo
B8 44332211 mov eax,11223344
mantendrá el opcode B8.
Nota: Esto es un 'mejor esfuerzo' usando la API de IDA, por lo que puede haber algunos casos en los que solo funcione parcialmente. Para una solución 100% correcta necesitaríamos incluir una biblioteca de desensamblado x86 dedicada.
Se pueden lograr resultados similares con Reglas de Patrón de Código, pero esto puede ser más rápido, tanto para la interacción del usuario como para la búsqueda real.
Copia el desensamblado seleccionado al portapapeles, tal como aparece en IDA.
Un breve comentario sobre el rendimiento: