Отладка драйверов под Windows: VirtualBox+WinDbg
Однажды мне понадобилось написать драйвер под Windows XP SP2. Сразу встал вопрос отладки. Уж очень не хотелось использовать мудреный SoftIce, ребутиться при кадждой ошибке или делать откаты. Поэтому было решено использовать виртуалку VirtualBox, которой я частенько пользуюсь и характеристиками которой вполне доволен, и отладчиком Windows Debugger от Microsoft. Через несколько часов в окошке WinDbg радостно замаячили строчки на Си, и было решено сделать «напоминалку», которая получилась неплохим «HowTo». Итак, начнем…
HowTo
1 [Host — машина]
Для начала необходимо настроить COM-порт у виртуальной машины.
Для этого выбираем в [Port Mode] [Host Pipe] и пишем имя пайпа(желательно \\.\pipe\com_1).
Далее запускаем «жертву».
2 [Target — машина]
Теперь немножко изменим boot.ini. Изначало в нем было только то, что не выделено(на картинке).
Добавим новую строку путем копирования первой и добавления нескольких строчек как на картинке.
Если не видно — изменяем строчку типа multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=«Microsoft Windows XP Professional RU» /noexecute=optin /fastdetect так:
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=«Microsoft Windows XP Professional RU» /fastdetect /debug /debugport=com1 /baudrate=115200
Перегружаемся и выбираем из 2ух пунктов вариант где в квадратных в конце скобочках стоит что-то типа «with debugger» или «С отладчиком».
3 [Target — машина]
Создадим «скелет» драйвера — файлы make.bat, SOURCES и MAKEFILE:
%SystemRoot%\system32\cmd.exe /c "cd %DDK_PATH%\bin\&&setenv.bat %DDK_PATH%\&&cd E:\vbg\debug\&&build -ceZ"
copy bin\i386\*.pdb %DBG_SYM_PATH%
copy *.c %DBG_SRC_PATH%
copy *.cpp %DBG_SRC_PATH%
copy *.h %DBG_SRC_PATH%
copy *.hpp %DBG_SRC_PATH%
pause
(вместо E:\vbg\debug\ впишите имя папки, где находится ваш драйвер)
TARGETNAME=driver
TARGETPATH=bin
TARGETTYPE=DRIVER
C_DEFINES=$(C_DEFINES)
INCLUDES=C:\WINDDK\2600\inc
SOURCES=driver.cpp
RELEASETYPE=DDK!INCLUDE $(NTMAKEENV)\makefile.def
4 [Target — машина]
Теперь сам драйвер driver.cpp, сверху основной код:
extern "C"{ #include "ntddk.h" } #include "struct.h" VOID OnUnload(IN PDRIVER_OBJECT DriverObject){ DbgPrint("OnUnload called\n"); }; extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,IN PUNICODE_STRING theRegistryPath){ AB v = {2,3}; PAB pv = &v; _asm int 3 ; v.a++; pv->b++; DbgPrint("a = %d, b = %d\n",v.a,v.b); theDriverObject->DriverUnload=&OnUnload; return STATUS_SUCCESS; }
Этот драйвер вызывает отладчик прерыванием int 3.
5 [Target — машина]
Вспомогательный инклуд — файл struct.h:
typedef struct _ab{
int a,b;
}AB, *PAB;
6 [Target — машина]
Теперь заходим в Мой Компьютер -> Свойства -> Дополнительно -> Переменные среды и добавляем три переменные:
DBG_SYM_PATH- Путь к папке, куда будут помещаться файлы символов*
DBG_SRC_PATH — Путь к папке, куда будут помещаться с кодом**
DDK_PATH — Путь к DDK
**+* = В свою очередь эти папки должны располагаться на предварительно созданном диске для шары.
7 [Target — машина]
Теперь можно начинать стройку — делаем дабл-клик по make.bat, и если все предварительно прошло нормально, то должно появиться окно с содержимым подобному верхнему и несколько дополнительных файлов в каталоге с драйвером.
8 [Host — машина]
Пропишем в отладчике пути к папкам с символами и файлами кода(они должны располагаться в папке с шарой)
9 [Host — машина]
Собственно вписываем в Port \\.\pipe\com_1 запускаем дебаг(отладчик будет писать что он не пашет, но это означает, что он просто ждет на target-машине прерывания или еще какого-нибудь события.
10 [Target — машина]
Качайте набор программ [KmdKit] для работы с всякой kernel и не только утварью по ссылке KmdKit и запускайте KmdManager(который в папке tools) — программу для инсталляции/запуска/остановки/деинсталляции драйвера.
После запуска пропишите путь к драйверу(можно просто перетащить мышкой) и нажмите register+run — система тут же зависнет — так и должно быть, ведь отладчик перехватил прерывание и остановил всю систему. Переходите в хост — машину и смотрите следующий пункт.
11 [Host — машина]
Отладчик всплыл и появилось то, что сверху(если не появилось то надо чуть подождать).
Делаем шаги — жмем F10, пока не дойдем до конца программы и в конце в окне «Command-Kenel» набираем g и жмем ентер. После нажатия g система уйдет в свободное плавание и target — система разблокируется.
Переходим в taget-систему и в следующий пункт.
12 [Target — машина]
Нажимаем Stop — Unregister.
Если все прошло так, как я писал, значит у вас получилось.