WinDbg 시작(커널 모드)
- 아티클
- 2023. 03. 08.
이 문서의 내용
WinDbg는 Windows용 디버깅 도구에 포함된 커널 모드 및 사용자 모드 디버거입니다. 이 문서에서는 WinDbg를 커널 모드 디버거로 사용하기 시작하는 데 도움이 되는 연습을 제공합니다.
Windows용 디버깅 도구를 가져오는 방법에 대한 자세한 내용은 WinDbg Windows 디버거 다운로드 및 설치를 참조하세요. 디버깅 도구를 설치한 후 64비트(x64) 및 32비트(x86) 버전의 도구에 대한 설치 디렉터리를 찾습니다. 예:
- C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
- C:\Program Files (x86)\Windows Kits\10\Debuggers\x86
커널 모드 디버깅 설정
커널 모드 디버깅 환경에는 일반적으로 호스트 컴퓨터 와 대상 컴퓨터라는 두 대의 컴퓨터가 있습니다. 디버거는 호스트 컴퓨터에서 실행되고 디버깅 중인 코드는 대상 컴퓨터에서 실행됩니다. 호스트와 대상은 디버그 케이블로 연결됩니다.
Windows 디버거는 다음과 같은 유형의 케이블을 지원합니다.
- 이더넷
- USB 2.0/USB 3.0
- 직렬(null 모뎀이라고도 함)
속도와 안정성을 위해 로컬 네트워크 허브와 함께 이더넷 케이블을 사용해야 합니다. 다음 다이어그램에서는 이더넷 케이블을 사용하여 디버깅하기 위해 연결된 호스트 및 대상 컴퓨터를 보여 줍니다.
이전 버전의 Windows에 대한 옵션은 USB 또는 직렬 케이블과 같은 직접 케이블을 사용하는 것입니다.
호스트 및 대상 컴퓨터를 설정하는 방법에 대한 자세한 내용은 수동으로 커널 모드 디버깅 설정을 참조하세요.
가상 머신 - VM
디버거를 Hyper-V 가상 머신에 연결하는 방법에 대한 자세한 내용은 가상 머신의 네트워크 디버깅 설정 - KDNET을 참조하세요.
커널 모드 디버깅 세션 설정
호스트 및 대상 컴퓨터를 설정하고 디버그 케이블에 연결한 후 커널 모드 디버깅 세션을 설정할 수 있습니다. 설정에 사용한 것과 동일한 항목의 지침을 따릅니다. 예를 들어 이더넷을 통해 디버깅할 호스트 및 대상 컴퓨터를 설정하려는 경우 다음 문서에서 커널 모드 디버깅 세션을 설정하기 위한 지침을 찾을 수 있습니다.
WinDbg 사용 시작
- 호스트 컴퓨터에서 WinDbg를 열고 대상 컴퓨터를 사용하여 커널 모드 디버깅 세션을 설정합니다.
- 디버거 설명서 CHM 파일을 열려면 도움말 메뉴로 이동하여 내용을 선택합니다. 디버거 설명서는 Windows용 디버깅 도구에서도 온라인으로 사용할 수 있습니다.
- 커널 모드 디버깅 세션을 설정하면 WinDbg가 자동으로 대상 컴퓨터에 침입할 수 있습니다. WinDbg가 중단되지 않으면 디버그 메뉴로 이동하여 중단을 선택합니다.
- WinDbg 창 아래쪽의 명령줄에서 다음 명령을 입력합니다.다음 예제와 유사하게 출력됩니다.
- dbgcmd
- .sympath srv*
-
기호 검색 경로는 WinDbg에 기호(PDB) 파일을 찾을 위치를 알려줍니다. 디버거는 함수 이름 및 변수 이름과 같은 코드 모듈에 대한 정보를 얻기 위해 기호 파일이 필요합니다..새로고침Symbol search path is: srv* Expanded Symbol search path is: cache*;SRV*https://msdl.microsoft.com/download/symbols
- WinDbg에 기호 파일의 초기 찾기 및 로드를 수행하도록 지시하는 다음 명령을 입력합니다.
- 로드된 모듈 목록을 보려면 다음 명령을 입력합니다.다음 예제와 유사하게 출력됩니다.
- dbgcmd
- Lm
-
0:000>3: kd> lm start end module name fffff800`00000000 fffff800`00088000 CI (deferred) ... fffff800`01143000 fffff800`01151000 BasicRender (deferred) fffff800`01151000 fffff800`01163000 BasicDisplay (deferred) ... fffff800`02a0e000 fffff800`03191000 nt (pdb symbols) C:\...\ntkrnlmp.pdb fffff800`03191000 fffff800`03200000 hal (deferred) ...
- 대상 컴퓨터 실행을 시작하려면 다음 명령을 입력합니다.
- g
- 다시 중단하려면 디버그 메뉴로 이동하여 중단을 선택합니다.
- 다음 명령을 입력하여 모듈의 _FILE_OBJECT 데이터 형식을 nt 검사합니다.다음 예제와 유사하게 출력됩니다.
- dbgcmd
- dt nt!_FILE_OBJECT
-
0:000>0: kd> dt nt!_FILE_OBJECT +0x000 Type : Int2B +0x002 Size : Int2B +0x008 DeviceObject : Ptr64 _DEVICE_OBJECT +0x010 Vpb : Ptr64 _VPB ... +0x0c0 IrpList : _LIST_ENTRY +0x0d0 FileObjectExtension : Ptr64 Void
- 다음 명령을 입력하여 모듈의 일부 기호를 nt 검사합니다.다음 예제와 유사하게 출력됩니다.
- dbgcmd
- x nt!*CreateProcess*
-
0:000>0: kd> x nt!*CreateProcess* fffff800`030821cc nt!ViCreateProcessCallbackInternal (<no parameter info>) ... fffff800`02e03904 nt!MmCreateProcessAddressSpace (<no parameter info>) fffff800`02cece00 nt!PspCreateProcessNotifyRoutine = <no type information> ...
- 다음 명령을 입력하여 MmCreateProcessAddressSpace에 중단점을 배치합니다.중단점이 설정되었는지 확인하려면 다음 명령을 입력합니다.다음 예제와 유사하게 출력됩니다.
- dbgcmd
- Bl
- bu nt! MmCreateProcessAddressSpace
-
대상 컴퓨터를 실행할 수 있도록 g 를 입력합니다.0:000>0: kd> bu nt!MmCreateProcessAddressSpace 0: kd> bl 0 e fffff800`02e03904 0001 (0001) nt!MmCreateProcessAddressSpace
- 대상 컴퓨터가 디버거에 즉시 침입하지 않으면 대상 컴퓨터에서 몇 가지 작업을 수행합니다(예: 메모장 열기). MmCreateProcessAddressSpace가 호출되면 대상 컴퓨터가 디버거로 중단됩니다. 스택 추적을 보려면 다음 명령을 입력합니다.k
dbgcmd
- 다음 예제와 유사하게 출력됩니다.
- .새로고침
-
0:000>2: kd> k Child-SP RetAddr Call Site ffffd000`224b4c88 fffff800`02d96834 nt!MmCreateProcessAddressSpace ffffd000`224b4c90 fffff800`02dfef17 nt!PspAllocateProcess+0x5d4 ffffd000`224b5060 fffff800`02b698b3 nt!NtCreateUserProcess+0x55b ... 000000d7`4167fbb0 00007ffd`14b064ad KERNEL32!BaseThreadInitThunk+0xd 000000d7`4167fbe0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
- 보기 메뉴에서 디스어셈블리를 선택합니다.
- 디버그 메뉴에서 단계별 실행을 선택하거나 F10 키를 누릅니다. 디스어셈블리 창을 watch 단계 명령을 몇 번 더 입력합니다.
- 다음 명령을 입력하여 중단점을 지웁다.대상 컴퓨터를 실행할 수 있도록 g 를 입력합니다. 다시 침입하려면 디버그 메뉴로 이동하여 중단을 선택하거나 Ctrl-Break를 누릅니다.
- 기원전*
- 모든 프로세스 목록을 보려면 다음 명령을 입력합니다.다음 예제와 유사하게 출력됩니다.
- dbgcmd
- !process 0 0
-
0:000>0: kd> !process 0 0 **** NT ACTIVE PROCESS DUMP **** PROCESS ffffe000002287c0 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000 DirBase: 001aa000 ObjectTable: ffffc00000003000 HandleCount: <Data Not Accessible> Image: System PROCESS ffffe00001e5a900 SessionId: none Cid: 0124 Peb: 7ff7809df000 ParentCid: 0004 DirBase: 100595000 ObjectTable: ffffc000002c5680 HandleCount: <Data Not Accessible> Image: smss.exe ... PROCESS ffffe00000d52900 SessionId: 1 Cid: 0910 Peb: 7ff669b8e000 ParentCid: 0a98 DirBase: 3fdba000 ObjectTable: ffffc00007bfd540 HandleCount: <Data Not Accessible> Image: explorer.exe
- 한 프로세스의 주소를 복사하고 다음 명령을 입력합니다.예: !process ffffe00000d5290 2
dbgcmd
- 출력에는 프로세스의 스레드가 표시됩니다.
- !process 주소 2
-
0:000>0:000>0: kd> !process ffffe00000d52900 2 PROCESS ffffe00000d52900 SessionId: 1 Cid: 0910 Peb: 7ff669b8e000 ParentCid: 0a98 DirBase: 3fdba000 ObjectTable: ffffc00007bfd540 HandleCount: Image: explorer.exe THREAD ffffe00000a0d880 Cid 0910.090c Teb: 00007ff669b8c000 ffffe00000d57700 SynchronizationEvent THREAD ffffe00000e48880 Cid 0910.0ad8 Teb: 00007ff669b8a000 ffffe00000d8e230 NotificationEvent ffffe00000cf6870 Semaphore Limit 0xffff ffffe000039c48c0 SynchronizationEvent ... THREAD ffffe00000e6d080 Cid 0910.0cc0 Teb: 00007ff669a10000 ffffe0000089a300 QueueObject
- 한 스레드의 주소를 복사하고 다음 명령을 입력합니다.예: !thread ffffe00000e6d080
dbgcmd
- 출력에는 개별 스레드에 대한 정보가 표시됩니다.
- !thread Address
-
0: kd> !thread ffffe00000e6d080 THREAD ffffe00000e6d080 Cid 0910.0cc0 Teb: 00007ff669a10000 Win32Thread: 0000000000000000 WAIT: ... ffffe0000089a300 QueueObject Not impersonating DeviceMap ffffc000034e7840 Owning Process ffffe00000d52900 Image: explorer.exe Attached Process N/A Image: N/A Wait Start TickCount 13777 Ticks: 2 (0:00:00:00.031) Context Switch Count 2 IdealProcessor: 1 UserTime 00:00:00.000 KernelTime 00:00:00.000 Win32 Start Address ntdll!TppWorkerThread (0x00007ffd14ab2850) Stack Init ffffd00021bf1dd0 Current ffffd00021bf1580 Base ffffd00021bf2000 Limit ffffd00021bec000 Call 0 Priority 13 BasePriority 13 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5 ...
- 플러그 앤 플레이 디바이스 트리의 모든 디바이스 노드를 보려면 다음 명령을 입력합니다.
dbgcmd
- !devnode 0 1
-
0:000>0: kd> !devnode 0 1 Dumping IopRootDeviceNode (= 0xffffe000002dbd30) DevNode 0xffffe000002dbd30 for PDO 0xffffe000002dc9e0 InstancePath is "HTREE\ROOT\0" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) DevNode 0xffffe000002d9d30 for PDO 0xffffe000002daa40 InstancePath is "ROOT\volmgr\0000" ServiceName is "volmgr" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) DevNode 0xffffe00001d49290 for PDO 0xffffe000002a9a90 InstancePath is "STORAGE\Volume\{3007dfd3-df8d-11e3-824c-806e6f6e6963}#0000000000100000" ServiceName is "volsnap" TargetDeviceNotify List - f 0xffffc0000031b520 b 0xffffc0000008d0f0 State = DeviceNodeStarted (0x308) Previous State = DeviceNodeStartPostWork (0x307) ...
- 디바이스 노드 및 해당 하드웨어 리소스를 보려면 다음 명령을 입력합니다.
dbgcmd
- !devnode 0 9
-
0:000>... DevNode 0xffffe000010fa770 for PDO 0xffffe000010c2060 InstancePath is "PCI\VEN_8086&DEV_2937&SUBSYS_2819103C&REV_02\3&33fd14ca&0&D0" ServiceName is "usbuhci" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) TranslatedResourceList at 0xffffc00003c78b00 Version 1.1 Interface 0x5 Bus #0 Entry 0 - Port (0x1) Device Exclusive (0x1) Flags (0x131) - PORT_MEMORY PORT_IO 16_BIT_DECODE POSITIVE_DECODE Range starts at 0x3120 for 0x20 bytes Entry 1 - DevicePrivate (0x81) Device Exclusive (0x1) Flags (0000) - Data - {0x00000001, 0x00000004, 0000000000} Entry 2 - Interrupt (0x2) Shared (0x3) Flags (0000) - LEVEL_SENSITIVE Level 0x8, Vector 0x81, Group 0, Affinity 0xf ...
- 서비스 이름이 디스크인 디바이스 노드를 보려면 다음 명령을 입력합니다.
dbgcmd
- !devnode 0 1 디스크
-
0: kd> !devnode 0 1 disk Dumping IopRootDeviceNode (= 0xffffe000002dbd30) DevNode 0xffffe0000114fd30 for PDO 0xffffe00001159610 InstancePath is "IDE\DiskST3250820AS_____________________________3.CHL___\5&14544e82&0&0.0.0" ServiceName is "disk" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) ...
- !devnode 0 1의 출력은 노드에 대한 PDO(물리적 디바이스 개체)의 주소를 보여 줍니다. PDO(물리적 디바이스 개체)의 주소를 복사하고 다음 명령을 입력합니다.예: <PdoAddress>!devstack 0xffffe00001159610
- dbgcmd
- !devstack PdoAddress
-
0:000>0: kd> !devstack 0xffffe00001159610 !DevObj !DrvObj !DevExt ObjectName ffffe00001d50040 \Driver\partmgr ffffe00001d50190 ffffe00001d51450 \Driver\disk ffffe00001d515a0 DR0 ffffe00001156e50 \Driver\ACPI ffffe000010d8bf0
- 드라이버 disk.sys 대한 정보를 얻으려면 다음 명령을 입력합니다.
dbgcmd
- !drvobj disk 2
-
0:000>0: kd> !drvobj disk 2 Driver object (ffffe00001d52680) is for: \Driver\disk DriverEntry: fffff800006b1270 disk!GsDriverEntry DriverStartIo: 00000000 DriverUnload: fffff800010b0b5c CLASSPNP!ClassUnload AddDevice: fffff800010aa110 CLASSPNP!ClassAddDevice Dispatch routines: [00] IRP_MJ_CREATE fffff8000106d160 CLASSPNP!ClassGlobalDispatch [01] IRP_MJ_CREATE_NAMED_PIPE fffff80002b0ab24 nt!IopInvalidDeviceRequest [02] IRP_MJ_CLOSE fffff8000106d160 CLASSPNP!ClassGlobalDispatch [03] IRP_MJ_READ fffff8000106d160 CLASSPNP!ClassGlobalDispatch ... [1b] IRP_MJ_PNP fffff8000106d160 CLASSPNP!ClassGlobalDispatch
- 의 !drvobj 출력은 디스패치 루틴의 주소를 보여 줍니다. CLASSPNP!ClassGlobalDispatch)을 입력합니다. 에서 ClassGlobalDispatch중단점을 설정하고 확인하려면 다음 명령을 입력합니다.Bl대상 컴퓨터가 디버거에 즉시 침입하지 않으면 대상 컴퓨터에서 몇 가지 작업을 수행합니다(예: 메모장을 열고 파일을 저장). 가 호출되면 대상 컴퓨터가 디버거 ClassGlobalDispatch 에 침입합니다. 스택 추적을 보려면 다음 명령을 입력합니다.k
dbgcmd
- 다음 예제와 유사하게 출력됩니다.
- .새로고침
- 를 입력 g 하여 대상 컴퓨터를 실행할 수 있도록 합니다.
- bu CLASSPNP! ClassGlobalDispatch
-
2: kd> k Child-SP RetAddr Call Site ffffd000`21d06cf8 fffff800`0056c14e CLASSPNP!ClassGlobalDispatch ffffd000`21d06d00 fffff800`00f2c31d volmgr!VmReadWrite+0x13e ffffd000`21d06d40 fffff800`0064515d fvevol!FveFilterRundownReadWrite+0x28d ffffd000`21d06e20 fffff800`0064578b rdyboost!SmdProcessReadWrite+0x14d ffffd000`21d06ef0 fffff800`00fb06ad rdyboost!SmdDispatchReadWrite+0x8b ffffd000`21d06f20 fffff800`0085cef5 volsnap!VolSnapReadFilter+0x5d ffffd000`21d06f50 fffff800`02b619f7 Ntfs!NtfsStorageDriverCallout+0x16 ...
- 디버깅 세션을 종료하려면 다음 명령을 입력합니다.
- Qd
명령 요약
- 도움말 메뉴의 내용 명령
- .sympath(기호 경로 설정)
- .reload(모듈 다시 로드)
- x(기호 검사)
- g(Go)
- dt(표시 유형)
- 디버그 메뉴의 중단 명령
- lm(로드된 모듈 나열)
- k(디스플레이 스택 백트레이스)
- bu(중단점 설정)
- bl(중단점 목록)
- bc(중단점 지우기)
- 디버그 메뉴의 단계별 명령(F11)
- !프로세스
- !스레드
- !devnode
- !devstack
- !drvobj
- qd(종료 및 분리)
추가 정보
'[Microsoft]' 카테고리의 다른 글
32비트 또는 64비트 디버깅 도구 선택 (0) | 2023.12.06 |
---|---|
환경 디버깅 (0) | 2023.12.06 |
WinDbg 시작(사용자 모드) (0) | 2023.12.06 |
Windows 디버깅 시작 (0) | 2023.12.06 |
Windows 드라이버 단계별 랩 디버그(에코 커널 모드) (0) | 2023.12.06 |