커널모드 디버깅 환경에서 특정 프로세스를 디버깅 하기위한 방법을 설명 합니다.
1. !process
타겟 프로세스의 정보를 얻습니다. 우리에게는 EPROCESS 정보가 필요합니다.
PROCESS 8202b328 SessionId: 0 Cid: 042c Peb: 7ffd5000 ParentCid: 0544
DirBase: 103cf000 ObjectTable: e1cd7780 HandleCount: 43.
Image: notepad.exe
2-1. .process /i
얻어온 EPROCESS 주소로 프로세스 컨텍스트를 변경합니다. /i 옵션을 사용하면 프로세스 컨텍스트가 타겟 프로세스로 맞춰지고 디버깅 권한을 가지게 됩니다.
You need to continue execution (press 'g' <enter>) for the context
to be switched. When the debugger breaks in again, you will be in
the new process context.
2-2. .thread /p /r
스레드 정보를 얻어서 컨텍스를 변경하는 또 다른 방법 입니다. '.f(+-)' 명령어를 사용하면 컨텍트를 자유롭게 넘나들 수 있습니다.
kd> !process 8202b328 2 <===== THREAD 정보획득
PROCESS 8202b328 SessionId: 0 Cid: 0774 Peb: 7ffda000 ParentCid: 0548
DirBase: 0e2fb000 ObjectTable: e17d64e8 HandleCount: 41.
Image: notepad.exe
THREAD 823196b0 Cid 0774.0778 Teb: 7ffdf000 Win32Thread: e1b34390 WAIT: (WrUserRequest) UserMode Non-Alertable
822c42e0 SynchronizationEvent
kd> .thread /p /r 823196b0
Implicit thread is now 823196b0
Implicit process is now 8228b118
.cache forcedecodeuser done
Loading User Symbols
..........................
kd> kn
*** Stack trace for last set context - .thread/.cxr resets it
# ChildEBP RetAddr
00 f4f9ec38 804dc0f7 nt!KiSwapContext+0x2e
01 f4f9ec44 804dc143 nt!KiSwapThread+0x46
02 f4f9ec6c bf802f45 nt!KeWaitForSingleObject+0x1c2
03 f4f9eca8 bf801b1d win32k!xxxSleepThread+0x192
04 f4f9ecec bf819e81 win32k!xxxRealInternalGetMessage+0x418
05 f4f9ed4c 804de7ec win32k!NtUserGetMessage+0x27
06 f4f9ed4c 7c90e514 nt!KiFastCallEntry+0xf8
07 0007feb8 7e4191be ntdll!KiFastSystemCallRet
08 0007fed8 01002a1b USER32!NtUserGetMessage+0xc
09 0007ff1c 01007511 notepad!WinMain+0xe5
0a 0007ffc0 7c817077 notepad!WinMainCRTStartup+0x174
0b 0007fff0 00000000 kernel32!BaseProcessStart+0x23
kd> .frame 9
09 0007ff1c 01007511 notepad!WinMain+0xe5
kd> .f+
0a 0007ffc0 7c817077 notepad!WinMainCRTStartup+0x174
kd> .f-
09 0007ff1c 01007511 notepad!WinMain+0xe5
kd> .f-
08 0007fed8 01002a1b USER32!NtUserGetMessage+0xc
3. press 'g' <enter> => (2-1. 기준으로 설명 합니다)
프로세스 컨텍스트가 맞춰지면 'g'를 눌러 디버거를 실행 시킵니다. 잠시 후 int3 이 발생하면서 타겟 프로세스 디버깅이 가능한 상태가 됩니다.
Break instruction exception - code 80000003 (first chance)
nt!RtlpBreakWithStatusInstruction:
804e3592 cc int 3
4. !process
타겟 프로세스로 디버깅 제어가 넘어왔는지 확인합니다.
kd> !process
PROCESS 8202b328 SessionId: 0 Cid: 042c Peb: 7ffd5000 ParentCid: 0544
DirBase: 103cf000 ObjectTable: e1cd7780 HandleCount: 43.
Image: notepad.exe
VadRoot 82119be8 Vads 62 Clone 0 Private 149. Modified 925. Locked 0.
DeviceMap e15d9ab8
Token e1c74b18
ElapsedTime 09:56:46.467
UserTime 00:00:00.110
KernelTime 00:00:00.931
QuotaPoolUsage[PagedPool] 33764
QuotaPoolUsage[NonPagedPool] 2480
Working Set Sizes (now,min,max) (129, 50, 345) (516KB, 200KB, 1380KB)
PeakWorkingSetSize 835
VirtualSize 30 Mb
PeakVirtualSize 35 Mb
PageFaultCount 1009
MemoryPriority BACKGROUND
BasePriority 8
CommitCharge 241
THREAD 8227d4f0 Cid 042c.0440 Teb: 7ffdf000 Win32Thread: e1d82008 WAIT: (WrUserRequest) UserMode Non-Alertable
8213e3e8 SynchronizationEvent
5. bp
브레이크 포인트를 설정하고 실제 디버깅이 가능한지 확인해 봅니다. 타겟 프로세스(메모장)에서 파일을 생성할 때 브레이크를 설정하겠습니다.
kd> bp kernel32!CreateFileA
kd> bl
0 e 7c801a28 0001 (0001) kernel32!CreateFileA
6. g
브레이크가 설정된 후 실행(g) 합니다. 타겟 프로세스(메모장)에서 파일저장을 클릭하면 디버거에 브레이크 포인트가 걸리게 됩니다.
Breakpoint 0 hit
kernel32!CreateFileA:
001b:7c801a28 8bff mov edi,edi
[참고 - WinDbg로 쉽게 배우는 Windows Debugging 413 page]




ntifs.h

