compilación de prueba de Windows
Compilación de prueba de Linux
Drltrace es un rastreador de llamadas API dinámico para aplicaciones de Windows y Linux. Drltrace está construido sobre el marco de instrumentación binaria dinámica DynamoRIO. Drltrace fue implementado inicialmente por Derek Bruening y distribuido con los marcos DynamoRIO y DrMemory. Este repositorio contiene una versión independiente de drltrace con scripts y materiales adicionales sobre cómo usarlo para el análisis de malware. La versión de lanzamiento se puede descargar aquí.
El uso de drltrace es muy sencillo. Un usuario debe especificar un directorio de registro y un nombre de un proceso de destino de la siguiente manera:
drltrace -logdir . -- calc.exe
Eso es todo, la herramienta inyectará las DLL necesarias en el proceso de destino, iniciará la instrumentación y, en paralelo, registrará información sobre todas las llamadas a la biblioteca que se ejecutan en el proceso de destino:
~~43600~~ msvcrt.dll!__wgetmainargs
arg 0: 0x010d2364
arg 1: 0x010d2368
and return to module id:0, offset:0x193a
~~43600~~ ntdll.dll!EtwEventRegister
arg 0: 0x002ff994
arg 1: 0x010d1490
and return to module id:0, offset:0x157e
~~43600~~ ntdll.dll!EtwEventSetInformation
arg 0: 0x007b4b40
arg 1: 0x00000033
and return to module id:0, offset:0x15a1
~~43600~~ SHELL32.dll!ShellExecuteW
arg 0: <null> (type=<unknown>, size=0x0)
arg 1: <null> (type=wchar_t*, size=0x0)
arg 2: calculator:// (type=wchar_t*, size=0x0)
arg 3: <null> (type=wchar_t*, size=0x0)
arg 4: <null> (type=wchar_t*, size=0x0)
arg 5: 0x1 (type=int, size=0x4)
and return to module id:0, offset:0x167d
El formato de la salida es simple y puede analizarse fácilmente mediante un script externo:
~~[thread id]~~ [dll name]![api call name]
arg [arg #]: [value] (type=[Windows type name], size=[size of arg])
and return to module id:[module unique id], offset:[offset in memory]
El análisis con grep
se puede realizar cuando se utiliza el argumento -grepable
; esto imprime los nombres de las funciones y los argumentos, todos en una línea:
~~4824~~ KERNELBASE.dll!CreateFileW {0: C:WindowsFontsstaticcache.dat (type=wchar_t*, size=0x0)} {1: 0x80000000 (type=DWORD, size=0x4)} {2: 0x3 (type=DWORD, size=0x4)} {3: 0x005cde8c (type=<unknown>*, size=0x0)} {4: 0x3 (type=DWORD, size=0x4)} {5: 0x80 (type=DWORD, size=0x4)}
La tabla de identificadores únicos del módulo se imprime al final del archivo de registro:
Module Table: version 3, count 70
Columns: id, containing_id, start, end, entry, checksum, timestamp, path
0, 0, 0x010d0000, 0x010da000, 0x010d1b80, 0x0000f752, 0xb5fe3575, C:WindowsSysWOW64calc.exe
1, 1, 0x6d4c0000, 0x6d621000, 0x6d563940, 0x00136d65, 0x59ce1b0b, C:UsersMaxDownloadsdrltracedrltracedynamoriolib32releasedynamorio.dll
2, 2, 0x73800000, 0x73975000, 0x7380dbf7, 0x00000000, 0x59ce1b0f, C:UsersMaxDownloadsdrltracedrltracebinrelease/drltracelib.dll
3, 3, 0x742f0000, 0x742fa000, 0x742f2a00, 0x0000c877, 0x0adc52c1, C:WindowsSystem32CRYPTBASE.dll
4, 4, 0x74300000, 0x74320000, 0x7430c9b0, 0x0002c617, 0x245970b4, C:WindowsSystem32SspiCli.dll
5, 5, 0x74410000, 0x74431000, 0x74416900, 0x0002a940, 0x88a53c1d, C:WindowsSystem32GDI32.dll
6, 6, 0x74440000, 0x74500000, 0x7446fb20, 0x000cc410, 0xd343d532, C:WindowsSystem32RPCRT4.dll
7, 7, 0x74500000, 0x74525000, 0x745047d0, 0x00026737, 0xa39c8991, C:WindowsSystem32IMM32.DLL
8, 8, 0x74550000, 0x745c7000, 0x7456e8a0, 0x00081857, 0x73b971e1, C:WindowsSystem32advapi32.dll
9, 9, 0x748f0000, 0x74929000, 0x748febd0, 0x00045303, 0xa58be652, C:WindowsSystem32cfgmgr32.dll
10, 10, 0x74930000, 0x75c78000, 0x74aa09d0, 0x01377aa6, 0x4b39926b, C:WindowsSystem32SHELL32.dll
Drltrace puede filtrar fácilmente las llamadas entre bibliotecas e imprimir solo las llamadas API realizadas desde el módulo principal (o desde un montón) de una aplicación de destino especificando la opción -only_from_app
, que es muy útil en el caso de aplicaciones que generan registros enormes. Para un control más granular, la opción -filter
permite al usuario especificar un archivo de configuración de filtro para filtrar funciones específicas de la lista blanca o ignorar funciones de la lista negra (consulte el archivo filter.config para ver ejemplos). Drltrace también tiene varios scripts externos útiles para filtrar llamadas API para determinadas bibliotecas e imprimir solo cadenas y llamadas API potencialmente interesantes.
Los módulos principales de Drltrace se distribuyen bajo BSD.
Algunos archivos necesarios para drltrace se distribuyen bajo LGPL. Consulte los archivos fuente para obtener más detalles.
El análisis de malware no es una tarea fácil. Los empaquetadores de software sofisticados como Themida y Armadillo y, por supuesto, docenas de empaquetadores anónimos escritos por autores de malware, además de cifrado de código y datos, facilitan significativamente (en algunos casos haciéndolo completamente imposible) la ingeniería inversa estática de dichas muestras, lo que complica la vida de los analistas de malware. En tal caso, el seguimiento de llamadas API puede reducir significativamente la cantidad de tiempo necesario para comprender una intención maliciosa real y revelar muchos detalles técnicos sobre el código malicioso protegido.
Si bien la técnica tradicional de enlace de API se implementó con éxito en varias soluciones, los autores de malware han estudiado bien el enfoque y puede detectarse y/o eludirse fácilmente. Además, estas herramientas se distribuyen como aplicaciones GUI independientes y pesadas (como productos propietarios) que a menudo no son fáciles de integrar en el flujo de trabajo de análisis de malware existente.
Si miramos el mundo de Linux, hay una herramienta maravillosa llamada ltrace. Usando un solo comando bash, podemos obtener fácilmente el seguimiento completo de las llamadas API de un determinado ejecutable.
¿Por qué no tenemos una herramienta de este tipo (como ltrace en Linux) para Windows que también sea transparente frente a los trucos anti-investigación utilizados por el malware moderno?
Resulta que existe una técnica que puede ayudarnos a tener dicha herramienta para Windows y rastrear llamadas API de forma transparente hacia el programa ejecutado. Esta técnica se llama instrumentación binaria dinámica, también conocida como DBI. DBI es una técnica de análisis del comportamiento de una aplicación binaria en tiempo de ejecución mediante la inyección de código de instrumentación.
Sin embargo, la aplicación de DBI para el análisis de malware está inmerecidamente limitada por la automatización de descompresión y varias pruebas de conceptos para instrucciones, bloques básicos y seguimiento de llamadas a funciones. Hasta donde sabemos, drltrace es una primera herramienta para el seguimiento de llamadas API basada en DBI que puede usarse en la práctica para el análisis de malware. Proporcionamos varios ejemplos de análisis de malware en nuestra wiki donde describimos cómo drltrace permitió deleitarse en varios minutos con una gran cantidad de detalles técnicos internos sobre muestras maliciosas sofisticadas sin siquiera iniciar IDA o el depurador.
-logdir [ .] Log directory to print library call data
-only_from_app [ false] Reports only library calls from the app
-follow_children [ true] Trace child processes
-print_ret_addr [ false] Print library call's return address
-num_unknown_args [ 2] Number of unknown libcall args to print
-num_max_args [ 6] Maximum number of arguments to print
-default_config [ true] Use default config file.
-config [ ""] The path to custom config file.
-filter [filter.config] The path of the whitelist/blacklist file.
-ignore_underscore [ false] Ignores library routine names starting with "_".
-help [ false] Print this message.
-version [ false] Print version number.
-verbose [ 1] Change verbosity.
-use_config [ true] Use config file
-grepable [ false] Grepable output
Drltrace admite archivos de configuración externos donde un usuario puede describir cómo drltrace debe imprimir argumentos para ciertas llamadas API.
HANDLE|CreateRemoteThread|HANDLE|SECURITY_ATTRIBUTES*|size_t|THREAD_START_ROUTINE*|VOID*|DWORD|__out DWORD*
Cada argumento de función debe estar separado por |
. El primer argumento es el tipo de retorno, el segundo argumento es el nombre de una función y el resto son los argumentos de la función. Un token __out
se usa para marcar argumentos de salida y ___inout
se usa para marcar argumentos de entrada+salida.
Puede encontrar ejemplos de cómo utilizar drltrace para el análisis de malware complejo en nuestra página Wiki.
Para facilitar el trabajo con archivos de registro, hemos implementado un script llamado api_calls_viz.py
que se puede utilizar para generar imágenes RGB donde cada color de píxel representa una llamada API única. Por ejemplo, la siguiente imagen representa el archivo de registro del malware WannaCry.
Las grandes áreas verdes en la imagen representan llamadas API ( wcscmp/wcsicmp
) que se utilizan para seleccionar archivos con extensiones interesantes (por ejemplo, docx, xls, py) para cifrarlos. Las áreas moradas representan llamadas API ( FindFirstFile/FindNextFile/CryptEncrypt
) que se utilizan para enumerar y cifrar archivos y carpetas en el disco.
El script también puede generar una representación HTML de la imagen RGB generada donde se puede seleccionar cada elemento para mostrar un nombre de llamada API.
Archivo HTML sin formato.
Consulte el directorio api_calls_viz
para obtener más detalles.
Puede encontrar un manual detallado en esta página Wiki.
Windows, Linux (macOS en el futuro).
x86, x64 (ARM en la lista).
Biblioteca estándar C y C++ (y scripts de manejo de registros escritos en Python).
Decidimos implementar nuestro rastreador de llamadas API sobre el marco de instrumentación binaria dinámica DynamoRIO. Drltrace le pide a DynamoRIO que realice la instrumentación de la llamada LoadLibrary para poder manejar las nuevas bibliotecas que carga el proceso de destino. Cuando el proceso intenta cargar una nueva biblioteca, DynamoRIO redirige el flujo de control a drltracelib.dll
. A su vez, drltrace enumera las funciones exportadas en la DLL recién cargada y registra una devolución de llamada especial para cada una de ellas. Por lo tanto, si el malware llama a alguna función exportada, la devolución de llamada de drltrace se ejecutará antes de esta función y la herramienta podrá registrar toda la información requerida, como el nombre de la función y los argumentos. Es posible que se registre otra devolución de llamada después de la función para guardar los resultados de la ejecución.
¿Por qué no Intel Pin? Decidimos utilizar DynamoRIO motivados por las siguientes razones:
-syswide_on
de drrun.exe
). Sin embargo, en el futuro será necesario implementar un soporte especial en drltrace para este tipo de situaciones.Nuestro rastreador de problemas contiene más detalles sobre el futuro de drltrace.
Maksim Shudrak https://github.com/mxmssh
Derek Bruening https://github.com/derekbruening
Joe Testa https://github.com/jtesta