반응형


WinDbg 요약  WinDbg 분석 / 프로그래밍 

2012/04/25 09:46

복사http://msbang.co.kr/80158660259


WinDbg 공부하면서 요약한 내용을 정리한 것인데…

하다보면 느끼는데… 이런거 정리할 시간에 글자 하나라도 더 보는게 좋은거 같다.. ^^;

 

 

 

WinDbg로 쉽게 배우는 Windows Debugging (요약)

- 에어컨 / 김성현, 이태화, 김희준 지음 -

 

 

 

1장. WinDbg에 대해

 

 

WinDbg 디버깅 종류

  • UserMode : 응용프로그램 디버깅
  • KernelMode : 커널모드 드라이버 개발, 윈도우 커널 분석

 

 

메모리 덤프 파일

응용프로그램에 문제가 발생할 때 상태가 저장된 파일, 오류가 발생했을 시점의 레지스터, 콜스택, 메모리, 프로세스, 스레드 정보 등이 저장되며 문제가 발생한 마지막 순간의 상태를 보존한다.

 

설정에 따른 메모리 덤프

(예) 메모리(1GB)

            ㅇ 전체 메모리 덤프 => C:\Windows\MEMORY.dmp(1GB)

            ㅇ 커널 메모리 덤프 => C:\Windows\MEMORY.dmp(300MB)

            ㅇ 작은 메모리 덤프 => C:\Windows\Minidump\Mini022908-01.dmp(64KB)

 

 

 

유저모드 vs 커널모드 가상 메모리 공강

 

 

 

블루스크린 (BSOD) – Blue Screen of Death

BSOD는 커널모드에서 문제가 발생했을 때 나타난다. BSOD가 발생했을 때 가장 먼저 생각하는 것이 "최근에 새로 설치한 하드웨어가 무엇이었는가"이며, 새로 설치한 하드웨어가 없다면 새로 설치한 프로그램이 무엇인가를 살펴본다. 커널모드 드라이버를 포함하는 프로그램일 수 있기 때문이다.

 

 

커널모드가 유저모드 디버깅과 다른점은 디버거가 하나의 드라이버에 연결돼 디버깅하는 것이 아니라 운영체제 자체에 연결돼 커널모드 전체를 디버깅한다

 

 

라이브 디버깅 vs 덤프 디버깅

라이브 디버깅이란 프로그램 동작 중 디버깅을 하는 것, 직접 작성한 소스코드를 한줄한줄 수행하면서 디버깅하는 경우, 이미 작성된 프로그램의 버그를 확인하는 경우

 

 

포스트모텀 디버깅(PostMortem Debugging)

라이브 디버깅을 통해 문제를 해결하는 것이 아니라 문제가 발생한 순간이나 특정한 상황을 덤프 파일과 같은 스냅샷으로 생성하고 추후에 그것을 분석해 문제를 해결하는 과정

 

 

디버그 심볼 파일 (.pdb)

디버그 심볼 파일이란 실행 파일을 빌드할 때 생성되는 디버그용 정보 파일로 포함되는 디버그 정보는 실행 파일안에 존재하는 함수나 변수들의 이름과 위치, 소스파일, 소스 라인 정보이다.

심볼 파일이 없다면 소스 라인 디버깅이 불가능할 뿐만 아니라 함수나 변수 이름조차 파악이 어렵다.

  • 마이크로소프트는 윈도우 버전마다 심볼 패키지를 제공
  • 용량이 큰 심볼 패키지 다운로드 문제 해결을 위해 웹 심볼 이용

 

 

윈도우 OS 버전별 정보

[그림 1-1] 윈도우 OS 버전 순서

 

 

WinDbg 명령

  • 일반 명령(Debugger Commands)
  • 메타 명령(Meta Commands)
  • 확장 명령(Extension Commands)

 

 

드라이버(Driver)

드라이버는 커널모드 드라이버나 장치 드라이버를 줄여서 사용하는 용어로 장치를 운전(동작)해주는 소프트웨어 프로그램을 의미한다.

2장. WinDbg 시작

 

 

유저모드 라이브 디버깅

특정 프로세스를 라이브 디버깅(Live Debugging)하는 것은 소프트웨어를 개발할 때 비주얼 스튜디오를 사용해서 디버깅하는 것과 같은 개념이다.

 

 

디버거 연결

  • WinDbg에서 MyApp.exe(예제)를 실행하면서 연결하는 방법

    Main 함수부터 디버깅 하려고 할 때 사용, MyApp.exe가 실제로 실행되기 전부터 디버거가 붙어서 실행된다.

  • 이미 MyApp.exe가 실행된 상태에서 WinDbg를 나중에 연결하는 방법

    특별한 조건으로 실행된 상태의 응용프로그램을 디버깅해야 할 때나 서비스 프로세스를 디버깅해야 할 때 사용한다.

  • MyApp.exe가 먼저 실행된 상태에서 어떤 문제가 발생했을 때 자동으로 WinDbg가 연결

 

 

심볼 파일 로드

로드해야 하는 심볼 파일은 크게 운영체제 심볼 파일과 디버깅하려는 모듈의 심볼 파일

 

1) 운영체제 심볼(웹 심볼)

File 메뉴 → Symbol File Path… 에서 심볼 경로 추가

SRV*D:\MySymbols*http://msdl.microsoft.com/download/symbols

 

위에 보다 더 간단한 방법으로 명령창에서 아래 명령어 입력하면 자동

0:000> .sysmfix D:\MySymbols

0:000> .reload

 

 

2) 모듈 심볼 파일

File 메뉴 → Symbol File Path… 에서 심볼 경로 추가 (마지막에 ; 하고 추가하면 됨)

SRV*D:\OsSymbols*http://msdl.microsoft.com/download/symbols;D:\MySymbols

 

명령창 입력 방법

0:000> .sympath

0:000> .sympath+ D:\MySymbols

 

 

실행 : g / F5

정지 : Ctrl + break

 

MyApp.exe 에 MyApp!CMyAppDlg::OnBreakPoint() 함수에 브레이크 포인트 설정하기

브레이크 포인트 설정> bp MyApp!CMyAppDlg::OnBreakPoint

브레이크 포인트 확인> bl

 

 

0번 브레이크 포인트 disable> bd 0

0번 브레이크 포인트 enable> be 0

 

브레이크 포인트 해제(Breakpoint Clear)

> bc 0

> bc *

> bc 3-5

> bc 2,7,8

 

 

콜 스택 확인

어떤 함수들이 어떤 순서로 해당 함수를 호출했는지 확인하는 것

 

 

 

 

3장. WinDbg로 디버깅하기

 

 

디버거를 붙여놓지 않은 상황에서 응용프로그램이 갑자기 종료하거나 시스템이 재부팅될 때 디버거가 붙어있지 않았다면 윈도우는 크래시 덤프(Crash Dump) = 메모리 덤프 파일을 만들어 놓는다.

 

 

유저모드 덤프 디버깅

  1. 덤프 파일 수집 (입력: drwtsn32)

     

     

    문제가 발생하면 이곳에 덤프 로그가 남는다.

     

     

  2. 덤프 파일 열기

Microsoft (R) Windows Debugger Version 6.11.0001.404 X86

Copyright (c) Microsoft Corporation. All rights reserved.

 

Loading Dump File [C:\Users\msBang\Desktop\WinDbg 예제\Ch3\Dump\UserMode Crash\user.dmp]

User Mini Dump File with Full Memory: Only application data is available

 

Comment: 'Dr. Watson generated MiniDump'

Symbol search path is: SRV*D:\OsSymbols*http://msdl.microsoft.com/download/symbols;D:\MySymbols

Executable search path is:

Windows XP Version 2600 (Service Pack 2) UP Free x86 compatible

Product: WinNt, suite: SingleUserTS

Machine Name:

Debug session time: Sun Jun 7 02:08:38.000 2009 (GMT+9)

System Uptime: 0 days 0:02:44.356

Process Uptime: 0 days 0:01:29.000

..........................

This dump file has an exception of interest stored in it.

The stored exception information can be accessed via .ecxr.

(3b8.3c0): Access violation - code c0000005 (first/second chance not available)

eax=00000000 ebx=00000001 ecx=0042d1a0 edx=00000055 esi=00424778 edi=0012fea0

eip=00401baf esp=0012f8c8 ebp=0012f8d4 iopl=0 nv up ei pl nz na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206

*** WARNING: Unable to verify checksum for MyApp.exe

MyApp!CMyAppDlg::MyStrCpy+0x40:

00401baf 8810 mov byte ptr [eax],dl ds:0023:00000000=??

 

 

콜 스택 확인 – 문제가 발생한 흐름 파악

  1. 모듈 정보 보기

    > lmvm MyApp (특정 모듈 정보 자세히 보기)

  2. 심볼 맞추기 (os정보와 app정보를 심볼에 추가한다)

     

    Private 심볼은 소스파일과 변수들의 정보를 모두 포함하는 심볼 파일이다.

  3. 심볼 설정후 콜 스택 보기

    > k

    심볼을 맞춰 놓은 상황이므로 운영체제 함수들과 MyApp.exe 함수들의 이름이 정확히 보인다.

    콜 스택이 정확하게 보이므로 함수들의 호출 흐름을 보고 어디 근처에서 문제 발생했는지 알 수 있다.

  4. 콜 스택 창에서 마지막 함수 살펴보기
  5. 문제가 발생한 이유 추측하기

 

 

 

 

 

 

커널모드 덤프 디버깅

  1. 덤프 파일 수집

    ㅇ 미니덤프 => C:\Windows\Minidump\Mini022608-01.dmp (08. 2. 26 첫번째 덤프)

    ㅇ 전체덤프 => C:\Windows\MEMORY.dmp

     

  2. 덤프 파일 열어보기

    File → Open Crash Dump (MEMORY.dmp)

Microsoft (R) Windows Debugger Version 6.11.0001.404 X86

Copyright (c) Microsoft Corporation. All rights reserved.

 

Loading Dump File [C:\Users\msBang\Desktop\WinDbg 예제\Ch3\Dump\BugCheck 0x8E\MEMORY.DMP]

Kernel Summary Dump File: Only kernel address space is available

 

Symbol search path is: SRV*D:\OsSymbols*http://msdl.microsoft.com/download/symbols;D:\MySymbols

Executable search path is:

Windows XP Kernel Version 2600 (Service Pack 2) UP Free x86 compatible

Product: WinNt, suite: TerminalServer SingleUserTS

Built by: 2600.xpsp_sp2_gdr.070227-2254

Machine Name:

Kernel base = 0x804d9000 PsLoadedModuleList = 0x8055e700

Debug session time: Sun Jul 5 00:45:40.609 2009 (GMT+9)

System Uptime: 0 days 0:01:06.234

Loading Kernel Symbols

...............................................................

...........................................................

Loading User Symbols

PEB is paged out (Peb.Ldr = 7ffd500c). Type ".hh dbgerr001" for details

Loading unloaded module list

........

*******************************************************************************

* *

* Bugcheck Analysis *

* *

*******************************************************************************

 

Use !analyze -v to get detailed debugging information.

 

BugCheck 8E, {c0000005, f9f2463f, f7ae7c64, 0}

 

*** ERROR: Module load completed but symbols could not be loaded for MyDrv.sys

PEB is paged out (Peb.Ldr = 7ffd500c). Type ".hh dbgerr001" for details

PEB is paged out (Peb.Ldr = 7ffd500c). Type ".hh dbgerr001" for details

Probably caused by : MyDrv.sys ( MyDrv+63f )

 

Followup: MachineOwner

---------

 

 

  1. !analyze –v 메시지 보기

    도움말에서 버크체크번호 확인하기 (Bug Check 0x8e)

     

  2. > !analyze –v

kd> !analyze -v

:

KERNEL_MODE_EXCEPTION_NOT_HANDLED (8e)

:

Some common problems are exception code 0x80000003. This means a hard

:

Arguments:

Arg1: c0000005, The exception code that was not handled

Arg2: f9f2463f, The address that the exception occurred at

Arg3: f7ae7c64, Trap Frame

:

TRAP_FRAME: f7ae7c64 -- (.trap 0xfffffffff7ae7c64)

:

STACK_TEXT:

f7ae782c 805006bb 0000008e c0000005 f9f2463f nt!KeBugCheckEx+0x1b

f7ae7bf4 805432d5 f7ae7c10 00000000 f7ae7c64 nt!KiDispatchException+0x3b1

f7ae7c5c 80543286 f7ae7ce0 f9f2463f badb0d00 nt!CommonDispatchException+0x4d

f7ae7c70 bf805a0c 815241a8 e19f96c0 f7ae7c9c nt!Kei386EoiHelper+0x18a

f7ae7ce0 f9f246a0 00000000 f9f24830 00000001 win32k!FreeObject+0x25

WARNING: Stack unwind information not available. Following frames may be wrong.

f7ae7cfc f9f24fb7 00000050 e14834a8 f8427000 MyDrv+0x6a0

f7ae8c40 804f1095 81561270 815908e0 806e6410 MyDrv+0xfb7

f7ae8c50 8058070a 81590950 814b4488 815908e0 nt!IopfCallDriver+0x31

f7ae8c64 8058156d 81561270 815908e0 814b4488 nt!IopSynchronousServiceTail+0x60

f7ae8d00 8057a0c2 000000b8 00000000 00000000 nt!IopXxxControlFile+0x5c5

f7ae8d34 8054286c 000000b8 00000000 00000000 nt!NtDeviceIoControlFile+0x2a

f7ae8d34 7c93eb94 000000b8 00000000 00000000 nt!KiFastCallEntry+0xfc

0012f878 00000000 00000000 00000000 00000000 0x7c93eb94

:

MODULE_NAME: MyDrv

:

> .trap 0xfffffffff7ae7c64 // 트랩 프레임 보기

> k // 문제가 발생했을 당시의 콜 스택 보기

kd> k

*** Stack trace for last set context - .thread/.cxr resets it

ChildEBP RetAddr

WARNING: Stack unwind information not available. Following frames may be wrong.

f7ae7ce0 f9f246a0 MyDrv+0x63f

f7ae7cfc f9f24fb7 MyDrv+0x6a0

f7ae8c40 804f1095 MyDrv+0xfb7

f7ae8c50 8058070a nt!IopfCallDriver+0x31

 

  1. 모듈 정보 보기

    파일이름, 파일버전, 파일날짜 등을 확인하고 모듈 소스코드와 심볼 파일을 찾는다.

    >lmvm MyDrv

kd> lmvm MyDrv

start end module name

f9f24000 f9f25c80 MyDrv (no symbols)

Loaded symbol image file: MyDrv.sys

Image path: \??\C:\WinDbgCD\Ch2\Bin\MyDrv.sys

Image name: MyDrv.sys

Timestamp: Tue Jun 02 23:37:42 2009 (4A253936)

:

MyDrv의 시작주소와 끝주소, 실행위치, 파일이름, 만들어진 날짜/시간 확인

 

  1. 심볼 맞추기

    파일 시간이 일치하는 MyDrv.pdb 파일을 D:\MySymbols에 복사후 심볼경로 설정

    > .sympath // 현재 심볼경로 확인 후 미설정이면 아래처럼

    > .symfix D:\OsSymbols

    > .sympath+ D:\MySymbols

    > .reload

     

    ※ 운영체제 심볼 설정하기 (3가지 방법)

    ㅇ _NT_SYMBOL_PATH 환경변수 이용

    1. 내 컴퓨터 → 속성 → 고급 시스템 설정 → 환경변수
    2. _NT_SYMBOL_PATH 생성 →

      SRV*D:\OsSymbols*http://msdl.microsoft.com/download/symbols

      이렇게 하면 WinDbg가 실행될 때 자동으로 해당 위치를 참고해 심볼 경로를 설정후 시작

    ㅇ WinDbg 명령프롬프트 실행 (-y 옵션)

    C:\windbg –y SRV*D:\OsSymbols*http://msdl.microsoft.com/download/symbols

    ㅇ Workspace 저장

  2. 심볼 맞춘후 모듈 정보 다시보기

    > lmvm MyDrv

kd> lmvm MyDrv

start end module name

f9f24000 f9f25c80 MyDrv (private pdb symbols) d:\mysymbols\MyDrv.pdb

Loaded symbol image file: MyDrv.sys

Image path: \??\C:\WinDbgCD\Ch2\Bin\MyDrv.sys

Image name: MyDrv.sys

Timestamp: Tue Jun 02 23:37:42 2009 (4A253936)

CheckSum: 0000EF71

ImageSize: 00001C80

:

 

  1. 콜 스택 다시보기 (심볼 맞췄으니 함수명이 보일 것이다.)

kd> k

*** Stack trace for last set context - .thread/.cxr resets it

ChildEBP RetAddr

f7ae7ce0 f9f246a0 MyDrv!MyStrCpy+0x3f [e:\windbgcd\ch2\src\mydrv\mydrv.c @ 314]

f7ae7cfc f9f24fb7 MyDrv!BugCheck8E+0x40 [e:\windbgcd\ch2\src\mydrv\mydrv.c @ 328]

f7ae8c40 804f1095 MyDrv!MyDrvDeviceControl+0x357 [e:\windbgcd\ch2\src\mydrv\mydrv.c @ 540]

f7ae8c50 8058070a nt!IopfCallDriver+0x31

f7ae8c64 8058156d nt!IopSynchronousServiceTail+0x60

f7ae8d00 8057a0c2 nt!IopXxxControlFile+0x5c5

f7ae8d34 8054286c nt!NtDeviceIoControlFile+0x2a

:

맨 마지막(제일 윗부분)에 호출된 부분들이 자신이 작성한(MyDrv) 모듈인 경우 여기가 문제가 발생한 곳이라 인정하면 된다.

 

  1. 콜 스택 창에서 마지막 함수 살펴보기

     

    콜 스택에서 해당 함수 더블클릭 (File → Source File Path 설정되어 있어야 함)

    소스코드 분석

     

  2. 문제가 발생한 이유 추측하기
  3. 로컬 창으로 변수 보기
  4. 와치 창으로 메모리 보기 (전역변수 확인)

 

★ 콜 스택을 보면서 분석을 시작하는 것이 중요!

 

 

[출처] WinDbg 요약|작성자 msBang

반응형

+ Recent posts