Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Введение в режимы трассировки SoftICE
Автор: Fox Mulder

Из открытий компьютерной вирусологии:
Oказывается, первый троян был конь!

Сегодня продолжаем учиться использовать SoftICE. Каждый исследователь программ должен уметь трассировать программы.

Трассировкой мы будем называть процесс пошагового выполнения программы. Под шагом программы обычно понимается выполнение одной команды, но здесь есть некоторые тонкости, которые как раз связаны с режимами трассировки.

В SoftICE существует два режима трассировки: внутренний и внешний.

  • внутренний - такой режим, когда по шагам выполняются все команды этой функции
  • внешний - когда все команды функции выполняются за один шаг.

Давайте рассмотрим оба этих режима на примерах. В качестве исследуемой программы будем использовать уже знакомый нам WinZip 7.0. Но перед тем, как начать хотел бы обратить Ваше внимание вот на какую деталь: многие из Вас при работе с SoftICE используют Symbol Loader для загрузки программ. Так вот, делать этого не нужно - Symbol Loader предназначен для использования программистами, которые отлаживают свои программы. Для нас с Вами она практически бесполезна. Тогда у Вас может возникнуть вопрос: а как же загружать программу? Просто запускайте ее как обычно из меню Пуск и дальше работайте. Дело в том, что SoftICE запускается еще до загрузки Windows и Вы в любой момент можете его активизировать нажатием Ctrl+D, вне зависимости от того, загружали ли Вы программу через Symbol Loader или нет.

Запускаем WinZip, выбираем в меню Help пункт About WinZip... Появляется окно с информацией о WinZip. Далее активизируем SoftICE (Ctrl+D) и устанавливаем точку прерывания на вызов функции EndDialog(). Эта функция вызывается при закрытии диалогового окна (разговор о диалоговых окнах у нас впереди, но чтобы Вы представляли, что это такое, посмотрите на окно About WinZip - это типичный пример диалогового окна). При нажатии на кнопку ОК программа прерывается при вызове функции EndDialog(). Обратите внимание на надпись на самой нижней желтой линии: USER32 - она означает, что мы находимся не в модуле нашей программы (WINZIP32), а в модуле, в который загружена библиотека user32.dll Далее нажимаем F12, чтобы программа прервалась после выполнения команды ret и оказываемся в модуле нашей программы WINZIP32 по адресу 4013A0. Нам надо посмотреть текст программы немного выше этого адреса.

Для скроллирования (прокручивания) текста в окнах SoftICE служат стрелочки, расположенные с правой стороны окна. Существует два вида стрелочек: первые, похожие на треугольники, предназначены для прокрутки текста по одной стоке, другие, выглядящие как нормальные стрелки - для прокрутки текста постранично. Несколько раз нажимаем на верхнюю стрелочку для прокрутки текста построчно, пока не увидим строку 401397. После этого делаем двойной щелчок мышью по этой строке (в любом ее месте). Двойной щелчок по строке эквивалентен установке точки прерывания на выполнение команды по этому адресу. В нашем случае случае устанавливается точка прерывания на выполнение команды по адресу 401397 (эквивалентом двойного щелчка в данном случае будет команда bpx 401397, но работать мышью гораздо удобнее). Строка, на которую установлена точка прерывания выделяется зеленым цветом. Удалить установленную точку прерывания можно сделав на ней двойной щелчок еще раз.

Теперь давайте посмотрим какие точки прерывания у нас установлены. Список установленных точек прерывания выдается по команде bl (breakpoint list). У нас установлены две точки прерывания поэтому список будет иметь следующий вид:


00) bpx USER32!EndDialog
01) bpx #0137:00401397

Слева выводится номер установленной точки прерывания. 0 - это точка прерывания на выполнение API-функции EndDialog(), 1 - точка прерывания на выполнение команды по адресу 401397. С точками прерывания можно производить следующие действия: отключать установленные, включать выключенные точки прерывания, редактировать и удалять.

Давайте попробуем отключить точку прерывания на вызов функции EndDialog(). Для отключения точки прерывания используется команда bd (breakpoint disable), после которой необходимо указать ее номер (в нашем случае - 0), т.е. вводим команду bd 0. Убедиться в том, что точка прерывания действительно отключена мы можем с помощью команды bl. Вводим bl и получаем следующий список установленных точек прерывания:


00)*bpx USER32!EndDialog
01) bpx #0137:00401397

Обратите внимание, что в нулевой строке появилась звездочка. Этот символ означает, что точка прерывания отключена.

Для чего используют отключение точек прерывания? Рассмотрим на нашем примере. Сначала нам была нужна точка прерывания на вызов функции EndDialog(), но после того, как мы нашли, в каком месте программы она вызывается такая необходимость пропала. В принципе, можно эту точку прерывания удалить, но если Вы думаете, что она может Вам еще понадобиться через некоторое время, но до этого не должна функционировать, то лучше ее отключить. Это избавит Вас от траты времени на повторную установку этой точки прерывания в будущем.

Для продолжения выполнения программы нажимаем F5. Вновь выбираем в меню Help пункт About WinZip... Нажимаем кнопку ОК - программа прерывается при выполнении команды по адресу 401397 (об этом сообщается в окне команд SoftICE).

Попробуем выполнить внешнюю трассировку участка программы. Для внешней трассировки используется команда p(горячая клавиша F10). После первого нажатия F10 курсор перемещается на следующую строку 401399 - выполнилась команда push 01. При втором нажатии F10 выполняется команда push ebx и курсор устанавливается на строке 40139A. В этой строке выполняется вызов API-функции EndDialog(). После нажатия F10 курсор перемещается на следующую строку 4013A0, т.е. вся функция EndDialog() выполняется как одна команда. Это удобно, когда не важно, что происходит внутри функции, а время трассировки хотелось бы сократить.

Если же Вам необходимо знать, что происходит внутри функции, то тогда Вам необходимо использовать внутреннюю трассировку. Внутренняя трассировка выполняется командой t (горячая клавиша F8).

Для продолжения программы нажимаем F5, далее вновь выбираем questions/About Winzip... Программа прерывается по адресу 401397. Два раза нажимаем F8 (команды push в обоих режимах выполняются совершенно одинаково) и оказываемся вновь в стоке 40139A. После нажатия F8 курсор оказывается не на следующей строке, как в предыдущем режиме, а в начале функции EndDialog() в модуле USER32 (адрес BFF61ABE). При нажатия F8 выполняется команда mov cl, 9Ah и курсор перемещается на следующую строку, т.е. Вы можете выполнять трассировку функции. Если функция достаточно длинная, а Вы уже узнали все, что хотели и не желаете бесцельно трассировать ее до конца, можете воспользоваться командой p ret (горячая клавиша F12) которая прерывает программу после выполнения команды ret (команда возврата из функции). Нажмите F12 и программа прервется по знакомому нам уже адресу 4013A0, сразу после вызова функции EndDialog().

Надеюсь, все что я написал Вам понятно.

Проект Delphi World © Выпуск 2002 - 2024
Автор проекта: USU Software
Вы можете выкупить этот проект.