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

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

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

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


1) трассируемая команда вызывает исключение

2) трассируемая программа выполняет pushfd (а там TF=1...)

3) трассируемая программа выполняет popfd, может начать трассировать сама себя

4) трассируемая программа выполняет iretd, тоже самое

5) mov ss,xx/pop ss - подлая штука, может быть с префиксами

6) трассируемая программа выполняет intxx/int3/icebp

7) трассируемая программа выполняет into

8) трассируемая команда читает int1 descriptor

9) трассируемая команда пишет в int1 descriptor

10) трассируемая программа выполняет sidt (...)

11) трассируемая программа выполняет lidt

12) трассируемая команда пишет в dr6 (использует для хранения чисел/проверки)

13) вариации: трассируемая программа ставит свой обработчик INT1/3, начинает трассировать себя, ставит hardware-breakpoint'ы на чтение/запись/выполнение, использует исключения для своих нужд и всё это работает одновременно, причем приоритет выполнения играет роль.

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

[что еще нужно для отладчика]

В большинстве случаев, для написания даже простого трейсера, несущего какую-то полезную нагрузку, нам понадобится не только возможность обрабатывать брекпоинты и трассировку, но и анализировать исполняемый код. А для этого нам нужен дизассемблер. Скорее всего, полноценный дизассемблер нам не понадобится, а достаточно будет простого дизассемблера длин, иногда нам может понадобиться вывод текста (дизасм листинга кода). Давай сформулируем требования, которым должен удовлетворять дизассемблер, применяемый в отладчике:

1) Независимость от операционной системы. Это необходимо для обеспечения универсальности дизассемблера и для работы его в любых условиях (в том числе даже без загруженного в память ядра системы).

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

3) Очень важна корректность дизассемблирования нестандартных опкодов (содержащих многократные префиксы, недопустимые значения байта Mod R/M или SIB), так как такие команды любят применять в защитах для обмана дизассемблеров и эмуляторов.

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