
Drltrace é um rastreador de chamadas de biblioteca para aplicações Windows e Linux.
Build de teste do Windows
Drltrace é um rastreador de chamadas de API dinâmico para aplicações Windows e Linux. Drltrace é construído sobre o framework 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 independente 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. O usuário precisa especificar um diretório de log e o nome do processo alvo da seguinte forma:
drltrace -logdir . -- calc.exe
Isso é tudo, a ferramenta injetará as DLLs necessárias no processo alvo, iniciará a instrumentação e, em paralelo, registrará informações sobre todas as chamadas de biblioteca executadas no processo alvo:
~~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 única linha:
~~4824~~ KERNELBASE.dll!CreateFileW {0: C:\Windows\Fonts\staticcache.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 únicos dos módulos é impressa ao 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:\Windows\SysWOW64\calc.exe
1, 1, 0x6d4c0000, 0x6d621000, 0x6d563940, 0x00136d65, 0x59ce1b0b, C:\Users\Max\Downloads\drltrace\drltrace\dynamorio\lib32\release\dynamorio.dll
2, 2, 0x73800000, 0x73975000, 0x7380dbf7, 0x00000000, 0x59ce1b0f, C:\Users\Max\Downloads\drltrace\drltrace\bin\release/drltracelib.dll
3, 3, 0x742f0000, 0x742fa000, 0x742f2a00, 0x0000c877, 0x0adc52c1, C:\Windows\System32\CRYPTBASE.dll
4, 4, 0x74300000, 0x74320000, 0x7430c9b0, 0x0002c617, 0x245970b4, C:\Windows\System32\SspiCli.dll
5, 5, 0x74410000, 0x74431000, 0x74416900, 0x0002a940, 0x88a53c1d, C:\Windows\System32\GDI32.dll
6, 6, 0x74440000, 0x74500000, 0x7446fb20, 0x000cc410, 0xd343d532, C:\Windows\System32\RPCRT4.dll
7, 7, 0x74500000, 0x74525000, 0x745047d0, 0x00026737, 0xa39c8991, C:\Windows\System32\IMM32.DLL
8, 8, 0x74550000, 0x745c7000, 0x7456e8a0, 0x00081857, 0x73b971e1, C:\Windows\System32\advapi32.dll
9, 9, 0x748f0000, 0x74929000, 0x748febd0, 0x00045303, 0xa58be652, C:\Windows\System32\cfgmgr32.dll
10, 10, 0x74930000, 0x75c78000, 0x74aa09d0, 0x01377aa6, 0x4b39926b, C:\Windows\System32\SHELL32.dll
Drltrace pode facilmente filtrar chamadas inter-bibliotecas e imprimir apenas as chamadas de API realizadas a partir do módulo principal (ou de um heap) de uma aplicação alvo, especificando a opção -only_from_app, que é muito útil no caso de aplicações que geram logs enormes. Para um controle mais granular, a opção -filter permite que o usuário especifique um arquivo de configuração de filtro para incluir funções específicas na lista de permissões ou ignorar funções na lista negra (veja o arquivo filter.config para exemplos). Drltrace também possui vários scripts externos úteis para filtrar chamadas de API para determinada biblioteca, imprimir apenas chamadas de API potencialmente interessantes e strings.
Os módulos principais do Drltrace são distribuídos sob a licença BSD.
Alguns arquivos necessários para o drltrace são distribuídos sob LGPL. Consulte os arquivos fonte para mais detalhes.
A análise de malware não é uma tarefa fácil. Empacotadores de software sofisticados como Themida e Armadillo, e claro, dezenas de empacotadores sem nome escritos por autores de malware, além da criptografia de código e dados, dificultam significativamente (em alguns casos tornando 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 entender a 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 várias 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 aplicações GUI pesadas e independentes (como produtos proprietários), que muitas vezes não são fáceis de integrar no fluxo de trabalho existente de análise de malware.
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 uma ferramenta como essa (como o ltrace no Linux) para Windows que também seja transparente contra truques anti-pesquisa usados por malwares modernos?
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. Essa 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 de DBI para análise de malware é injustamente limitada pela automação de desempacotamento e várias provas de conceito para rastreamento de instruções, blocos básicos e chamadas de função. Até onde sabemos, o 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 nossa wiki, onde descrevemos como o drltrace permitiu revelar em poucos minutos muitos detalhes técnicos internos sobre amostras maliciosas sofisticadas sem sequer 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 suporta arquivos de configuração externos onde o usuário pode descrever como o 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 é o tipo de retorno, o segundo argumento é o nome da função em si e os demais 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 o 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 o nome de uma chamada de API.

Consulte o diretório api_calls_viz para mais detalhes.
Você pode encontrar um manual detalhado nesta página Wiki.
Windows, Linux (macOS no futuro).
x86, x64 (ARM na lista).
C e C++ (biblioteca padrão) e scripts de manipulação de logs escritos em Python.
Decidimos implementar nosso rastreador de chamadas de API sobre o framework de instrumentação binária dinâmica DynamoRIO. O drltrace solicita ao DynamoRIO que realize a instrumentação da chamada LoadLibrary para ser capaz de 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, o drltrace enumera as funções exportadas na DLL recém-carregada e registra um callback especial para cada uma delas. Assim, se alguma função exportada for chamada pelo malware, o callback do drltrace será executado antes dessa função e a ferramenta poderá registrar todas as informações necessárias, como nome da função e argumentos. Outro callback pode ser registrado após a função para salvar os resultados da execução.
Por que não o Intel Pin? Decidimos usar o DynamoRIO motivados pelas seguintes razões:
-syswide_on do drrun.exe). No entanto, no futuro, é necessário implementar um suporte especial no drltrace para tais situações.Nosso rastreador de issues 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