Отладка драйверов под Windows: VirtualBox+WinDbg

Предисловие


Однажды мне понадобилось написать драйвер под Windows XP SP2. Сразу встал вопрос отладки. Уж очень не хотелось использовать мудреный SoftIce, ребутиться при кадждой ошибке или делать откаты. Поэтому было решено использовать виртуалку VirtualBox, которой я частенько пользуюсь и характеристиками которой вполне доволен, и отладчиком Windows Debugger от Microsoft. Через несколько часов в окошке WinDbg радостно замаячили строчки на Си, и было решено сделать «напоминалку», которая получилась неплохим «HowTo». Итак, начнем...

HowTo


1
[Host — машина]

image

Для начала необходимо настроить COM-порт у виртуальной машины.
Для этого выбираем в [Port Mode] [Host Pipe] и пишем имя пайпа(желательно \\.\pipe\com_1).
Далее запускаем «жертву».

2
[Target — машина]

image

Теперь немножко изменим 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 — машина]

image

Создадим «скелет» драйвера — файлы 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 — машина]

image

Теперь сам драйвер 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 — машина]
image

Вспомогательный инклуд — файл struct.h:

typedef struct _ab{
int a,b;
}AB, *PAB;


6
[Target — машина]

image

Теперь заходим в Мой Компьютер -> Свойства -> Дополнительно -> Переменные среды и добавляем три переменные:
DBG_SYM_PATH- Путь к папке, куда будут помещаться файлы символов*
DBG_SRC_PATH — Путь к папке, куда будут помещаться с кодом**
DDK_PATH — Путь к DDK
**+* = В свою очередь эти папки должны располагаться на предварительно созданном диске для шары.

7
[Target — машина]

image

Теперь можно начинать стройку — делаем дабл-клик по make.bat, и если все предварительно прошло нормально, то должно появиться окно с содержимым подобному верхнему и несколько дополнительных файлов в каталоге с драйвером.

8
[Host — машина]

image

Пропишем в отладчике пути к папкам с символами и файлами кода(они должны располагаться в папке с шарой)

9
[Host — машина]

image

Собственно вписываем в Port \\.\pipe\com_1 запускаем дебаг(отладчик будет писать что он не пашет, но это означает, что он просто ждет на target-машине прерывания или еще какого-нибудь события.

10
[Target — машина]

image

Качайте набор программ [KmdKit] для работы с всякой kernel и не только утварью по ссылке KmdKit и запускайте KmdManager(который в папке tools) — программу для инсталляции/запуска/остановки/деинсталляции драйвера.
После запуска пропишите путь к драйверу(можно просто перетащить мышкой) и нажмите register+run — система тут же зависнет — так и должно быть, ведь отладчик перехватил прерывание и остановил всю систему. Переходите в хост — машину и смотрите следующий пункт.

11
[Host — машина]

image

Отладчик всплыл и появилось то, что сверху(если не появилось то надо чуть подождать).
Делаем шаги — жмем F10, пока не дойдем до конца программы и в конце в окне «Command-Kenel» набираем g и жмем ентер. После нажатия g система уйдет в свободное плавание и target — система разблокируется.
Переходим в taget-систему и в следующий пункт.

12
[Target — машина]

image

Нажимаем Stop — Unregister.

Если все прошло так, как я писал, значит у вас получилось. Если нет, то задавайте вопросы. Надеюсь, эта информация была полезной.

Спасибо за внимание.
Поделиться публикацией
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 11
  • +1
    В прошлый раз, когда надо было отлаживать драйвер — так и не удалось запустить такую схему. Пришлось довольствоваться DBG_PRINT'ами… Спасибо!
    • +3
      Жал что про VirtualKD, которая значительно ускоряет скорость отладки нет ни слова!
      • 0
        +1 ТС нужно попробовать VirtualKD — это отличное дополнение к VS для отладки драйверов в VBox'е.
        • +1
          Про VirtualKD напишу чуть позже.
        • 0
          Не просто увеличивает скорость отладки, а увеличивает ее в раз так 15!
          + существенно упрощает процедуру настроки.
          http://virtualkd.sysprogs.org
        • 0
          Одна беда: WinDbg — неудобен :-(
          • +1
            Есть такое, но для программиста куда важнее иметь корректно работающий функционал, чем удобную и красивую, но плохо работающую. Хотя не отрицаю было бы куда лучше если и то и другое в одном наборе. Но не думаю, что сиспрограммеры из MS хорошие Usability-дизайнеры.
            • 0
              Неплохие, я бы сказал. Тот же отладчик VS (хотя бы даже 6-ки) — удобный и хороший инструмент, если есть сорцы.
              • 0
                А вы видели их WLK? После тестирования драйверов у меня язык не поворачивается плохого слова про iTunes сказать.
        • +1
          Код после слов: «Теперь сам драйвер driver.cpp, сверху основной код:» слишком много занимает места на экране. Вы применили тег код? Если вдруг забыли, то обрамите с настройкой «cpp»

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

          Самое читаемое