Останов на точке входа приложения в WinDbg

Метки:  ,

Как то раз столкнулся с интересной проблемой при открытии исполняемого файла в WinDbg на отладку. Для опытного реверсера ситуация, скорее всего, достаточно тривиальная, тем не менее с ней из раза в раз сталкиваются те, кто впервые пытается отладить типовой исполняемый модуль (.exe) при помощи отладчика WinDbg. Заключается она в том, что совершенно непонятно как поставить точку останова на непосредственно в точку входа, то есть на первую инструкцию (основной функции) отлаживаемого исполняемого файла. Обычно для отладки приложение открывается через меню File - Open Executable... (или просто нажатием комбинации клавиш Ctrl+E). По умолчанию, после загрузки исполняемого файла, отладчик останавливается задолго до начала непосредственно кода самой программы, где-то глубоко в коде загрузчика образов Windows. Вот типичный пример:

Отладчик "встает" на инструкции int 3 (программная точка останова) в глубине функции LdrpDoDebuggerBreak. Начиная выполнять пошаговую отладку (при помощи клавиш F10 или F11), в конечном итоге, проходим по всей логике загрузчика образов и управление передается на код программы. При таком подходе тратится драгоценное время, на ненужные, в большинстве случаев, действия. Зачем нам это всё нужно и как сразу сделать останов на точке входа приложения?

Метод 1: совсем простой

Если ваш отладчик WinDbg ведет себя подобным образом, нам потребуется выполнить серию дополнительных действий. Для того, что бы попасть непосредственно в точку входа программы, необходимо при срабатывании точки останова (в загрузчике образов) выполнить серию команд:

bp @$exentry
g

либо такую вот серию:

bu @$exentry
g

В итоге, после того, как мы продолжим выполнение при помощи команды g, отладчик встанет на первой инструкции, размещающейся в точке входа исполняемого модуля.

Метод 2: чуть сложнее

Получаем содержимое структуры PEB (Блок окружения процесса, Process Environment Block) командой:

В данном выводе нас интересует содержимое члена ImageBaseAddress, который определяет базовый адрес загрузки кодового сегмента образа в виртуальное пространство процесса.
Затем выводим дамп заголовка:

В данном выводе получаем адрес точки входа (address of entry point), который в нашем случае равен значению 4F25. Соответственно, актуальный стартовый адрес равен сумме ImageBaseAddress и полученного только что address of entry point. В нашем примере получается: 00400000 + 4F25. Проверим правильность вычислений, дизассемблируя блок по данному адресу:

как мы видим, первая команда изучаемого исполняемого файла у нас соответствует той команде, которую мы видели при использовании метода №1, что подтверждает правильность вычислений. Теперь мы можем выставить точку останова на данный адрес командой:

bp 00400000+4F25

и продолжить выполнение программы:

g

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *