Еще про отладку WinDbg

Внезапно обнаружил, что уже половина июня прошла незаметно..
У кого-то каникулы-отпуска, а я тут рутиной всякой занимаюсь, и почему-то ее никак не становится меньше.
Приходится заниматься и тем и этим, и всем понемножку. К сожалению, некоторые начатые проекты для плат Марсоход подвисли из-за навалившихся работ.
Сейчас опять занимаюсь отладной / reverse-engineering очередного драйвера. Я уже как-то писал про отладку драйверов. В принципе эта информация не является какой-то уникальной, документации по отладчику WinDbg у самого Microsoft много.

Заметил, что если каким-то инструментом не пользуешься регулярно, то постепенно он забывается. Так и у меня с WinDbg.
В принципе, я знаю как им пользоваться, но приходит время и через пол года опять тратишь 1-2 дня, чтоб какую-то мелочь вспомнить.

Вот решил для самого себя написать памятку.
Простой вопрос: "Как поставить точку останова WinDbg в контексте пользовательского процесса?"

Тут история такая: Windows является многозадачной операционной системой.
В ОС одновременно выполняются множество процессов и потоков.
Причем в некоторый момент времени может оказаться, что интересующий нас процесс вообще не доступен или выгружен из памяти.
То есть, нажмем Ctrl+Break в отладчике WinDbg, Windows остановится, но где мы оказались в настоящий момент времени, во время останова?

С драйверами ядра не так. С драйверами все в некотором смысле проще. Тут выполняешь команду kd> bp mydrv!DriverEntry и точка останова готова. А вот как быть с пользовательским процессом?

  • Первое. Нужно найти среди исполняемых процессов именно тот, который интересует.

Например, меня в настоящий момент интересует, что читает из файла некоторый пользовательский процесс (пусть это будет winlogon.exe). Значит делаю в отладчике Ctrl+Break, что бы прервать Windows и войти в режим команд отладчика.
Команда kd> !process 0 0 выводит список всех работающих процессов. Если знаем имя образа процесса, то можно проще:

 kd> !process 0 0 winlogon.exe
PROCESS ffffe00070ec4900
    SessionId: 2  Cid: 0a28    Peb: 7ff71fbc4000  ParentCid: 09cc
    DirBase: 2fbfc000  ObjectTable: ffffc0003373b240  HandleCount: <Data Not Accessible>
    Image: winlogon.exe

Здесь PROCESS ffffe00070ec4900 - это адрес структуры EPROCESS. Она описывает текущее состояние процесса операционной системы Windows.

  • Второе. Мы знаем, что интересующий нас процесс существует, но он где-то там далеко. Отладчик скорее всего не в контексте нашего процесса. Нужно сменить контекст:

 kd> .process /i ffffe00070ec4900
You need to continue execution (press 'g' <enter>) for the context
to be switched. When the debugger breaks in again, you will be in
the new process context.

И это еще не все. Нужно однократно "отпустить Windows", и когда scheduler Windows переключая процессы дойдет до нашего, отладчик сам остановится уже в контексте нужного процесса. Поэтому, отпускаю Windows:

kd> g

И через секунду получаю в отладчике

Break instruction exception - code 80000003 (first chance)
nt!DbgBreakPointWithStatus:
fffff801`609dcb90 cc              int     3

Это то, что нужно. Теперь я нахожусь в контексте моего процесса.

  • Третье. Теперь можно поставить точку останова уже непосредственно на любую из известных нам функций API Windows прямо в нужном процессе Windows.

kd> bp /p ffffe0007095a900 kernel32!ReadFile

Параметр /p ffffe0007095a900 как раз указывает на EPROCESS нужного процесса. Ну и меня интересует Windows API связанное с чтением из файла, поэтому ReadFile.

Теперь точка останова стоит. Отпускаю Windows из отладчика:

kd> g

Теперь, каждый раз, когда именно этот экземпляр процесса  winlogon.exe что-то будет читать из файла я тут же остановлюсь в отладчике и смогу посмотреть, что же было им прочитано...

 

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