Использование информационных команд
SoftIce имеет в своем распоряжении много разных команд, с помощью которых можно узнать состояние и получить иную информацию об операционной системе и запущенных в ней приложениях. Мы рассмотрим только две команды: H (Help) и CLASS. Эти команды выводят достаточно много информации в окне команд (Command Window), поэтому желательно увеличить размер этого окна, для этого закроем окно локальных переменных (Locals Window).
По команда H можно получить помощь по всем командам SoftIce или более подробную информацию о конкретной команде, если введете ее имя в качестве аргумента команды H:
:H CLASS Display window class information CLASS [-x] [task-name] Ex: CLASS USERПервая строка дает описание команды, вторая показывает информацию о синтаксисе и аргументах, которые могут использоваться в команде, третья строка содержит пример использования команды.
Целью выполнения функции RegisterAppClass является регистрация шаблона для классов окон, которые будут использованы приложением GdiDemo для создания окон. Используя команду CLASS можно посмотреть зарегистрированные классы для GdiDemo:
Результатом выполнения данной команды является информация о каждом зарегистрированном классе окна. Информация включает в себя: имя класса, адрес внутренней структуры данных WNDCLASS, модуль который зарегистрировал данный класс, адрес процедуры, которая обслуживает данный класс и состояние флагов стиля класса. Для получения подробной информации воспользуйтесь ключом -X.
Handle Class Name Owner WndwProc Styles --------------------------Application Private------------------------------- 5110 ??? GDIDEMO 2E9F:00000114 07000003 40AC ??? GDIDEMO 2E9F:000000FE 07000003 409C ??? GDIDEMO 2E9F:000000E8 03000003 3BC4 ??? GDIDEMO 2E9F:000000D2 03000003 3BB4 ??? GDIDEMO 2E9F:000000BC 07000003 3A00 ??? GDIDEMO 2E9F:000000A6 07000003Символьные имена
Когда вы загружаете приложение с отладочной информацией, SoftIce автоматически создает таблицу символьных имен которая содержит все имена, определенные в данном приложении. Используя команду TABLE можно посмотреть какие таблицы символьных имен загружены в настоящий момент:
:TABLE GDIDEMO [NM32] 0001044741 Bytes Of Symbol Memory AvailableИспользуемая в данный момент таблица символьных имен выделена цветом. Если текущая таблица символьных имен не соответствует той на которую ссылается ваше приложение, то используя команду TABLE с именем вашего приложения в качестве аргумента, вы подключите нужную таблицу (если для вашего приложения создана таблица):
Используя команду SYM вы можете посмотреть все символьные имена, определенные в текущей таблице (на экран выводятся по сегментам, внутри них в алфавитном порядке). Если интересует какие-то определенные имена, то используйте шаблоны:
:SYM w* .text (0137:00401000, 000145C1 bytes) 0137:004012E0 WinMain 0137:00405700 WinMainCRTStartup 0137:004013AD WndProc 0137:0040AF50 wcslen 0137:0040C160 wcsncnt 0137:004107A0 wctomb 0137:0040FA50 write_char 0137:0040FAD0 write_multi_char 0137:0040FB20 write_stringНа экране список всех символьных имен начинающихся с буквы w, все они расположены в сегменте .text (выполняемый сегмент, он начинается с адреса 0137:00401000 и имеет длину 0145C1H байт), т.е. эти имена - имена функций и процедур входящие в приложение GDIDEMO. Данные находятся в сегментах .data, .rdata, .idata.
Условные точки останова
Одним из символов, определенных в приложении GDIDEMO, является функция LockWindowInfo. Назначение этой функции - возвращение адреса переменных, которые определяют свойства окна. Для того чтобы ознакомиться с условными точками останова и точками останова на доступ к памяти, мы выполним следующие действий:
· Установим точку останова на функцию LockWindowInfo.
· Отредактируем поставленную точку останова таким образом, чтобы она срабатывала по определенному нами условию.
· Установим точку останова на доступ к ячейки памяти, для того чтобы отследить обращения к этой ячейке.
Установка точки останова на функцию LockWindowInfo.
Командой BPX LockWindowInfo поставим точку останова на выполнение на эту функцию. Каждый раз, когда в одном из окон приложения GDIDEMO нужно будет обновить информацию, программой будет вызываться функция LockWindowInfo, так как на эту функцию поставлена точка останова, то будет вызываться SoftIce. Командой BL проверьте, установилась ли точка останова. Запустите приложение командой X или G. Как только будет вызвана функция LockWindowInfo, SoftIce всплывет. Так как обновление происходит постоянно, то постоянно вызывается и SoftIce, что очень неудобно, если нас интересует обновление какого-либо конкретного окна. Чтобы перехватить вызов на обновление конкретного окна, к примеру, POLYDEMO, воспользуемся условной точкой останова. Из исходного текста программы (файл wininfo.c) видно, что функция LockWindowInfo получает в качестве входного аргумента один параметр HWND (Handle Window) - дескриптор окна, и возвращает в вызывающую функцию одно значение - указатель на переменные для данного окна. То есть если бы мы заставили срабатывать точку останова только на обработчик окна POLYDEMO, мы бы добились своей цели. Для начала нам необходимо узнать дескриптор нашего окна, для этого воспользуемся командой:
:HWND GDIDEMO WindowHandle hQueue SZ Qowner ClassName WindowProcedure 0724(1) 10FF 32 GDIDEMO GDIDEMO 365F:000001C4 0728(2) 10FF 32 GDIDEMO MdiClient 17A7:00001988 0734(3) 10FF 32 GDIDEMO BOUNCEDEMO 365F:00000232 0730(3) 10FF 32 GDIDEMO POLYDEMO 365F:000001DA 072C(3) 10FF 32 GDIDEMO DRAWEMO 365F:0000021cДескриптор окна POLYDEMO имеет значение 0730. Если в списке вы не увидели нужного окна, то запустите приложение клавишей X или G, опять сработает точка останова, проверьте, создалось ли окно, если нет, то повторите последние действия. Теперь можно останавливать исполнение программы только в том случае, когда в качестве параметра для функции LockWindowInfo используется значение 0730. В Windows параметры для функции обычно передаются через стек. При остановке в функции LockWindowInfo стек будет выглядеть следующим образом (посмотреть содержимое стека можно подведя курсор к регистру ESP, нажав правую кнопку мыши, вызвать контекстное меню и выбрать команду Display, неплохо бы еще сменить командой DD формат вывода данных в DataWindow на показ двойных слов, так как наше приложение 32-разрядное):
ESP = 0055FC00 013F:0055FC00 00404852 00000730 0055FC3C 00008CAA· Число 00404852 - это адрес, на который программа перейдет после завершения работы нашей функции (адрес возврата).
· Число 00000730 - это дескриптор окна POLYDEMO (собственно то, что нас интересует).
Теперь зная, где и что у нас передается в функцию, мы можем выставить условную точку останова. Для этого вызовем на редактирование точку останова, поставленную на функции LockWindowInfo:
:BPE 0В нижней строке командного окна появится строка:
:BPX LockWindowInfoи курсор установится в конце строки. Теперь можете редактировать точку останова по своему усмотрению, в конце строки добавьте следующее условие:
IF ESP->4 == 00000730и нажмите Enter.
Точка останова теперь будет выглядеть так:
:BPX LockWindowInfo IF ESP->4 == 00000730То есть она будет срабатывать тогда, когда двойное слово по адресу ESP+4 будет равным числу 00000730, которое соответствует дескриптору окна POLYDEMO. Проверьте командой BL, соответствует ли точка останова заданной, запустите приложение и убедитесь, что вся эта конструкция замечательно работает.
Установим точку останова на доступ к первому двойному слову данных экземпляра окна POLYWINDOW. Как уже отмечалось выше, входным аргументом для функции LockWindowInfo является дескриптор окна, выходным - адрес данных экземпляра окна. После срабатывания точки останова, поставленной на функции LockWindowInfo с параметром соответствующим дескриптору окна POLYWINDOW, на выходе функции будем иметь адрес данных экземпляра окна POLYWINDOW, по этому адресу и поставим точку останова на доступ к памяти.
Для того чтобы получить адрес данных экземпляра окна, выполним программу до строки с номером 57 (в файле WININFO.C):
:G .57Функция возвращает 32-битное значение (в нашем случае адрес) в регистре EAX, поэтому можно, используя команду BPMD (BreakPoint Memory Dword) и значение адреса в регистре EAX, поставить точку останова на доступ к первом слову данных экземляра окна POLYDEMO:
:BPMD EAXЭта команда использует регистры аппаратной отладки встроенные в процессор для отслеживания чтения и записи двойного слова по указанному линейному адресу. В данном случае это первое слово данных экземпляра окна POLYDEMO. Используйте команду BL, чтобы проверить правильность установки точки останова.
:BL 00) BPX LOCKWINDOWINFO IF ((ESP->4)==0x00000730) 01) BPMD #015F:0052006C RW DR3Точка останова с номером 0 установлена на исполнение функции LockWindowInfo и точка останова с номером 1 стоит на доступ к памяти по адресу #015F:0052006C.
Отключите 0 точку останова командой BD (Breakpoint Disable):
:BD 0В отличие от команды BC, которая удаляет точку останова, команда BD временно отключает точку, т.е. она не будет срабатывать, но ее в любой момент можно включить обратно командой BE (Breakpoint Enable). Отключенные точки останова выделяются звездочками рядом с порядковым номером точки останова.
:BL 00) * BPX LOCKWINDOWINFO IF ((ESP->4)==0x00000730) 01) BPMD #015F:0052006C RW DR3Запустите SoftIce командами X или G, когда окно POLYDEMO попытается получить доступ к первому двойному слову экземпляра данных окна, сработает точка останова и SoftIce всплывет, это будет происходить в функциях PolyRedraw и PolyDrawBez. Эти функции обращаются к полю nBezTotal, которое находиться по нулевому смещению в данных экземпляра окна POLYDEMO. Значение этого поля задает количество кривых одновременно выводимых в окно POLYDEMO.
Примечание: Из-за особенностей архитектуры процессоров Intel перехват обращения к ячейки памяти произойдет после исполнения команды, обращающейся к памяти, т.е. SoftIce остановиться на следующей команде.
Сбросьте все точки останова командой BC * и выйдете из SoftIce.
Как заставить SoftIce pаботать?
Config.Sys: Device=c:\...\...\S-Ice.Exe
Затем запускаете Ldr.Exe <пpограмма>. У MS-DOS есть маленький баг: он неверно выставляет значение регистра SP - он уменьшает его значения на 2, и некоторые защиты, активно использующие стек заставляют повеситься задачу. Лечится правкой кода MS-DOS при загрузке INT 21h AX=4B01h или командой "R SP=SP+2"
Как заставить SoftIce/Win/W95 pаботать?
Отредактировать файл WINICE.DAT, дать возможность грузить отладчику символьную информацию из системных DLL-ей. (В Winice.DAT даются ссылки на USER.EXE, KRNL386.EXE, WIN386.EXE)
exp=c:\win\system\user.exe exp=c:\win\system\gdi.exe exp=c:\win\system\krnl386.exehttp://protect.htmlweb.ru/