Модернизация IDA Pro. Debugger-плагин. Часть I. Теория

ba01df5253b845cf8bb51c632a1500f2.jpg


Всем привет. Я решил попробовать начать цикл статей по модернизации нашей с вами любимой IDA Pro.
В каждом из туториалов я попытаюсь раскрыть довольно таки сложную и мало изученную тему: написание различных модулей:

  • загрузчики;
  • плагины;
  • дебагер-плагины;
  • процессорные модули;
  • скрипты.


И, если процессорные модули, плагины и скрипты — тема все таки более менее раскрытая, то все остальное — практически полный мрак (в конце статьи я дам список литературы и проектов, где есть хоть что-то).

Итак, первая статья из цикла будет посвящена написанию плагина-отладчика, а точнее предварительной теории. В штатной поставке IDA SDK уже имеются исходники основных дебагеров (Windows, Linux, Mac). Но как быть, например, с Amiga, M68000?
Данная статья скорее будет посвящена скучной и не очень теории. Настоятельно рекомендуется с ней ознакомиться, т.к. многие моменты в дальнейшем могут быть непонятны именно из-за невозможности представить общую концепцию.

Для начала, определимся с тем, какие бывают плагины-отладчики.

Типы дебагер-плагинов


У плагинов-отладчиков для IDA бывает два основных типа:

  • локальный — исполняется на той же машине, на которой происходит процесс отладки;
  • удаленный (RPC) — исполняется удаленно. Придется дергать его локальным плагином.


Еще есть кое-какие другие, но они не будут рассмотрены в данных статьях (или будут?). Я опишу здесь только локальный отладчик, т.к. удаленный требует в два раза больше кода (клиент и сервер), и еще не достаточно хорошо мной изучен.

Составляющие дебагер-плагина


  • Собственно, IDA. Посылает команды, принимает и реагирует на сообщения от дебагера, отображает текущее состояние отладки;
  • Эмулятор нужного нам процессора или кода. Допустим, он умеет выполнять инструкции, сообщать о брейкпоинтах, приостанавливать и продолжать процесс эмуляции, стартовать и завершать процесс;
  • Ну и сам дебагер-плагин. Он должен взаимодействовать с эмулятором, посылать сообщения в IDA, читать текущее состояние регистров, памяти.


Итак, обо всех составляющих по порядку.

IDA — визуальный интерфейс


Собственно, сама IDA является переходником между интерфейсом пользователя и дебагером, посылая ему команды, и ожидая какой-либо реакции (сообщений). Команды могут быть такими:

  • Завершение обработки текущего события;
  • Начало / пауза / завершение процесса или потока;
  • Шаг (Step Into, Step Over, Step Until Return);
  • Установка / удаление бряков;
  • Чтение / запись памяти или регистров;


Дебагер-плагин


Задача плагина — реагировать на команды от IDA (см. выше), и посылать ей события следующих типов, сработавших в эмуляторе:

  • Старт / приостановка / присоединение / отсоединение от / завершение процесса;
  • Старт / завершение потока;
  • Брейкпоинт;
  • Шаг (Step Into, Step Over, Step Until Return);
  • Исключение.


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

Эмулятор — всему голова


Каково назначение эмулятора? Конечно, выполнение инструкций. Еще он умеет хранить контекст. Иногда, держит информацию о брейкпоинтах (а бывает, что и нет — тогда приходится их реализовывать на уровне дебагера). Так же, бывает, что функции приостановки / продолжения исполнения сам эмулятор не имеет, и приходится ее как-то реализовывать. Одно радует — обычно исходники эмуляторов для многих платформ уже существуют, и, зачастую, их нужно только чуть-чуть модернизировать под нашу задачу.

Итак, эмулятор сообщает в дебагер о наступлении в себе событий:

  • Произошел запуск / завершение процесса или потока;
  • Сработал брейкпоинт;
  • Был выполнен шаг;
  • Сработало исключение.


События


Разберем событие Шага:

  1. Я нажимаю в IDA клавишу F7 (Step Into);
  2. В дебагер попадает команда завершения последнего наступавшего до этого события. Обычно дебагер в этом случае должен будет сказать эмулятору продолжить исполнение;
  3. Далее дебагер получает команду выполнения шага в потоке, реагирует на это выполнением одной инструкции эмулятора;
  4. Эмулятор сообщает обратно в дебагер о том, что событие STEP наступило, помещая его в очередь событий (об очереди событий читайте ниже);
  5. Дебагер достает из очереди событий отправленное событие, и сообщает о нем в IDA;
  6. IDA реагирует на наступившее событие. В данном случае, осознает, что шаг был выполнен, и показывает текущий адрес EIP, на который мы встали после выполнения шага;
  7. После того, как мы насмотрелись на окно IDA с состоянием регистров и прочего, и хотим что-то сделать дальше (например, другой шаг, нажимая F7), происходит снова цикл на первый пункт.


Очередь событий:
Такая штука, которая постоянно крутится в отдельном потоке дебагера, в ожидании наступления новых событий эмулятора. Получая новое событие, необходимо приостановить эмуляцию (т.к. шаг подразумевает фриз процесса), а затем передать событие в IDA. Когда IDA сообщит, что событие обработано, в дебагер придет команда завершения обработки текущего события.

Как видите, тема очень мутная, и, не очень простая. Но, это так кажется на первый взгляд. В следующей статье мы приступим собственно к написанию дебагер-плагина, заодно и разберемся, что да как.

— Список литературы и проектов:


  • The IDA Book — лучшая в своем роде книга по IDA Pro. Там есть практически все (ну, кроме как о дебагерах).
    MUST HAVE!;
  • deci3dbg — один из двух публичных дебагер-модулей.
    Отладчик для PS3;
  • idados — второй дебагер-модуль, хоть и жутко кривой (но автора можно простить, т.к. тема мало изучена и сейчас).
    Отладчик MS-DOS;
  • idados_dosbox — мой форк предыдущего проекта. Хотя бы собирается нормально, и не так бажит;
  • IDASDK\plugins\debugger — то, с чего все начинают. Сложно, непонятно.

© Habrahabr.ru