Compilação de teste do Windows
Versão de teste do Linux
Drltrace é um rastreador dinâmico de chamadas de API para aplicativos Windows e Linux. Drltrace é construído sobre a estrutura de instrumentação binária dinâmica DynamoRIO. Drltrace foi inicialmente implementado por Derek Bruening e distribuído com os frameworks DynamoRIO e DrMemory. Este repositório contém uma versão autônoma do drltrace com scripts e materiais adicionais sobre como usá-lo para análise de malware. A versão de lançamento pode ser baixada aqui.
O uso do drltrace é muito simples. Um usuário precisa especificar um diretório de log e um nome de um processo de destino da seguinte maneira:
drltrace -logdir . -- calc.exe
Isso é tudo, a ferramenta injetará as DLLs necessárias no processo de destino, iniciará a instrumentação e, paralelamente, registrará informações sobre todas as chamadas de biblioteca executadas no processo 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
O formato da saída é simples e pode ser facilmente analisado por um 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]
A análise com grep
pode ser feita quando o argumento -grepable
é usado; isso imprime os nomes das funções e argumentos em uma linha:
~~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)}
A tabela de identificadores exclusivos do módulo é impressa no final do arquivo de log:
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 pode facilmente filtrar chamadas entre bibliotecas e imprimir apenas chamadas de API realizadas a partir do módulo principal (ou de um heap) de um aplicativo de destino, especificando a opção -only_from_app
que é muito útil no caso de aplicativos que geram logs enormes. Para um controle mais granular, a opção -filter
permite ao usuário especificar um arquivo de configuração de filtro para filtrar funções específicas da lista de permissões ou ignorar funções da lista negra (consulte o arquivo filter.config para obter exemplos). Drltrace também possui vários scripts externos úteis para filtrar chamadas de API para determinadas bibliotecas, imprimir apenas chamadas e strings de API potencialmente interessantes.
Os módulos principais do Drltrace são distribuídos no BSD.
Alguns arquivos necessários para drltrace são distribuídos sob LGPL. Veja os arquivos de origem para mais detalhes.
A análise de malware não é uma tarefa fácil. Compactadores de software sofisticados como Themida e Armadillo e, claro, dezenas de compactadores sem nome escritos por autores de malware, além de criptografia de código e dados, facilitam significativamente (em alguns casos, tornando-o completamente impossível) a engenharia reversa estática de tais amostras, complicando a vida dos analistas de malware. Nesse caso, o rastreamento de chamadas de API pode reduzir significativamente o tempo necessário para compreender uma intenção maliciosa real e revelar muitos detalhes técnicos sobre o código malicioso protegido.
Embora a técnica tradicional de API-hooking tenha sido implementada com sucesso em diversas soluções, a abordagem é bem estudada por autores de malware e pode ser facilmente detectada e/ou contornada. Além disso, essas ferramentas são distribuídas como aplicativos GUI independentes e pesados (como produtos proprietários), que muitas vezes não são fáceis de integrar no fluxo de trabalho de análise de malware existente.
Se olharmos para o mundo Linux, existe uma ferramenta maravilhosa chamada ltrace. Usando um único comando bash, podemos facilmente obter o rastreamento completo das chamadas de API de um determinado executável.
Por que não temos essa ferramenta (como o ltrace no Linux) para Windows, que também é transparente contra truques anti-pesquisa usados por malware moderno?
Acontece que existe uma técnica que pode nos ajudar a ter essa ferramenta para Windows e rastrear chamadas de API de forma transparente para o programa executado. Esta técnica é chamada de instrumentação binária dinâmica, também conhecida como DBI. DBI é uma técnica de análise do comportamento de uma aplicação binária em tempo de execução por meio da injeção de código de instrumentação.
No entanto, a aplicação do DBI para análise de malware é injustamente limitada pela descompactação da automatização e por diversas provas de conceitos para instruções, blocos básicos e rastreamento de chamadas de função. Até onde sabemos, drltrace é a primeira ferramenta para rastreamento de chamadas de API baseada em DBI que pode ser usada na prática para análise de malware. Fornecemos vários exemplos de análise de malware em nosso wiki, onde descrevemos como o drltrace permitiu revelar em vários minutos muitos detalhes técnicos internos sobre amostras maliciosas sofisticadas, mesmo sem iniciar o IDA ou o 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 oferece suporte a arquivos de configuração externos onde um usuário pode descrever como drltrace deve imprimir argumentos para determinadas chamadas de API.
HANDLE|CreateRemoteThread|HANDLE|SECURITY_ATTRIBUTES*|size_t|THREAD_START_ROUTINE*|VOID*|DWORD|__out DWORD*
Cada argumento de função deve ser separado por |
. O primeiro argumento é do tipo de retorno, o segundo argumento é o próprio nome de uma função e o restante são os argumentos da função. Um token __out
é usado para marcar argumentos de saída e ___inout
é usado para marcar argumentos de entrada + saída.
Você pode encontrar exemplos de como usar drltrace para análise de malware complexo em nossa página Wiki.
Para facilitar o trabalho com arquivos de log, implementamos um script chamado api_calls_viz.py
que pode ser usado para gerar imagens RGB onde cada cor de pixel representa uma chamada de API única. Por exemplo, a imagem abaixo representa o arquivo de log do malware WannaCry.
As grandes áreas verdes na imagem representam chamadas de API ( wcscmp/wcsicmp
) que são usadas para selecionar arquivos com extensões interessantes (por exemplo, docx, xls, py) para criptografá-los. As áreas roxas representam chamadas de API ( FindFirstFile/FindNextFile/CryptEncrypt
) que são usadas para enumerar e criptografar arquivos e pastas no disco.
O script também pode gerar uma representação HTML da imagem RGB gerada onde cada elemento pode ser selecionado para mostrar um nome de chamada de API.
Arquivo HTML bruto.
Consulte o diretório api_calls_viz
para obter mais detalhes.
Você pode encontrar um manual detalhado nesta página Wiki.
Windows, Linux (macOS no futuro).
x86, x64 (ARM na lista).
Biblioteca padrão C e C++ (e scripts de manipulação de logs escritos em Python).
Decidimos implementar nosso rastreador de chamadas de API no framework de instrumentação binária dinâmica DynamoRIO. Drltrace pede ao DynamoRIO para realizar a instrumentação da chamada LoadLibrary para poder lidar com novas bibliotecas sendo carregadas pelo processo alvo. Quando o processo tenta carregar uma nova biblioteca, o DynamoRIO redireciona o fluxo de controle para drltracelib.dll
. Por sua vez, drltrace enumera funções exportadas na DLL recém-carregada e registra um retorno de chamada especial para cada uma delas. Assim, se alguma função exportada for chamada por malware, o retorno de chamada do drltrace será executado antes desta função e a ferramenta será capaz de registrar todas as informações necessárias, como nome da função e argumentos. Outro retorno de chamada pode ser registrado após a função para salvar os resultados da execução.
Por que não Intel Pin? Decidimos utilizar o DynamoRIO motivados pelos seguintes motivos:
-syswide_on
de drrun.exe
). Porém, futuramente, será necessário implementar um suporte especial no drltrace para tais situações.Nosso rastreador de problemas contém mais detalhes sobre o futuro do drltrace.
Maksim Shudrak https://github.com/mxmssh
Derek Bruening https://github.com/derekbruening
Joe Testa https://github.com/jtesta