Программная среда для динамического анализа бинарного кода

Связывание интерфейсов среды TrEx со скриптовым языком


В качестве инструментального языка, при разработке среды TrEx был использован язык С++, что позволило добиться в критических местах кода должного уровня производительности. Однако с точки зрения пользователя среды она является «монолитом», обладающим фиксированным набором возможностей, и предоставляющим их средствами графического интерфейса. Разработка и встраивание собственных модулей-расширений способна решить эту проблему, однако такой подход сопряжен со значительными временными задержками, не приемлемыми для пользователя. Подходящим решением в данной ситуации является встраивание в среду интерпретатора скриптового языка, обеспеченного привязкой к методам и классам Common API.

В качестве кандидата на встраивание рассматривались следующие языки: Lua, Ch, Java/Javascript, Perl, Ruby. Были сформулированы следующие обязательные требования, которым должен удовлетворять скриптовый язык и его окружение.

  • Возможность удобной работы с классами языка C++.
  • Поддержка шаблонов.
  • Перехват исключительных ситуаций.
  • Наличие средств автоматизации для построения привязки.

В результате рассмотрения была выбрана связка Lua/SWIG. Ключевыми достоинствами выбранного решения является: открытый код, наличие сообщества, занимающегося развитием этих программных средств, малые накладные расходы на встраивание при использовании генератора кода привязки SWIG.

Возможность выполнения Lua-скриптов обеспечивается скриптовой консолью, совмещенной с окном вывода информационных сообщений среды. Применяемый интерпретатор Lua, по сравнению со стандартным, обладает следующими отличиями.

  1. Тип number, соответствующий в стандартном Lua C-типу double, в TrEx является 64-битным знаковым целым.
  2. Формат ввода чисел соответствует стандартному: число «10» воспринимается как десятичное 10, число «0x10» как десятичное 16, число «010» как восьмеричное 8. Формат вывода чисел всегда шестнадцатеричный, без префикса «0x».
  3. Операция возведения в степень в силу слабой применимости для целых чисел заменена на «исключающее или».
  4. Набор стандартных библиотек сохранен без изменений, за исключением библиотеки math, которая отключена по причине переопределения типа number.


При открытии трассы в ее контексте автоматически выполняется скрипт autoload.lua, расположенный в каталоге TrEx. Предоставляемый скрипт создает окружение, позволяющее получить доступ к элементам трассы в более простом виде, нежели при использовании C++-интерфейсов напрямую.

В стандартном окружении определен набор таблиц, используемых для ввода-вывода и работы с моделью и трассой.

Таблица TrEx.Util содержит следующие два поля.


  • TrEx.Util.loggerInstance хранит ссылку на объект Logger, позволяющий выводить сообщения в консоль и файл журнала.
  • TrEx.Util.traceContext хранит ссылку на объект TraceContext открытой трассы.


Таблица TrEx.Model используется для работы с регистровым файлом архитектуры, соответствующей открытой трассе. По ключу, соответствующему имени регистра (в нижнерегистровом или верхнерегистровом написании) или его числовому коду таблица позволяет получить описание регистра в виде структуры NamedElement.

Таблица TrEx.Trace содержит механизмы для работы с шагами трассы. Помимо получения количества шагов в трассе по ключу n, она позволяет обратиться к отдельному шагу по ключу, соответствующему его порядковому номеру. Помимо того, через ключ TrEx.Trace.position доступен номер выбранного пользователем шага.



Для доступа к декомпозиции на зависимости используется поле Dep объекта шага трассы, например TrEx.Trace[0].Dep. Данная таблица содержит количество зависимостей в ключе n, а также сами зависимости в виде объектов класса Dep по числовым ключам с 0 до n - 1.

Разбор на зависимости управляется флагами, содержащимися в TrEx.Trace.depFlags. В начальном состоянии флаги устанавливаются в значение 15, соответствующее наиболее полному набору флагов.

Рассмотрим пример использования TrEx.Trace.Dep: выводим все зависимости инструкции в шаге stepIndex (Рис. 2).

Таблица TrEx.Notepad предоставляет расширенные возможности вывода для скриптов с использованием окон «блокнотов». В каждом из таких блокнотов может содержаться список шагов и сопоставленной им текстовой информации с возможностью перехода к соответствующему шагу в трассе по двойному клику.



Для создания нового или доступа к уже существующему блокноту применяется индексированный доступ к таблице по имени блокнота (имя может являться произвольной строкой). Пример работы с блокнотом показан на Рис. 3.

local dumpDeps = function(stepIndex) local i

-- Цикл по зависимостям. for i = 0, TrEx.Trace[stepIndex].Dep.n - 1 do -- Выводим номер зависимости и ее текстовый вид. print(i, TrEx.Trace[stepIndex].Dep[i]) end end

Рис. 2. Работа с зависимостями в Lua-скрипте

for i = 0, TrEx.Trace.n - 1 do -- Проверяем eax. if 0 == TrEx.Trace[i].eax then -- Добавляем в блокнот "Zero EAX". TrEx.Notepad["Zero EAX"]:print(i, "На этом шаге eax == 0") end

-- Проверяем ebx. if 0 == TrEx.Trace[i].ebx then -- Добавляем в блокнот "Zero EBX". TrEx.Notepad["Zero EBX"]:print(i, "На этом шаге ebx == 0") end

-- Если на каком-то шаге eax и ebx равны нулю одновременно, добавляем текст в оба блокнота -- и выделяем его красным (0x0000FF) цветом. if (0 == TrEx.Trace[i].eax) and (0 == TrEx.Trace[i].ebx) then -- Добавляем в оба блокнота красный текст. TrEx.Notepad["Zero EAX"]:cprint(i, "Причем ebx тоже 0!", 0x0000FF) TrEx.Notepad["Zero EBX"]:cprint(i, "Причем eax тоже 0!", 0x0000FF) end end

Рис. 3. Пример использования TrEx.Trace и TrEx.Notepad для поиска шагов, где eax == 0 или ebx == 0.

В блокноте, таким образом, определены два метода: print(stepIndex, message) и cprint(stepIndex, message, color). В качестве color могут использоваться произвольные RGB-цвета.


Содержание раздела