
Drltrace — это трассировщик вызовов библиотек для приложений Windows и Linux.
Сборка для Windows
Drltrace — это динамический трассировщик вызовов API для приложений Windows и Linux. Drltrace построен на основе фреймворка динамической бинарной инструментации DynamoRIO. Drltrace изначально был реализован Дереком Брюнингом и распространялся с фреймворками DynamoRIO и DrMemory. Этот репозиторий содержит отдельную версию drltrace с дополнительными скриптами и материалами по её использованию для анализа вредоносного ПО. Релизную сборку можно скачать здесь.
Использование drltrace очень простое. Пользователю нужно указать каталог для журнала и имя целевого процесса следующим образом:
drltrace -logdir . -- calc.exe
Всё, инструмент внедрит необходимые DLL в целевой процесс, начнёт инструментацию и параллельно будет записывать информацию обо всех вызовах библиотек, выполняемых в целевом процессе:
~~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
Формат вывода прост и легко парсится внешним скриптом:
~~[id потока]~~ [имя DLL]![имя вызова API]
arg [№ аргумента]: [значение] (type=[имя типа Windows], size=[размер аргумента])
and return to module id:[уникальный id модуля], offset:[смещение в памяти]
Парсинг с помощью grep возможен при использовании аргумента -grepable; в этом случае имена функций и аргументы печатаются в одной строке:
~~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)}
Таблица уникальных идентификаторов модулей печатается в конце файла журнала:
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 может легко отфильтровывать межбиблиотечные вызовы и печатать только вызовы API, выполненные из главного модуля (или из кучи) целевого приложения, с помощью опции -only_from_app, что очень полезно в случае приложений, генерирующих огромные журналы. Для более тонкого управления опция -filter позволяет пользователю указать файл конфигурации фильтра, чтобы фильтровать определённые разрешённые функции или игнорировать запрещённые (см. примеры в файле filter.config). Drltrace также имеет несколько полезных внешних скриптов для фильтрации вызовов API по определённой библиотеке, вывода только потенциально интересных вызовов API и строк.
Основные модули Drltrace распространяются под лицензией BSD.
Некоторые файлы, необходимые для drltrace, распространяются под LGPL. Подробнее см. в исходных файлах.
Анализ вредоносного ПО — непростая задача. Сложные программные упаковщики, такие как Themida и Armadillo, а также десятки безымянных упаковщиков, написанных авторами вредоносного ПО, плюс шифрование кода и данных значительно затрудняют (в некоторых случаях делая полностью невозможным) статическое реверсирование таких образцов, усложняя жизнь аналитикам вредоносного ПО. В таких случаях трассировка вызовов API может значительно сократить время, необходимое для понимания реального вредоносного замысла, и раскрыть множество технических деталей о защищённом вредоносном коде.
Хотя традиционная техника API-хукинга была успешно реализована в нескольких решениях, этот подход хорошо изучен авторами вредоносного ПО и может быть легко обнаружен и/или обойдён. Более того, эти инструменты распространяются как отдельные тяжеловесные GUI-приложения (проприетарные продукты), которые не всегда легко интегрировать в существующий рабочий процесс анализа вредоносного ПО.
Если посмотреть на мир Linux, там есть замечательный инструмент ltrace. С помощью одной команды bash мы можем легко получить полный трассировку вызовов API определённого исполняемого файла.
Почему у нас нет такого инструмента (как ltrace в Linux) для Windows, который был бы также прозрачен для анти-исследовательских трюков, используемых современным вредоносным ПО?
Оказывается, существует техника, которая может помочь нам создать такой инструмент для Windows и прозрачно трассировать вызовы API для выполняемой программы. Эта техника называется динамическая бинарная инструментация (DBI). DBI — это метод анализа поведения бинарного приложения во время выполнения путём внедрения инструментационного кода.
Однако применение DBI для анализа вредоносного ПО незаслуженно ограничено автоматизацией распаковки и несколькими доказательствами концепций для трассировки инструкций, базовых блоков и вызовов функций. Насколько нам известно, drltrace — это первый инструмент для трассировки вызовов API на основе DBI, который можно использовать на практике для анализа вредоносного ПО. Мы предоставили несколько примеров анализа вредоносного ПО в нашей вики, где описали, как drltrace позволил за несколько минут выявить множество внутренних технических деталей сложных вредоносных образцов, даже не запуская IDA или отладчик.
-logdir [ .] Каталог журнала для вывода данных о вызовах библиотек
-only_from_app [ false] Сообщать только о вызовах библиотек из приложения
-follow_children [ true] Трассировать дочерние процессы
-print_ret_addr [ false] Печатать адрес возврата вызова библиотеки
-num_unknown_args [ 2] Количество неизвестных аргументов вызова библиотеки для вывода
-num_max_args [ 6] Максимальное количество аргументов для вывода
-default_config [ true] Использовать конфигурационный файл по умолчанию.
-config [ ""] Путь к пользовательскому конфигурационному файлу.
-filter [filter.config] Путь к файлу белого/чёрного списка.
-ignore_underscore [ false] Игнорировать имена библиотечных процедур, начинающиеся с "_".
-help [ false] Вывести это сообщение.
-version [ false] Вывести номер версии.
-verbose [ 1] Уровень подробности.
-use_config [ true] Использовать конфигурационный файл
-grepable [ false] Вывод, пригодный для grep
Drltrace поддерживает внешние конфигурационные файлы, в которых пользователь может описать, как drltrace должен выводить аргументы для определённых вызовов API.
HANDLE|CreateRemoteThread|HANDLE|SECURITY_ATTRIBUTES*|size_t|THREAD_START_ROUTINE*|VOID*|DWORD|__out DWORD*
Каждый аргумент функции должен быть разделён символом |. Первый аргумент — это тип возвращаемого значения, второй — имя самой функции, остальные — аргументы функции. Токен __out используется для пометки выходных аргументов, а ___inout — для входных+выходных аргументов.
Примеры использования drltrace для анализа сложного вредоносного ПО можно найти на нашей странице Wiki.
Чтобы упростить работу с файлами журналов, мы реализовали скрипт под названием api_calls_viz.py, который можно использовать для генерации RGB-изображений, где каждый цвет пикселя представляет уникальный вызов API. Например, изображение ниже представляет файл журнала вредоносного ПО WannaCry.

Большие зелёные области на изображении представляют вызовы API (wcscmp/wcsicmp), которые используются для выбора файлов с интересными расширениями (например, docx, xls, py) для их шифрования. Фиолетовые области представляют вызовы API (FindFirstFile/FindNextFile/CryptEncrypt), которые используются для перечисления и шифрования файлов и папок на диске.
Скрипт также может генерировать HTML-представление созданного RGB-изображения, где каждый элемент можно выбрать, чтобы показать имя вызова API.

Подробнее см. в каталоге api_calls_viz directory.
Подробное руководство можно найти на этой странице Wiki.
Windows, Linux (macOS в будущем).
x86, x64 (ARM в планах).
Стандартная библиотека C и C++ (а также скрипты для обработки журналов на Python).
Мы решили реализовать наш трассировщик вызовов API на основе фреймворка динамической бинарной инструментации DynamoRIO. Drltrace просит DynamoRIO выполнить инструментацию вызова LoadLibrary, чтобы иметь возможность обрабатывать новые библиотеки, загружаемые целевым процессом. Когда процесс пытается загрузить новую библиотеку, DynamoRIO перенаправляет поток управления в drltracelib.dll. В свою очередь, drltrace перечисляет экспортируемые функции в недавно загруженной DLL и регистрирует специальный обратный вызов для каждой из них. Таким образом, если какая-то экспортируемая функция будет вызвана вредоносным ПО, обратный вызов drltrace будет выполнен до этой функции, и инструмент сможет записать всю необходимую информацию, такую как имя функции и аргументы. Другой обратный вызов может быть зарегистрирован после функции для сохранения результатов выполнения.
Почему не Intel Pin? Мы решили использовать DynamoRIO по следующим причинам:
-syswide_on утилиты drrun.exe). Однако в будущем необходимо реализовать специальную поддержку в drltrace для таких ситуаций.Наш трекер задач содержит больше подробностей о будущем drltrace.
Максим Шудрак https://github.com/mxmssh
Дерек Брюнинг https://github.com/derekbruening
Джо Теста https://github.com/jtesta