Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #83, НОЯБРЬ 2005 г.

Строим отладчик

Ms-Rem (Ms-Rem@yandex.ru)

Хакер, номер #083, стр. 083-112-3


А теперь давай подробнее рассмотрим управляющие биты в регистрах dr6 и dr7. В dr6:

бит BT - устанавливается, если происходит включение задачи в задачу, где TSS имеет установленный бит ловушки отладки.

бит BS - разрешает обработчикам отладки отличать одноступенчатые ловушки от других условий отладки.

бит BD - устанавливается аппаратурой, если следующая команда получает доступ к регистру отладки.

биты B0-B3 - устанавливаются, если произошло прерывание ограниченного использования. В0 устанавливается, если произошло прерывание 0 (точка останова) и т.д.

dr7 - уже побольше, ведь он - Регистр Управления Отладкой, и используется для разрешения или уточнения различных точек останова. Состоит регистр из следующих составляющих:

LEN - двухбитовое поле, которое определяет длину прерывания. Все прерывания должны быть выровнены: 2-х байтовые векторы по границам слова; 4-х байтовые по границе двойных слов.

00 - длина в один байт,

01 - длина в два байта,

10 - неопределена,

11 - длина в четыре байта.

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

GE/LE - Глобальная и Локальная Верные Точки Останова: эти биты должны быть всегда установлены на 1 при использовании прерываний.

Gi/Li - Разблокировка Глобальной и Локальной Точек Останова: если Gi=1, либо Li=1, то прерывания разблокируются. Если эти биты установлены, то любое прерывание ограниченного использования (то есть точка останова, которая соответствует условиям, определенным битами LE) заставит процессор выполнять программу обработки отладки. Биты Li позволяют устанавливать локальные точки останова для индивидуальной задачи, но при этом не оказывают влияния на другую задачу. Gi позволяют устанавливать прерывания, воздействующие на все задачи.

Для того чтобы установить точку останова, микропроцессор должен работать на 0 уровне привилегий, в Реальном режиме. Точка останова должна быть установлена путем загрузки регистра точки прерывания (посредством команды MOV DRi,[операнд в памяти или регистре]). После чего должны быть установлены соответствующий LEN и RWE, а также биты разблокировки точки прерывания Gi и/или Li.

Биты Bi в DR6 всегда покажут любую точку останова ограниченного использования; но до тех пор, пока не будут установлены Gi или Li, процессор не будет выполнять программу отладки с этими прерываниями.

Так, с установкой брекпоинтов мы, пожалуй, разобрались, топаем дальше.

Трассировка в процессорах x86 реализуется посредством флага трассировки (9-ый бит) в регистре флагов efl. При установке этого бита каждая следующая выполняемая команда будет вызывать исключение int 1. Это обычно и используется отладчиками для трассировки исполнения кода. Установить этот флаг можно с помощью команд влияющих на регистр флагов (iretd, retf, popfd), либо (применительно к Windows) изменив контекст потока с помощью GetThreadContext/SetThreadContext.

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

Назад на стр. 083-112-2  Содержание  Вперед на стр. 083-112-4