Search
๐ŸชŸ

How to debugging a Kernel Driver

Date
Select
Tags

1. Introduce

ํ•ด๋‹น ํฌ์ŠคํŒ…์€ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๋””๋ฒ„๊น… ํ•  ๋•Œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ํฌ์ŠคํŒ…์ž…๋‹ˆ๋‹ค.
this posting describe how to debugging a kernel driver in a windbg.

1.1 Testbed

Host: Windows 10 19041.1052 and VirtualKD Guest: Windows 10 19041.985 and VirtualKD Debugger: Windbg

2. Why we debugging a kernel driver?

๋Œ€๋ถ€๋ถ„์˜ ๊ฒŒ์ž„ ํ•ต๊ณผ ์•ˆํ‹ฐ์น˜ํŠธ ์†”๋ฃจ์…˜์€ ์ปค๋„ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Most of a gamehack and anti-cheat solution are run with a kernel driver.
๊ฒŒ์ž„ํ•ต์„ ๋ง‰๊ณ  ์•ˆํ‹ฐ ์น˜ํŠธ ์†”๋ฃจ์…˜์„ ์—ฐ๊ตฌ ๋ฐ ๊ฐœ๋ฐœํ•˜๋ ค๋ฉด ์ปค๋„ ๋“œ๋ผ์ด๋ฒ„์— ๋Œ€ํ•œ ์ง€์‹์€ ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค. Knowledge of a kernel driver is necessary for prevent a gamehack and research anti-cheat solution.

3. How to debugging a Kenrel Driver

ํ•ด๋‹น ํฌ์ŠคํŒ…์—์„œ๋Š” ๋‘๊ฐ€์ง€์˜ ์ปค๋„ ๋””๋ฒ„๊น… ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. This posting describe a two way about kernel driver debugging in a windbg.

3.1 Set Exception Command

windbg์˜ Set Exception Command๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ๋“œ๋ผ์ด๋ฒ„ ๋กœ๋“œ ์‹œ์ ๋ถ€ํ„ฐ ๋””๋ฒ„๊น…์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. you can use the sxe command to debug when the driver is loaded
// sxe ld "DriverName.sys" 0: kd> sxe ld debugging.sys 0: kd> g
C
๋ณต์‚ฌ
ํ•ด๋‹น ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๋กœ๋“œํ•˜๋ฉด Exception์ด ๋ฐœ์ƒํ•˜๋ฉฐ, DriverEntry์— Breakpoint๋ฅผ Set ํ•˜๊ณ  ๋””๋ฒ„๊น…์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. When the driver is loaded, an Exception occurs, and sets a breakpoint to the DriverEntry and start debugging.
nt!DebugService2+0x5: fffff802`44e13be5 cc int 3 1: kd> lm start end module name 00007ffc`96650000 00007ffc`96682000 vertdll (deferred) 00007ffc`96690000 00007ffc`96885000 ntdll T (no symbols) fffff802`44560000 fffff802`447ef000 mcupdate_GenuineIntel (deferred) ... fffff802`4a1c0000 fffff802`4a1c7000 Debugging (deferred) ... 1: kd> bp Debugging!DriverEntry 1: kd> g Breakpoint 0 hit Debugging!DriverEntry: fffff802`4a1c1000 4053 push rbx
C
๋ณต์‚ฌ

3.2 PnpCallDriverEntry BreakPoint

๋“œ๋ผ์ด๋ฒ„ ๋กœ๋“œ ๋ฃจํ‹ด์—์„œ ํ˜ธ์ถœ๋˜๋Š” PnpCallDriverEntry ํ•จ์ˆ˜์— BreakPoint๋ฅผ ์„ค์ •ํ•ด ๋””๋ฒ„๊น… ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. and you can debug other way, sets a breakpoint to the PnpCallDriverEntry Function in a driverload routine
ํ•ด๋‹น ๋ฐฉ๋ฒ•์€ Driver ์‹ฌ๋ณผ์ด ์—†๊ฑฐ๋‚˜, ํŒจํ‚น๋œ ๋“œ๋ผ์ด๋ฒ„์— ์ฃผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. The method is mainly used when you don't have a driver symbol or you wanna debug a packed driver
0: kd> bp pnpcalldriverentry 0: kd> bl 0 e Disable Clear fffff805`7f375f00 0001 (0001) nt!PnpCallDriverEntry 0: kd> g Breakpoint 0 hit nt!PnpCallDriverEntry: fffff805`7f375f00 4c8bdc mov r11,rsp 1: kd> kn # Child-SP RetAddr Call Site 00 ffff8185`31ca0958 fffff805`7f3421f5 nt!PnpCallDriverEntry 01 ffff8185`31ca0960 fffff805`7f386cc7 nt!IopLoadDriver+0x4e5 02 ffff8185`31ca0b30 fffff805`7ef5a225 nt!IopLoadUnloadDriver+0x57 03 ffff8185`31ca0b70 fffff805`7ef0e3b5 nt!ExpWorkerThread+0x105 04 ffff8185`31ca0c10 fffff805`7f017348 nt!PspSystemThreadStartup+0x55 05 ffff8185`31ca0c60 00000000`00000000 nt!KiStartSystemThread+0x28 0: kd> u rip l20 nt!PnpCallDriverEntry: fffff805`7f375f00 4c8bdc mov r11,rsp fffff805`7f375f03 49895b08 mov qword ptr [r11+8],rbx fffff805`7f375f07 49897310 mov qword ptr [r11+10h],rsi fffff805`7f375f0b 57 push rdi fffff805`7f375f0c 4883ec50 sub rsp,50h fffff805`7f375f10 498363d800 and qword ptr [r11-28h],0 fffff805`7f375f15 488bda mov rbx,rdx fffff805`7f375f18 49894be0 mov qword ptr [r11-20h],rcx fffff805`7f375f1c 498d53d8 lea rdx,[r11-28h] fffff805`7f375f20 65488b042588010000 mov rax,qword ptr gs:[188h] fffff805`7f375f29 488bf9 mov rdi,rcx fffff805`7f375f2c b905000000 mov ecx,5 fffff805`7f375f31 498943e8 mov qword ptr [r11-18h],rax fffff805`7f375f35 e8b6c5eeff call nt!PnpEnableWatchdog (fffff805`7f2624f0) fffff805`7f375f3a 488bf0 mov rsi,rax fffff805`7f375f3d 488bd3 mov rdx,rbx fffff805`7f375f40 488b4758 mov rax,qword ptr [rdi+58h] fffff805`7f375f44 488bcf mov rcx,rdi fffff805`7f375f47 e84429caff call nt!guard_dispatch_icall (fffff805`7f018890) fffff805`7f375f4c 8bf8 mov edi,eax fffff805`7f375f4e 4885f6 test rsi,rsi fffff805`7f375f51 7454 je nt!PnpCallDriverEntry+0xa7 (fffff805`7f375fa7) fffff805`7f375f53 488b5e08 mov rbx,qword ptr [rsi+8] fffff805`7f375f57 41b001 mov r8b,1 fffff805`7f375f5a 4533c9 xor r9d,r9d fffff805`7f375f5d 418ad0 mov dl,r8b fffff805`7f375f60 488b4b38 mov rcx,qword ptr [rbx+38h] fffff805`7f375f64 e8d783b1ff call nt!ExDeleteTimer (fffff805`7ee8e340) fffff805`7f375f69 4883633800 and qword ptr [rbx+38h],0 fffff805`7f375f6e 8b4360 mov eax,dword ptr [rbx+60h] fffff805`7f375f71 85c0 test eax,eax fffff805`7f375f73 0f8f0b1b0d00 jg nt!PnpCallDriverEntry+0xd1b84 (fffff805`7f447a84)
C
๋ณต์‚ฌ
ํ•ด๋‹น ํ•จ์ˆ˜ ๋‚ด์˜ CFG ํ•จ์ˆ˜์—์„œ DriverEntry๋ฅผ ์ฒดํฌํ•˜๊ณ  ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. Checked and called the driverentry in the CFG function within PnpCallDriverEntry