Содержание материала

 

dwContinueStatus: DWORD;

{ как системе обрабатывать событие в ContinueDebugEvent. обнаружилось, что если это событие - не исключение (EXCEPTION_DEBUG_EVENT), то этот флажок системе "по сараю". а если исключение, то есть два варианта: DBG_CONTINUE - наш "отладчик" успешно обработал все сам, и DBG_EXCEPTION_NOT_HANDLED, что значиит - передать исключение системе на обработку }

CurThread: DWORD;

{ хэндл потока, найденный в нашем списке потоков (см. замечание чуть повыше) }

HProc: DWORD;

{ хэндл процесса, который мы отлаживаем }

Context: TContext;

{ контекст потока. проще говоря - содержание его регистров }

ThreadList: array[0..99] of record Id, Handle: DWORD; end;

{ тот самый пресловутый список потоков, который мы своими ручками будем создавать и поддерживать. в принципе, это должен быть список или динамический массив, ибо количество потоков, которые может создать программа, заранее не известно, но не будем заморачиваться. код-то демонстрационный! }

RetAddr: DWORD;

{ здесь будет храниться адрес возврата из перехваченной API-функции (так, на всякий случай. чтобы вы видели, как и откуда его можно добыть) }

BPAddr: DWORD;

{ в учебных целях мы будем перехватывать только одну функцию. поэтому вместо списка обойдемся просто переменной. здесь будет храниться адрес первого байтика перехваченной функции }

OrigByte: Byte;

{ а здесь будет храниться сам первый байтик }

RestoreBreak: Boolean;

{ флажок, который указывает обработчику события EXCEPTION_SINGLE_STEP надо ли восстанавливать точку останова. весь перехват выглядит так:

нашли стартовый адрес процедуры (это можно сделать просмотром таблицы экспорта у соответствующей DLL-ки. как именно - здесь не пишу. или разбирайтесь сами, или качайте мои исходники - там все есть. не то чтобы мне жалко, но к Debug API это имеет отношение весьма косвенное. опять же, если народ будет очень интересоваться, сделаю статью с quick overview формата PE);

запомнили ее первый байт;

записали вместо первого байта код $CC (это Int3 - DEBUG_EXCEPTION);

по приходу DEBUG_EXCEPTION:

проверили, точно ли мы прервались на адресе нашей точки останова. если нет - не делаем ничего. иначе:

восстановили первый байт;

установили флажок SINGLE_STEP;

установили флажок ResoteBreak;

ожидаем прихода события EXCEPTION_SINGLE_STEP;

по приходу EXCEPTION_SINGLE_STEP:

если установлен флажок RestoreBreak:

вернули на место $CC;

сбросили флажок ResoteBreak; }

ProcessFinished: Boolean;

{ флажок, указывающий, завершился ли отлаживаемый процесс. Sleepyhead говорит, что иногда процесс не завершается корректно (к примеру, отладчик, который отлаживает отладчик, который отлаживает отладчик... [Енота: GNU's not Unix :-)]), поэтому если процесс не завершится сам, мы прибьем его руками }

 

Добавить комментарий

Не использовать не нормативную лексику.

Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.

ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!


Защитный код
Обновить