Один из способов обхода аппаратных точек останова - замена обработчика первого прерывания на свой с последующим восстановлением. Тогда, даже если точки останова сработают, управление получит новый обработчик, который никому ничего нескажет. Можно ли перехватить момент замены обработчика? Попытался сделать это, внеся в один из DR-регистров 4 байта по смещению 8 в IDT, но, при первом же сабатывании первого прерывания происходит ребут. Вопрос в следующем - может быть, при обработке прерывания процессор сам читает адрес обработчика, на чем и срабатывает точка останова... то есть зацикливание до переполнения стека? И если это так, то как тогда отловить момент замеы обработчика?
Спешу обрадовать тебе - существует второй способ перехвата аппаратного прерывания - перепрограммирование котроллера прерываний или APIC в зависимости от компьютера. А отловить непосредственно замену INT1 нельзя, если ты тавишь брейк на запись, а вот на чтение (ведь тот кто меняет адрес обработки должен сначала прочитать старый) можно, потом перехватываешь IRQ0, и проверяешь каждые 1/18 сек, изменился ли адрес. Есть еще круче способ - shadow BIOS, сначала разрешаешь запись, пишешь свой адрес и запрещаешь запись. А далее все что хочешь, то и лови, ведь запись в эту область ничего не даст. Есть способ который работает только на Intel, выставив память страницы с IDT только на чтение.
Спешу обрадовать тебе - существует второй способ перехвата аппаратного прерывания - перепрограммирование котроллера прерываний или APIC в зависимости от компьютера Ну надо же! А что, при генерации int1 участвует контроллер прерываний??? А отловить непосредственно замену INT1 нельзя, если ты тавишь брейк на запись, а вот на чтение (ведь тот кто меняет адрес обработки должен сначала прочитать старый) можно, а сам процессор, когда происходит int1, не читает? Я об это писал в самом начале. потом перехватываешь IRQ0, и проверяешь каждые 1/18 сек, изменился ли адрес до этого я бы и сам догадался мне это не подходит, ибо за 1/18 секунды можно многое успеть Есть еще круче способ - shadow BIOS, сначала разрешаешь запись, пишешь свой адрес и запрещаешь запись. А далее все что хочешь, то и лови, ведь запись в эту область ничего не даст при чем тут Биос?! я не хочу запретить смену обработчика, я хочу ее отловить Есть способ который работает только на Intel, выставив память страницы с IDT только на чтение а на AMD не работает? меня, собственно, только семейство x86 и интересует. А писать в память, которая только для чтения, из драйвера - очень просто, так что это - не вариант.
Конечно же не участвует Читает Работает и на AMD. Но только ничего отловить он не сможет, так как обычно идт патчат при сброшеном WP бите. Имхо на x86 архитектуре это задача невыполнимая.
то есть, действительно происходит зацикливание... жаль реакция моя в предыдущем посте - шутливая, извините.
Решение есть, основанное на тех же принципах, с помощью которых одно время обходили 'Pentium F0 bug', а именно -- начало IDT помещается в конец страницы, т.е. первые n дескрипторов находятся на одной странице, а остальные -- на другой. Первая страница соотв. делается NP, а обработчик #PF выполняет всю грязную работу. Звучит просто, но реализация полноценного перехвата отнюдь не самая легкая, особенно если надо сделать совместимость со средой выполнения, в которой интенсивно используется трассировка/апп.брекпоинты по выполнению/данным.
Если на странице стоит noacess, то случиться. Но такой метод грозит несовместимостью с защитами типа StarForce и отладчиками.
А писать в память, которая только для чтения, из драйвера - очень просто, так что это - не вариант. ---- Писать в память которая только для чтения из драйвера действительно просто, про бит WP все вспоминают, а вот про MSR где дополнительно (начиная с Pentium pro) задаются облати памяти только для записи (использование данной технологии в операционных системах я не встречал, но она описана в мануале на процессор), при этом возникает машинное исключение (его вектор тоже задается в MSR), которое и отлавливаем. Иммено по причине использования MSR я уточнил, что способ работает только на Intel.
Да еще, если программа работает на уровне ядра, и написана достаточно грамотно, то действительно невозможно отловить замену обработчика INT1. Я в таких случаях в своем отладчике поступаю нетривиально использую провеку адреса INT1 по прерыванию IRQ0, если изменился - восстанавливаю. Вариант предложенный _BC_ мне очень понравился, хотя и он обходится.
Обойти не так уж легко как кажется на первый взгляд, особенно с применением определенных спецсредств... Т.к. этот способ легально использует ОС для фикса F0-bug'a, патч ядра в коде, обрабатывающем #PF, будет довольно трудно устранить. Обнаружить такой патч на 9х -- практически невозможно, т.к. данные в VMM перемешаны с кодом, плюс сам VMM на винте лежит запакованный в vmm32.vxd, vmm немного различается для разных подверсий 9х, да еще и сам VMM любит себя патчить для скорости... хотя некоторые мyдaки могут не побрезговать побегать по vmm'у дизассемблером длин и найти такой перехват, подобные прецеденты уже были. В аттаче кусочек кода с vmm, который обрабатывает F0-bug. _803879196__w9x_pf.rar
PROFi Я в таких случаях в своем отладчике поступаю нетривиально использую провеку адреса INT1 по прерыванию IRQ0, если изменился - восстанавливаю а что нетривиального в проверке по таймеру? И где гарантия, что за 1/18 секунды программа не заменит обработчик int1, не сделает свое дело и не восстановит оригинальный обработчик? Можно подробнее, какие именно MSR? _BC_ спасибо! буду смотреть, хотя реализация пока пугает сложностью
Wolfgang Грантий конечно нет, но такой нетривиальный подход позволяет непотерять управление над INT1. Что касается использования BIOS. То привожу файл, который позволяет открывать область BIOS с 0F000:0000 на запись (не прошивка биос) основан на изучении исходников AWORDа. Работает на всех BIOS AWARD. Что касается MSR, то почитай мануалы к Pentium III. Там все довольно запутано, но этот вариант работает. У меня сейчас к сожалению этой документации подрукой нет. 6094547__ShadowBios.rar