2009-06-25

Отладка драйвера в Windbg

Во время отладки драйвера с помощью vmware и Windbg часто возникает необходимость остановиться на точке входа драйвера. Если драйвер наш, и нам доступны исходники, можно просто добавить int 3 в код и перекомпилировать драйвер, но что делать если исходные коды не доступны?

Можно конечно вписать 0xCC в нужное место с помощью хексредактора, но тут есть ряд неудобств. Во-первых, нужно будет востанавливать оригинальный байт, а во-вторых у меня драйвер с изменённым байтом отказался загружаться, наверно нужно исправить контрольную сумму в заголовке? Дополнительная трата времени... Но можно поступить иначе.

Дизассемблируем ntkrnlpa.exe (или ntoskrnl.exe), находим там неэкспортируемую функцию IopLoadDriver, запоминаем/записываем адресс. В моём случае - 0049DEE4.

Прокручиваем листинг вниз, ищем примерно такой код:
PAGE:0049E546 0C4                 push    [ebp+Object]
PAGE:0049E54C 0C8 push edi
PAGE:0049E54D 0CC call dword ptr [edi+2Ch]
PAGE:0049E550 0C4 cmp eax, ebx
PAGE:0049E552 0C4 mov ecx, [ebp+var_98]
PAGE:0049E558 0C4 mov [ebp+var_54], eax
PAGE:0049E55B 0C4 mov [ecx], eax
PAGE:0049E55D 0C4 jge short loc_49E566
PAGE:0049E55F 0C4 mov [ebp+var_54], 0C0000365h

call dword ptr [edi+2Ch] - это переход на точку входа в загружаемого драйвера, значит находим смещение этого кода относительно начала функции IopCallDriver. В моём сулучае: 0x0049E54D - 0x0049DEE4 = 0x669. И ставим в windbg точку останова:
bp IopLoadDriver+0x669

Когда windbg останавливаеться на этой точке - нажимаем F11, и попадаем на EP драйвера =)
Конечно подразумеваеться что установленны корректные отладочне символы.

Вместо выполнения "сложных" арифметических операций (0x0049E54D - 0x0049DEE4 = 0x669) можно пойти в Options -> General -> Disassembly и поставить галочку "Function Offsets", тогда IDA выдаст что-то такое:
IopLoadDriver(x,x,x,x)+662  0C4                 push    [ebp+Object]
IopLoadDriver(x,x,x,x)+668 0C8 push edi
IopLoadDriver(x,x,x,x)+669 0CC call dword ptr [edi+2Ch]
IopLoadDriver(x,x,x,x)+66C 0C4 cmp eax, ebx
IopLoadDriver(x,x,x,x)+66E 0C4 mov ecx, [ebp+var_98]
IopLoadDriver(x,x,x,x)+674 0C4 mov [ebp+var_54], eax
IopLoadDriver(x,x,x,x)+677 0C4 mov [ecx], eax
IopLoadDriver(x,x,x,x)+679 0C4 jge short loc_49E566
IopLoadDriver(x,x,x,x)+67B 0C4 mov [ebp+var_54], 0C0000365h

Архив