1 / 40

WinDbg 를 이용한 커널 드라이버 디버깅 2. Live Debugging

WinDbg 를 이용한 커널 드라이버 디버깅 2. Live Debugging. KOREA SYSTEM PROGRAMMER 1 st System Kernel Conference 2003.11.8. 목차. Debugger 와 Debuggee Symbol Driver Verifier 소스레벨 디버깅 Deadlock Debugging. Debugger 와 Debuggee. Debugger – WinDbg 를 수행하는 PC(HOST) Debuggee – Driver 를 수행하는 PC(TARGET).

jamesramsey
Download Presentation

WinDbg 를 이용한 커널 드라이버 디버깅 2. Live Debugging

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. WinDbg를 이용한 커널 드라이버 디버깅2. Live Debugging KOREA SYSTEM PROGRAMMER 1st System Kernel Conference 2003.11.8

  2. 목차 • Debugger 와 Debuggee • Symbol • Driver Verifier • 소스레벨 디버깅 • Deadlock Debugging

  3. Debugger 와 Debuggee • Debugger – WinDbg를 수행하는 PC(HOST) • Debuggee – Driver를 수행하는 PC(TARGET)

  4. Debugger 와 Debuggee • 디버거와 디버기의 연결 준비 • 시리얼 케이블( 널모뎀 ) – 9 pin to 9 pin • HOST notebook - USB to Serial cable • HOST – WinDbg • Debugger OS: Windows NT4, 2000, XP, 2003 Server • TARGET – NT OS • Debuggee OS: Windows NT4, 2000, XP, 2003 Server • Debuggee Platform: x86, IA-64, AMD64

  5. Debugger 와 Debuggee • Step 0. 시리얼 케이블 연결 • Debugger(HOST) – COM1 • Debuggee(TARGET) – COM2

  6. Debugger 와 Debuggee • Step 1. Debuggee 설정과 부팅 • OS를 디버그 모드로 부팅해야 한다 • C:\boot.ini 수정 Hidden, ReadOnly 속성제거 [boot loader] timeout=30 default=multi(0)disk(0)rdisk(0)partition(1)\WINNT [operating systems] multi(0)disk(0)rdisk(0)partition(1)\WINNT="Microsoft Windows XP Professional" /fastdetect

  7. Debugger 와 Debuggee [operating systems] multi(0)disk(0)rdisk(0)partition(1)\WINNT="Microsoft Windows XP Professional" /fastdetect multi(0)disk(0)rdisk(0)partition(1)\WINNT="Microsoft Windows XP Professional" /fastdetect /debug /debugport=com2 /baudrate=115200 • /debug – OS를 디버그 모드로 설정 • /debugport –시리얼포트 지정(디폴트는 com2) • /baudrate – 9600, 19200, 38400, 57600, 115200 중 선택 • 부트메뉴 시작할 운영 체제를 선택하십시오: Windows XP Professional Windows XP Professional [디버그 가능]

  8. Debugger 와 Debuggee • Step 2. 디버거(HOST) PC에서 WinDbg 실행 • File 메뉴에서 Kernel Debug …메뉴 선택

  9. Debugger 와 Debuggee • Step 3. WinDbg와 Debuggee 연결 • WinDbg는 연결 대기 상태에서 • Debuggee가 디버그 모드로 부팅하면 WinDbg와 연결되어 디버그 메시지를 뿌리기 시작 • Debuggee가 먼저 디버그 모드로 부팅되어 있었다면 Ctrl-Break 로 연결

  10. Debugger 와 Debuggee • 부팅하면서 연결된 화면

  11. Symbol • Symbol이 없다면… kernel32+0x102A84 • Symbol이 있다면… kernel32!CreateFileA kernel32!CreateFileW … ntdll!NtCreateFile ntdll!NtCreateProcess … nt!NtCreateFile nt!ZwCreateFile (nt = ntoskrnl.exe) …

  12. Symbol • WinDbg로 OS를 디버깅하기 위한 기본요소 • OS 심볼 파일 ( NT4, 2000, XP, … ) • 링커가 exe, dll, sys 등과 함께 심볼 생성 • .dbg files, .pdb files • ntoskrnl.exe – ntoskrnl.pdb (checked build) • ntoskrnl.exe – ntoskrnl.pdb (free build) • ntoskrnl.exe – ntoskrnl.pdb (NT4) • ntoskrnl.exe – ntoskrnl.pdb (Win2K, sp1, sp?) • ntoskrnl.exe – ntoskrnl.pdb (XP, sp1)

  13. Symbol • 심볼에 들어있는 정보 • 함수이름, 주소, (인자) • (전역변수, 지역변수) • (소스라인, 파일패스) • 심볼 다운로드 • http://www.microsoft.com/ddk/debugging/symbols.asp • NT4 sp6, sp6a ~ XP sp1 free build • OS에 default로 들어가는 모든 모듈의 심볼 포함 • Debuggee OS 에 맞춰서 사용

  14. Symbol • WinDbg에 Debuggee OS 심볼 설정 • Step 1. C:\ossymbol\2ksp3에 심볼 저장 • Step 2. WinDbg Command에서 • kd>.sympath c:\ossymbol\2ksp3 • Symbol search path is: c:\ossymbol\2ksp3 • File - Symbol • Search Path

  15. Symbol • WebSymbol • Symbol Search Path에 MS 웹심볼 사이트지정 • Debuggee OS 구분없이 사용 가능 • 모듈 CheckSum 비교하여 일치하는 심볼 다운로드 • Lazy symbol loading ( download ) • 서버의 공유폴더에 다운로드하여 공유가능 • WebSymbol 설정 • kd>.sympath srv*c:\websymbol*http:// • msdl.microsoft.com/download/symbols • Symbol search path is: SRV*c:\websymbol* • http://msdl.microsoft.com/download/symbols

  16. Symbol • WebSymbol 설정 • kd> .symfix c:\websymbol • Symbol search path is: SRV*c:\websymbol* • http://msdl.microsoft.com/download/symbols • File – Symbol • Search Path

  17. Symbol • Public symbol 과 Private symbol • Public symbol – MS가 외부에 공개하는 심볼 • 함수이름, 주소 표시 • Private symbol – MS가 내부에서 사용하는 심볼 • 전역변수, 지역변수, 소스라인, 파일패스까지 표시 • 소스 연동 가능

  18. Symbol • 심볼생성 • WinDbg로 우리의 모듈을 디버깅하려면 • 우리 모듈의 심볼파일이 필요 • Checked Build ( debug build ) • drvname.sys, drvname.pdb 생성 • drvname.pdb는 private symbol • Full 디버그 정보 포함 • Free Build ( release build ) • drvname.sys, drvname.pdb 생성 • 2K, XP DDK에서는 Free도 디폴트로 pdb 생성

  19. Symbol • Free build에서 Private symbol 생성 • Free build sys(exe)를 소스레벨 디버깅 가능 • 릴리즈된 모듈에 대해서 소스레벨 디버깅 가능 • Compiler Option ( NT4 DDK ) • -Zi • Linker Option ( NT4 DDK ) • /DEBUG /DEBUGTYPE=windbg • Build Utility Macro ( NT4 DDK ) • Set NTDEBUGTYPE=windbg • Set USE_PDB=1

  20. Driver Verifier • 개발검증이란?

  21. Driver Verifier • 드라이버 검증을 위한 도구 • Driver Verifier ( Windows 2000, XP or later ) • Bounds Checker for Driver Edition • Checked Build OS from MSDN • HCT ( Hardware Compatibility Test ) • Driver Verifier Option • Special Pool – Memory 앞뒤에 Guard 영역 체크 • Force IRQL checking – IRQL 문제 확인 • Low resource simulation –가상 리소스 부족 • Pool tracking – Memory leak 체크 • I/O verification – IRP 핸들링 체크

  22. Driver Verifier • Driver Verifier 실행 • 실행창에서 verifier.exe ENTER • 도스창에서 verifier.exe ENTER

  23. Driver Verifier

  24. Driver Verifier

  25. Driver Verifier • Io Verification Example *********************************************************************** * THIS VALIDATION BUG IS FATAL AND WILL CAUSE THE VERIFIER TO HALT * * WINDOWS (BUGCHECK) WHEN THE MACHINE IS NOT UNDER A KERNEL DEBUGGER! * *********************************************************************** WDM DRIVER ERROR: [MyDrv.sys @ 0xF9D5C900] An IRP dispatch handler (F9D5C900 ) has returned a status that is inconsistent with the Irp's IoStatus.Status field. ( Irp = B23CEF68 - Irp->IoStatus.Status = 00000000 - returned = 00000102 ) IRP_MJ_DEVICE_CONTROL [ DevObj=00000000, FileObject=80DFFC50, Parameters=00000000 00000000 00220018 00000000 ] http://www.microsoft.com/hwtest/bc/redir.asp?os=5.1.2600&major=0xc9&minor=0x224&lang=0x9 Break, Ignore, Zap, Remove, Disable all (bizrd)? b Breaking in... (press g<enter> to return to assert menu) nt!DbgBreakPoint: 80517a98 cc int 3 kd> u 0xF9D5C900 MyDrv!MyDrvDeviceControl [d:\project\test\mydrv\mydrv.c @ 238]: f9d5c900 55 push ebp

  26. Driver Verifier NTSTATUS MyDrvDeviceControl( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp ) { // LINE 238 … switch (ulIoControlCode) { case MYDRV_IOCTL_IOVERIFY: ntStatus = STATUS_TIMEOUT; pIrp -> IoStatus.Status = STATUS_SUCCESS; pIrp -> IoStatus.Information = 0; break; … } IoCompleteRequest(pIrp, IO_NO_INCREMENT); return ntStatus; }

  27. 소스레벨 디버깅 • 심볼패스 지정 • C:\xpddk\src\fastfat\fastfat.pdb 폴더직접지정 • C:\mysymbols 폴더로 심볼파일들 복사 • 소스패스 지정 • .srcpath c:\xpddk\src\fastfat

  28. 소스레벨 디버깅 • IFS Kit 의 fastfat.sys를 checked build

  29. Deadlock Debugging • Hang 과 Deadlock • 어떤 쓰레드가? 어떤 동기화 객체를?

  30. Deadlock Debugging • Hang • 프로세스 응답없음 • 쓰레드가 대기상태인 경우 • 쓰레드가 무한루프인 경우 • Hang example • 어떤 쓰레드가 어떤 이벤트를 기다림 • 버그에 의해 그 이벤트가 시그널되지 않음 Thread B KeSetEvent(kEvent) Thread A KeWaitForSingleObject(kEvent)

  31. Deadlock Debugging • 대기중인 쓰레드 찾기 ( MyApp.exe & MyDrv.sys ) • kd> !process 0 7 • PROCESS 80ef0030 SessionId: 0 Cid: 07b8 Peb: 7ffdf000 ParentCid: 04a0 • DirBase: 020a6000 ObjectTable: e1138520 HandleCount: 328. • Image: wuauclt.exe • … • THREAD 80ef0da8 Cid 7b8.778 Teb: 7ffde000 Win32Thread: e1921100 WAIT: (WrUserRequest) • f2597ccc 804f82e4 80ef0e18 80ef0da8 804f24b2 nt!KiSwapContext+0x2e • f2597cd8 804f24b2 000024ff e1921100 00000000 nt!KiSwapThread+0x44 • … • PROCESS 81189910 SessionId: 0 Cid: 011c Peb: 7ffdf000 ParentCid: 01cc • DirBase: 07426000 ObjectTable: e1dde380 HandleCount: 373. • Image: msnmsgr.exe • 자신의 프로세스를 먼저 살펴보기 • 버그의 95% - 개발중인 자신의 모듈 • 버그의 4% - 자신의 모듈과 다른 모듈 충돌 • 버그의 1% - OS 버그

  32. Deadlock Debugging PROCESS 80dddda8 SessionId: 0 Cid: 06cc Peb: 7ffdf000 ParentCid: 01cc DirBase: 0b26c000 ObjectTable: e151e3b0 HandleCount: 56. Image: MyApp.exe … THREAD 80de8610 Cid 6cc.2b0 Teb: 7ffde000 Win32Thread: e1500638 WAIT: (Executive) KernelMode Non-Alertable … ChildEBP RetAddr Args to Child f23dfb60 804f82e4 80de8680 80de8610 804f24b2 nt!KiSwapContext+0x2e f23dfb6c 804f24b2 00000000 f9d5c4c0 a9580f00 nt!KiSwapThread+0x44 f23dfb94 80627f2c 00000000 00000000 00000000 nt!KeWaitForSingleObject+0x1c0 f23dfbbc f9d5c9a3 f9d5c4c0 00000000 00000000 nt!VerifierKeWaitForSingleObject+0x54 f23dfc10 804e8185 80f56318 a9580f68 8069f524 MyDrv!MyDrvDeviceControl+0xa3 (CONV: stdcall) [d:\project\test\mydrv\mydrv.c @ 266] f23dfc20 80626d10 80de8820 8069f2f0 a9580f68 nt!IopfCallDriver+0x31 kd> .thread 80de8610 Implicit thread is now 80de8610 *** Call Stack 창의 내용이 위와 같이 바뀜

  33. Deadlock Debugging • 대기중인 대상 찾기 • case MYDRV_IOCTL_EVENT1: • KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL ); • pIrp -> IoStatus.Status = STATUS_SUCCESS; // LINE 266 • pIrp -> IoStatus.Information = 0; • break; • case MYDRV_IOCTL_EVENT2: • KeSetEvent( &Event, IO_NO_INCREMENT, FALSE ); • pIrp -> IoStatus.Status = STATUS_SUCCESS; • pIrp -> IoStatus.Information = 0; • break;

  34. Deadlock Debugging • Deadlock • 프로세스 응답없음 • 시스템 락킹 • Deadlock Example • 쓰레드 두개가 두 개의 락을 소유 시도 Thread 1 Acquire Lock A … Acquire Lock B Release Lock A Thread 2 Acquire Lock B … Acquire Lock A Release Lock B

  35. Deadlock Debugging • 대기중인 쓰레드 찾기( MyApp.exe & MyDrv.sys ) kd> !process 0 0 MyApp.exe PROCESS 81570b90 SessionId: 0 Cid: 01e4 Peb: 7ffdf000 ParentCid: 01e8 DirBase: 0bc9c000 ObjectTable: e20a9d60 HandleCount: 44. Image: MyApp.exe kd> !process 81570b90 PROCESS 81570b90 SessionId: 0 Cid: 01e4 Peb: 7ffdf000 ParentCid: 01e8 DirBase: 0bc9c000 ObjectTable: e20a9d60 HandleCount: 44. Image: MyApp.exe VadRoot 813898a8 Vads 58 Clone 0 Private 175. Modified 81. Locked 0. ... THREAD 8158c9f8 Cid 1e4.3b0 Teb: 7ffde000 Win32Thread: e1a53660 WAIT: (Executive) KernelMode Non-Alertable f9fdf480 Mutant - owning thread 81116030 IRP List: 81397b90: (0006,0094) Flags: 00000000 Mdl: 00000000 Not impersonating ...

  36. Deadlock Debugging ChildEBP RetAddr f2208bac 804f82e4 nt!KiSwapContext+0x2e (FPO: [EBP 0xf2208be0] [0,0,4]) f2208bb8 804f24b2 nt!KiSwapThread+0x44 (FPO: [0,0,2]) f2208be0 f9fdf9e4 nt!KeWaitForSingleObject+0x1c0 (FPO: [Non-Fpo]) f2208c34 804e8185 MyDrv!MyDrvDeviceControl+0xe4 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\project\test\mydrv\mydrv.c @ 272] f2208c44 8055887c nt!IopfCallDriver+0x31 (FPO: [0,0,1]) f2208c58 805595a7 nt!IopSynchronousServiceTail+0x5e (FPO: [Non-Fpo]) f2208d00 80552468 nt!IopXxxControlFile+0x5a5 f2208d34 8052a421 nt!NtDeviceIoControlFile+0x28 (FPO: [Non-Fpo]) kd> .thread 8158c9f8 Implicit thread is now 8158c9f8 *** Call Stack 창의 내용이 위와 같이 바뀜

  37. Deadlock Debugging case MYDRV_IOCTL_MUTEX1: KeWaitForSingleObject( &MutexA, Executive, KernelMode, FALSE, NULL ); interval1.QuadPart = -30000000; KeDelayExecutionThread( KernelMode, FALSE, &interval1 ); KeWaitForSingleObject( &MutexB, Executive, KernelMode, FALSE, NULL ); KeReleaseMutex( &MutexA, FALSE ); // LINE 272 KeReleaseMutex( &MutexB, FALSE ); kd> dd mydrv!MutexB f9fdf480 00080002 00000000 8158ca68 8158ca68 f9fdf490 81116040 81116040 81116030 00000100 kd> dt KMUTEX f9fdf480 +0x000 Header : _DISPATCHER_HEADER +0x010 MutantListEntry : _LIST_ENTRY [ 0x81116040 - 0x81116040 ] +0x018 OwnerThread : 0x81116030 +0x01c Abandoned : 0 '' +0x01d ApcDisable : 0x1 ''

  38. Deadlock Debugging kd> !thread 0x81116030 THREAD 81116030 Cid 428.60c Teb: 7ffde000 Win32Thread: e20f6cb8 WAIT: (Executive) KernelMode Non-Alertable f9fdf4a0 Mutant - owning thread 8158c9f8 IRP List: 81396c10: (0006,0094) Flags: 00000000 Mdl: 00000000 ... ChildEBP RetAddr Args to Child f26ddbac 804f82e4 811160a0 81116030 804f24b2 nt!KiSwapContext+0x2e f26ddbb8 804f24b2 81116240 817b6bd8 81396c10 nt!KiSwapThread+0x44 f26ddbe0 f9fdfa59 00000000 00000000 00000000 nt!KeWaitForSingleObject+0x1c0 f26ddc34 804e8185 8120ec98 81396c10 8069f2f0 MyDrv!MyDrvDeviceControl+0x159 (CONV: stdcall) [d:\project\test\mydrv\mydrv.c @ 287] f26ddc44 8055887c 81412ac0 81396c80 81396c10 nt!IopfCallDriver+0x31 f26ddc58 805595a7 8120ec98 81396c10 81412ac0 nt!IopSynchronousServiceTail+0x5e f26ddd00 80552468 000000a0 00000000 00000000 nt!IopXxxControlFile+0x5a5 f26ddd34 8052a421 000000a0 00000000 00000000 nt!NtDeviceIoControlFile+0x28 kd> .thread 81116030 Implicit thread is now 81116030

  39. Deadlock Debugging case MYDRV_IOCTL_MUTEX2: KeWaitForSingleObject( &MutexB, Executive, KernelMode, FALSE, NULL ); interval2.QuadPart = -30000000; KeDelayExecutionThread( KernelMode, FALSE, &interval2 ); KeWaitForSingleObject( &MutexA, Executive, KernelMode, FALSE, NULL ); KeReleaseMutex( &MutexB, FALSE ); // LINE 287 KeReleaseMutex( &MutexA, FALSE ); kd> dd mydrv!MutexA f9fdf4a0 00080002 00000000 811160a0 811160a0 f9fdf4b0 8158ca08 8158ca08 8158c9f8 00000100 kd> dt KMUTEX f9fdf4a0 +0x000 Header : _DISPATCHER_HEADER +0x010 MutantListEntry : _LIST_ENTRY [ 0x8158ca08 - 0x8158ca08 ] +0x018 OwnerThread : 0x8158c9f8 +0x01c Abandoned : 0 '' +0x01d ApcDisable : 0x1 ''

  40. Q & A

More Related