Строим отладчик 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), так как такие команды любят применять в защитах для обмана дизассемблеров и эмуляторов. |