지난번 노가다 포스팅에 이어 태화님이 알려주신 깔끔 팁을 정리해 봅니다.
WinDbg는 Debug 메뉴에 Event Filters... 라는 항목이 있습니다.
각종 이벤트들을 디버거가 잡아주도록 하는 설정인데요.
여기에서 Load module을 enable해 놓으면 됩니다.
이렇게 설정해 놓고 드라이버를 로드하면 드라이버 이미지만 메모리에 로드하고 DriverEntry를 실행하기 전에 깔끔하게 브레이크 포인트가 걸립니다.
이 때 콜스택을 보면 아래와 같습니다.
ChildEBP RetAddr Args to Child
f9dffaa4 80528fce f9dffb3c f9dffab8 00000003 nt!DebugService2+0x10
f9dffac8 805a4cea f9dffb3c f9f90000 ffffffff nt!DbgLoadImageSymbols+0x42
f9dffc6c 80577254 f9dffcf0 00000000 00000000 nt!MmLoadSystemImage+0xa34
f9dffd4c 8057765f 00000528 00000001 00000000 nt!IopLoadDriver+0x370
f9dffd74 80535dd0 00000528 00000000 817ba020 nt!IopLoadUnloadDriver+0x45
f9dffdac 805c6a28 f7d18cf4 00000000 00000000 nt!ExpWorkerThread+0x100
f9dffddc 80542fa2 80535cd0 00000001 00000000 nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
여기서 DriverEntry의 주소를 어떻게 찾아야 하나 잠깐 당황했는데요.
DbgLoadImageSymbols()의 인자로 ImageBase가 전달되므로 찾을 수 있습니다.
NTAPI
DbgLoadImageSymbols(
IN PANSI_STRING Name,
IN PVOID Base,
IN ULONG_PTR ProcessId
)
콜스택에서 보이는 인자를 하나씩 확인해 보면
816faf00 "\WINDOWS\System32\Drivers\Null.S"
816faf20 "YS"
kd> lmvm null
start end module name
f9f90000 f9f90b80 Null (deferred)
Image path: Null.SYS
Image name: Null.SYS
...
드라이버 이름에 대한 주소라는 것과 드라이버의 ImageBase 주소라는 것을 확인할 수 있습니다.
ImageBase를 알고 있으므로 !dh 명령으로 EntryPoint를 구합니다.
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (i386)
6 number of sections
3B7D82EB time date stamp Sat Aug 18 05:47:39 2001
...
OPTIONAL HEADER VALUES
10B magic #
7.00 linker version
300 size of code
580 size of initialized data
0 size of uninitialized data
59A address of entry point
300 base of code
ImageBase에 address of entry point를 더해 주면 DriverEntry의 주소가 됩니다.
Null!DriverEntry:
f9f9059a 55 push ebp
f9f9059b 8bec mov ebp,esp
f9f9059d 83ec0c sub esp,0Ch
f9f905a0 56 push esi
깔끔하고 쉽게 구하는 방법이 있었네요. ^^