Просмотр параметров в стеке
В главе 5 показано, как устанавливать точки прерывания на системных и экспортируемых функциях. Одна из главных причин для установки точек прерывания на этих функциях — необходимость просматривать параметры, которые передаются в данную функцию.
С тех пор как Visual Basic 5 позволил получать "родной" код (native code), я хотел посмотреть, как работает "родная" компиляция. Каталог Visual Basic включал файлы LINK.EXE и С2.ЕХЕ. Эти две программы являются также частью Visual C++, и было любопытно посмотреть, как их использует Visual Basic, как вообще работает компиляция. Как можно понять из названия, LINK.EXE связывает объектные файлы и производит выполняемый двоичный файл. С2.ЕХЕ довольно сложен. В системе Visual C++ файл С2.ЕХЕ — это генератор кода, который производит машинный код.
Из интегрированной среды разработки (IDE) Visual C++ я открыл VB6.EXE как программу для отладки. Поскольку были загружены символы, нужно было установить точку прерывания на {,, kernel32}_CreateProcessA@40. Запустив Visual Basic, я создал простой проект, установил свойства 'Проекта для создания "родного" кода и выбрал команду File|Make из IDE Visual Basic. Точка прерывания на _CreateProcessA@4о,обеспечивает управление отладчика при запуске или С2.ЕХЕ, или LINK.EXE.
В Windows 2000 RC2 точка прерывания на _CreateProcessA@40 останавливает отладчик на адресе 0x77E8D7E6, когда инструкция, подлежащая выполнению (PUSH EBP), устанавливает стандартный кадр стека. Поскольку точка останова находится на первой инструкции функции createProcess, вершина стека содержит параметры и адрес возврата. Затем при помощи команды View|Debug Wmdows|Memory я открыл окно Memory и ввел в поле Address строку ESP, которая является именем регистра указателя стека, чтобы просмотреть содержимое стека.
По умолчанию данные в окне Memory отображаются в байтовом формате. Поиск при этом может быть довольно утомительным. Щелчок правой кнопкой мыши в окне Memory позволяет выбрать формат: byte, short hex (2 байта или WORD) и long hex (4 байта или DWORD).
На рис. 6.4 показан стек в окне Memory отладчика в начале точки прерывания на функции CreateProcess. Первое значение — адрес возврата для инструкции OxFB6B3F6J 10 следующих — Параметры фуyrwbb CreateProcess (СМ. табл. 6.5). Параметры функции CreateProcess занимают 40 байт, а каждый параметр имеет длину 4 байта. Стек растет от старших адресов памяти к младшим, а параметры помещаются в стек справа налево, поэтому параметры появляются в окне Memory в том же порядке, как в определении функции.
Рис. 6.4. Стек в окне Memory отладчика Visual C++
Просматривать индивидуальные значения первых двух параметров можно двумя способами. Первый состоит в том, чтобы использовать окно Memory, переключая его в байтовый формат и рассматривая конкретный адрес. Второй, более легкий способ, состоит в том, чтобы буксировать (мышью) адрес, который требуется рассмотреть, в окно Watch. В окне Watch для просмотра адреса следует использовать оператор приведения типов. Например, чтобы просмотреть параметр ipAppiicationName в примере, надо поместить в окно Watch строку <char*)Oxooi2EAC4. Работает любой способ просмотра, и оба должны показать следующие значения:
0х0012ЕАС4 "c:\vb\C2.EXE"
0х0012ЕВС4 "С@ -11 "e:\temp\VB815574
-f "c:\junk\vb\Forml.frm _W 3 _Gy _G5
-GS4096 _dos _Z1
-Fo"c:\junk\vb\Forml.OBJ" _Zi _QIfdiv
-ML _basic"
Таблица 6.5. Параметры, которые VB6.EXE передает В функцию CreateProcess
Значение
|
Тип
|
Параметр
|
0x001 2ЕАС4 |
LPCTSTR |
IpApplicationName |
0x0012EBC4 |
LPTSTR |
IpCommandLine |
0x00000000 |
LPSECURITY_ATTRIBUTES |
IpProcessAttributes |
0x00000000 |
LPSECURITY_ATTRIBUTES |
IpThreadAttributes |
0x00000001 |
BOOL |
blnheritHandles |
0x08000000 |
DWORD |
dwCreationFlags |
0x00000000 |
LPVOID |
IpEnvi r onment |
0x00000000 |
LPCTSTR |
IpCurrentDirectory |
0x001 2EA3C |
LPSTARTUPINFO |
IpStartupInfo |
0x001 2EC60 |
LPPROCESS_INFORMATION |
IpProcessInformation |