안녕하세요. moltak 입니다.

오늘은 드라이버 개발을 한다면 꼭 알아야 할 VMWare WinDBG 설정 방법을 포스팅 하겠습니다.

 

준비물: VMWare(6.5이상), WinDBG(6.0 이상), 꼭 해내겠다는 마음가짐.

 

세 개의 준비물만 갖추셨다면 완벽합니다.

세팅 순서는 VMWare->WinDBG 순서로 진행하겠습니다.

 

1. VMWare에 WindowsXP를 설치해 주세요. (다들 이미 너무 잘 아시는 내용)

2. 처음 WindowsXP를 VMWare에 설치하시고 가상 머신 세팅에 들어갑니다. (그림 참조)

3. 아래 Add 버튼을 누르셔서 Serial Port를 선택하세요.

4. Output to named pipe를 선택하세요. (그림 참조)

 

 

5. 아래 그림과 같이 세팅합니다. (Named pipe는 굉장히 중요하니 꼭 기억해 두세요.)

6. Yield CPU on poll 체크를 꼭 해주세요.

 

 

7. 아래 그림과 같이 세팅 되었을 겁니다.

 

 

8. 이제 VMWare안에 깔려있는 WindowsXP로 부팅합니다. 시스템 등록 정보-> 고급-> 시작 및 복구로 들어갑니다. 그리고 편집을 클릭합니다.

 

 

9. multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" 뒤에 /fastdetect /debug /debugport=COM1 /baudrate=115200를 추가 합니다.

이상으로 VMWare 세팅은 끝났습니다. 이제 WinDBG 설정을 하겠습니다.

 

 

10. WinDBG의 속성 창을 열어주세요.

빨간색 네모 박스 위치에 대상 뒤에 -b -k com:pipe,port=\\.\pipe\WDK,resets=0 를 붙여 넣어 주세요

 

 

자 이제 WinDBG를 열어 보세요. 근데 아래 그림과 같은 오류가 날 수 있습니다.

 

왜냐하면 VMWare에서 우리가 설정해준 Windows가 구동 중이 아닐 때 위와 같은 오류가 납니다.

이 것을 해결 하려면 Windows가 부팅 중일 때 WinDBG를 실행시키시면 해결할 수 있습니다.

 

 

그림처럼 vmware를 실행하자 마자 windbg 실행!! 그러면 됩니다.ㅋㅋㅋ

자 다들 아셨으니 공부합시다. ㅋㅋ 즐공 즐프요!!

 

 

 

Bloger: moltak.net

'scrap' 카테고리의 다른 글

유목문화에서 배우는 벤쳐경영  (0) 2012.03.16
말라리아를 진단하는 스마트폰 이야기  (0) 2012.03.14
방화벽 정책에 관하여  (0) 2010.04.29
방화벽 정책(예)  (0) 2010.04.29
방화벽 정책  (0) 2010.04.29

typedef struct _CHILD_RESULT
{
 DWORD dwDepth;
 LPVOID  lpLeftContext;
 LPVOID  lpRightContext;
}CHILD_RESULT, *PCHILD_RESULT;

typedef struct _CHECK_RESULT
{
 DWORD    dwFlags;
 DWORD    dwCheckResult;
 CHILD_RESULT  stChildResult;
 TCHAR    szResult[SZ_MAXSIZE];
 LPVOID    lpContext;
}CHECK_RESULT, *PCHECK_RESULT;


1) 구조체 형태 파악하기

0:000> dt _CHECK_RESULT
WinDbg_dt_test!_CHECK_RESULT
   +0x000 dwFlags          : Uint4B
   +0x004 dwCheckResult    : Uint4B
   +0x008 stChildResult    : _CHILD_RESULT
   +0x014 szResult         : [1024] Wchar
   +0x814 lpContext        : Ptr32 Void


2)구조체에 설정된 값 확인하기

0:000> dt _CHECK_RESULT 0x27f6f8
WinDbg_dt_test!_CHECK_RESULT
   +0x000 dwFlags          : 1
   +0x004 dwCheckResult    : 4
   +0x008 stChildResult    : _CHILD_RESULT
   +0x014 szResult         : [1024]  "Check_WinDBG_dt_Command function call"
   +0x814 lpContext        : (null)


2-1)구조체 값 확인하기 (심볼이 설정되었을때)

0:000> dt stChkResult
Local var @ 0x27f6f8 Type _CHECK_RESULT
   +0x000 dwFlags          : 1
   +0x004 dwCheckResult    : 4
   +0x008 stChildResult    : _CHILD_RESULT
   +0x014 szResult         : [1024]  "Check_WinDBG_dt_Command function call"
   +0x814 lpContext        : (null)


3) 구조체 특정 필드 확인하기 
0:000> dt _CHECK_RESULT dwCheckResult
WinDbg_dt_test!_CHECK_RESULT
   +0x004 dwCheckResult : Uint4B


3-1)구조체 특정 필드 값 확인하기 
0:000> dt _CHECK_RESULT dwCheckResult 0x27f6f8
WinDbg_dt_test!_CHECK_RESULT
   +0x004 dwCheckResult : 4
0:000> dt _CHECK_RESULT stChildResult 0x27f6f8
WinDbg_dt_test!_CHECK_RESULT
   +0x008 stChildResult : _CHILD_RESULT


4) 구조체 내에 있는 구조체 값 확인하기

0:000> dt _CHILD_RESULT 0x27f6f8+0x008
WinDbg_dt_test!_CHILD_RESULT
   +0x000 dwDepth          : 0
   +0x004 lpLeftContext    : (null)
   +0x008 lpRightContext   : (null)


5) 구조체에 있는 모든 값 나열(펼처서)해서 보기
0:000> dt -r _CHECK_RESULT 0x27f6f8
WinDbg_dt_test!_CHECK_RESULT
   +0x000 dwFlags          : 1
   +0x004 dwCheckResult    : 4
   +0x008 stChildResult    : _CHILD_RESULT
      +0x000 dwDepth          : 0
      +0x004 lpLeftContext    : (null)
      +0x008 lpRightContext   : (null)
   +0x014 szResult         : [1024]  "Check_WinDBG_dt_Command function call"
   +0x814 lpContext        : (null) 

'scrap' 카테고리의 다른 글

UDP Flooding  (0) 2010.03.19
Denial Of Service  (0) 2010.03.19
명령어1  (0) 2010.03.18
명령어2  (0) 2010.03.18
명령어3  (0) 2010.03.18

1) 커널의 모든 구조체 나열 : dt nt!_* (dt는 data type의 약자이고, nt는 윈도우 nt를 말하는게 아닐런지...ㅎㅎㅎ)

2) 커널의 특정 구조체 나열(인터럽트 관련) : dt nt!_*interrupt*

3) 특정 구조체의 구조 보기 : dt nt!_ktrap_frame

4) 특정 구조체 내의 하부 구조체까지 보는 명령 : dt nt!_ktrap_frame -r

5) 커널 내의 모든 스택 정보 보기 : !stacks 0

6) 시스템에 로드된 디바이스 드라이버 나열 : lm t n(lm은 list module의 약자 인듯...)


7) 전체 IDT(Interrupt Dispatch Table) 나열 : !idt -a

8) 빈번히(?) 호출된 interrupt 나열 : !idt => 어떤 빈도로 나열되는지 모르겠음.


9) 인터럽트 컨트롤러 나열 : !pic, !apic(작동 안함???)

10) io pic(programmable interrupt controller) 나열 : !ioapic


--------------------------------------- crash 분석 ---------------------------------------------------------

11) !analyze -v : 분석 결과 보기

12) kb : crash 당시의 커널 call stack 보기

13) !process -1 0 : crash 당시의 수행 중이던 프로세스

     !process -1 7 : crash 당시의 수행 중이던 프로세스의 상세 정보 출력(7이 상세 정보 출력 옵션임)

     - !process 0 0 : crash 당시의 가상메모리에 load 되어 있던 모든 프로세스(마지막이 0 flag 이므로, 간략히 출력 옵션임)

     - !process [process 시작주소] : 프로세스 관련 상세 정보 출력,

                                                   위의 커맨드로 시작주소를 알 수 있음.

     - 출력 정보 설명 :

        PROCESS : 프로세스의 정보가 들어있는 EPROCESS Block의 주소

        Cid : 프로세스 ID

        Peb : Process Environment Block 의 주소

        ParentCid : 부모 프로세스 ID

        Image : 프로세스 이름


14) !vm : crash 당시의 가상 메모리 사용 내역 요약 및 프로세스 리스트

15) !poolused : crash 당시의 커널 paged&nonpaged pool list

     - !poolused 2 : nonpaged pool 할당량 별로 정렬 후 출력

     - !poolused 4 : paged pool 할당량 별로 정렬 후 출력

16) !thread [thread 시작주소] : !process [process시작주소]를 하면 프로세스에 포함된 thread의 정보가

                                           나와서 확인 가능함.

     - 출력 정보 설명 : teb(thread environment block 시작 주소)

17) !locks : crash 당시 resource lock 정보

18) !handle : crash 당시에 open된 handle 정보 나열

     !handle [프로세스주소] : 해당 프로세스가 소유한 핸들을 출력함

     !handle [프로세스주소] f

19) !stack [프로세스주소] : 프로세스 관련 Stack 정보를 보여줌


--------------------------------------- hang 분석 ------------------------------------------------------

1) !analyze -hang -v : hang 분석을 해줌


--------------------------------------- !analyze -v 해석 ------------------------------------------------------

덤프에 따라, 일부 값은 안 나올수도 있음.


-v(verbose)  옵션은 상세 결과를 출력하게 함


1) FAULTING_IP : fault가 발생했을 때의 명령의 포인터 값

2) BUGCHECK_STR : 발생한 BUGCHECK을 설명하는 문장임.

                               BUGCHECK은 주로 커널 모드 fault와 연관이 있음.

3) DEFAULT_BUCKET_ID : 현재의 fault가 어떤 범주의 fault에 속하는지를 알려줌

4) LAST_CONTROL_TRANSFER : 스택에서 이뤄진 마지막 두 함수 호출을 보여준다.

                                               이들 주소에 ln 명령을 사용하면, 마지막 함수를 확인 가능함.

                                               (ln [주소] : 주소가 나타내는 심볼을 표시함)

5) STACK_TEXT : 스레드의 전체 스택 트레이스를 보여준다.

6) STACK_COMMAND : fault를 유발한 스레드의 stack trace를 구하기 위해 실행된 명령을 보여준다.

                                  ; 는 구분자임.

6) FOLLOWUP_IP : fault를 유발했을 가능성이 가장 큰 명령을 보여줌

7) SYMBOL_NAME : fault가 발생한 심볼의 이름을 보여줌

                              nt!ExDeferredFreePool+540 으로 나오는 것은 심볼이름이 아님. 주소를 나타냄

                              Private Symbol 이 없기 때문에 해당 주소의 구체적인 함수명 같은 심볼을 안 보여줌

                              (MS만 볼 수 있음)

8) FOLLOWUP_NAME : 이 fault를 누가 사후 점검해야 하는지를 나타냄

                                  보통 MachineOwner가 많음

9) IMAGE_NAME : fault가 발생한 이미지의 이름을 나타냄

10) MODULE_NAME : fault를 보이는 모듈의 이름을 나타냄

                              (lmvm [모듈명] 으로 조회 가능)

11) BUCKET_ID : fault가 속하는 문제의 범주를 보여줌

11) FOLLOW_UP : 이 fault에 가장 알맞은 소유자를 보여준다. 소유자를 찾을수 없다면 디폴트인 MachineOwner가 됨.


[출처] windbg 명령어 정리|작성자 난이


'scrap' 카테고리의 다른 글

Denial Of Service  (0) 2010.03.19
dt 명령어  (0) 2010.03.18
명령어2  (0) 2010.03.18
명령어3  (0) 2010.03.18
명렁어4  (0) 2010.03.18

아래 3가지 옵션을 이용하면 보다 많은 정보를 쉽게 확인 할 수 있습니다.

-V : 레지스터 또는 버추얼 메모리 주소 값을 보여 줍니다.

-t : 각 로컬 변수의 data type을 보여 줍니다.

-i : local, global, parameter, function, or unknown 등의 정보를 보여 줍니다.


적용예

1: kd> dv -V -t -i

prv param  b60b6b20 @ebp+0x08 void * P = 0x86558908

prv param  b60b6b24 @ebp+0x0c unsigned long TagToFree = 0

prv local  b60b6b24 @ebp+0x0c struct _EPROCESS * ProcessBilled = 0x00000000

prv local  b60b6b0c @ebp-0x0c unsigned long Tag = 0xb60b6b8d

prv local  b60b6b14 @ebp-0x04 _POOL_TYPE EntryPoolType = PagedPool (1)

prv local  b60b6b08 @ebp-0x10 unsigned long BigPages = 0x805bc066

prv local  b60b6b00 @ebp-0x18 _POOL_TYPE PoolType = NonPagedPool (0)

prv local  b60b6af0 @ebp-0x28 struct _KLOCK_QUEUE_HANDLE LockHandle = struct _KLOCK_QUEUE_HANDLE

prv local  b60b6b20 @ebp+0x08 unsigned long Combined = 0x86558908


로컬 변수인지 또는 파라미터 인지 보여주고 주소값이 나와서 값을 확인해 볼수 있다.


최근에 알게된 Tip을 하나 소개 합니다.

1)특정 콜스택 프레임으로 이동

1: kd> .frame 12

12 013bf554 65e931e8 ipnathlp!NatpDeletePortBlock+0x48


2) 로컬 변수와 파라미터 값 확인

1: kd> dv -V -t

013bf55c @ebp+0x08 struct _NAT_PORT_RESERVATION * PortReservation = 0x0013d1f0

013bf560 @ebp+0x0c struct _NAT_PORT_BLOCK * PortBlock = 0x02f75988

013bf544 @ebp-0x10 struct _IO_STATUS_BLOCK IoStatus = struct _IO_STATUS_BLOCK

013bf54c @ebp-0x08 struct tcp_blockports_request Request = struct tcp_blockports_request


//dt 명령어로 값을 확인했다.

1: kd> dt _NAT_PORT_RESERVATION 0x0013d1f0

ipnathlp!_NAT_PORT_RESERVATION

   +0x000 TcpipHandle      : 0x00000da8

   +0x004 BlockSize        : 0x20

   +0x006 PortBlockSize    : 0x18

   +0x008 PortBlockList    : _LIST_ENTRY [ 0x2f75988 - 0x12b7f8 ]


//dt 명령어로 값을 확인했다.

1: kd> dt _NAT_PORT_BLOCK 0x02f75988

ipnathlp!_NAT_PORT_BLOCK

   +0x000 Link             : _LIST_ENTRY [ 0x12c050 - 0x13d1f8 ]

   +0x008 StartHandle      : 0x1389

   +0x00c Bitmap           : _RTL_BITMAP

   +0x014 BitmapBuffer     : [0] 0


3) ?? 명령으로 특정 로컬 변수값 확인

1: kd> ?? Request  -> (?? 명령어로 확인할수 있는줄 몰랐다, 꼭 dt만 사용해야 하는줄 알았다.)

struct tcp_blockports_request

   +0x000 ReservePorts     : 0

   +0x004 NumberofPorts    : 0x1389

   +0x004 StartHandle      : 0x1389 a 0n5001

'scrap' 카테고리의 다른 글

dt 명령어  (0) 2010.03.18
명령어1  (0) 2010.03.18
명령어3  (0) 2010.03.18
명렁어4  (0) 2010.03.18
명령어5  (0) 2010.03.18

kd> .symfix e:\symbols

kd> .reload
Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
........................
Loading User Symbols

lm 을 사용하여 심볼이 로드된 상태를 봅니다.

kd> lm
start    end        module name
804d9000 806ede00   nt         (pdb symbols)          e:\symbols\ntoskrnl.pdb\8592B6763F344B562\ntoskrnl.pdb
806ee000 80701d80   hal        (deferred)            
f9871000 f988b580   Mup        (deferred)   
f996f000 f998e780   fltMgr     (deferred)
...

nt 는 심볼이 로드된 것이 보이는데 나머지는 deferred 라고 나옵니다.
이것은 WinDbg 의 lazy symbol loading (deferred symbol loading) 이라는 특징 때문에 그렇습니다.

WinDbg 는 심볼을 로드할 때 꼭 필요한 심볼만 올려놓고 나머지는 deferred 로 해놓고 심볼을 올리지 않습니다. deferred 로 된 녀석들은 나중에 해당 모듈이 WinDbg 상에서 실제 사용되는 순간이 발생해야만 로드가 됩니다. 필요한 것만 그때 그때 올려주는 나름대로 효율적인 방법입니다. ^^

WinDbg Help 에 보면 .reload 는 다양한 옵션을 가지고 있는데요.
제가 유용하게 사용하는 것만 몇가지 설명합니다.

.reload /i mydrv.sys (심볼이 맞지않아도 강제로 심볼 로드하기)

예를 들어 어제 빌드한 드라이버가 BSOD 를 발생시켜서 덤프가 만들어 졌는데 심볼은 보관하지 않아서 덤프분석을 할 수 없는 문제를 만났다고 가정합시다. 다행히도 어제 소스 코드를 그대로 보관하고 있었다고 하면 그것을 그대로 빌드하여 pdb 파일을 생성할 수 있습니다. 문제는 이 pdb 파일을 로드하려고 해도 WinDbg가 TimeStamp 등을 체크하여 symbol mismatch 에러를 내면서 심볼로드를 하지 않는다는 겁니다. 이런 경우에 심볼이 맞는지 확인하지 말고 강제로 올려달라는 /i 옵션을 사용하면 심볼이 올라갑니다.

.reload /f (심볼 모두 올리기)

보통 lazy symbol loading 상태로 그냥 사용하시면 되지만 혹시 모든 모듈의 심볼을 모두 올려 놓아야 할 경우가 있다면 /f 옵션을 사용해서 모든 모듈의 심볼을 올릴 수 있습니다.

.reload /u (심볼 모두 내리기)

반대로 모든 심볼을 모두 내려야 할 경우가 있다면 /u 옵션을 사용해서 모든 모듈의 심볼을 내릴 수 있습니다.

.reload /u mydrv.sys (특정모듈 심볼 내리기)

mydrv.pdb 를 로드하여 사용하고 있는데 새로 빌드한 mydrv.pdb 를 심볼패스에 복사하면 mydrv.pdb 가 사용중이라서 복사가 실패합니다. 이런 경우 /u mydrv.sys 옵션을 줘서 특정 모듈의 심볼만 내릴 수 있습니다.

.reload mydrv.sys (특정모듈 심볼 로드하기)

위와 같이 내려진 특정 모듈의 심볼만 다시 올리려면 mydrv.sys 처럼 모듈 이름을 줘서 로드합니다.


로드된 모듈 리스트 보기
 lm 명령을 이용하면 된다.

lm k : Kernel Mode 모듈 표시
lm u : User Mode 모듈 표시
lm m : 패턴을 검사하여 해당하는 것만 보여줌 <lm m my*>

lkd> lm
start    end        module name
00c80000 00c90000   NateOnHook40u   (export symbols)       C:\Program Files\NATEON\BIN\NateOnHook40u.dll
00cb0000 00cb9000   MgHookDll C (export symbols)       C:\Program Files\LG Software\On Screen Display\MgHookDll.dll
01000000 0106a000   windbg     (pdb symbols)          D:\Symbol\WebSymbol\windbg.pdb\D6EF677AA54441279479F0307F05A8941\windbg.pdb
016a0000 01784000   ext        (export symbols)       C:\Program Files\Debugging Tools for Windows\winext\ext.dll
01790000 017c1000   kext       (pdb symbols)          D:\Symbol\WebSymbol\kext.pdb\6B643FC4E9F94FF4ABA4CEF1FD6F89D61\kext.pdb


모듈의 심볼(Symbol) 검사
 x 모듈!패턴 을 입력하면 된다.

lkd> x nt!Ke*
804f8c02 nt!KeQuerySystemTime = <no type information>
804f8c9e nt!KeEnableInterrupts = <no type information>
80500e38 nt!KeSwitchKernelStack = <no type information>
804fad32 nt!KeReadStateProcess = <no type information>
804f9188 nt!KeReleaseInterruptSpinLock = <no type information>


데이터 타입(Date Type) 표시
 dt 데이터 타입 을 입력하면 된다.

lkd> dt _EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x06c ProcessLock      : _EX_PUSH_LOCK
   +0x070 CreateTime       : _LARGE_INTEGER
   +0x078 ExitTime         : _LARGE_INTEGER
   +0x080 RundownProtect   : _EX_RUNDOWN_REF
   +0x084 UniqueProcessId  : Ptr32 Void
   +0x088 ActiveProcessLinks : _LIST_ENTRY
   +0x090 QuotaUsage       : [3] Uint4B
   +0x09c QuotaPeak        : [3] Uint4B
   +0x0a8 CommitCharge     : Uint4B



메모리 덤프(Memory Dump)
 d* 명령들을 이용하면 된다.

db : Byte 형식 + Ascii 로 표시
dd : 데이터를 4Byte 형식으로 표시

lkd> db 8053db18
8053db18  8b ff 55 8b ec 8b 45 08-8b 4d 0c 8b 55 14 89 48  ..U...E..M..U..H
8053db28  0c 8b 4d 10 89 48 10 03-ca 89 48 14 8b 4d 18 83  ..M..H....H..M..
8053db38  c1 fe 89 48 18 8b 4d 1c-89 48 20 66 8b 4d 20 66  ...H..M..H f.M f



디스어셈블리(Disassembly)
 u 주소 를 이용하면 된다. 특정 함수를 디스어셈블리 하고 싶으면 uf 주소 를 하면 된다.

u 주소 : 주소에서 일부분만 디스어셈블리
u 주소1 주소2 : 주소1에서 주소 2까지 디스어셈블리

lkd> u 8053db18 or uf nt!NtOpenProcess
nt!KeInitializeProfile:
8053db18 8bff             mov     edi,edi
8053db1a 55               push    ebp
8053db1b 8bec             mov     ebp,esp
8053db1d 8b4508           mov     eax,[ebp+0x8]
8053db20 8b4d0c           mov     ecx,[ebp+0xc]


메모리 영역 속성 보기(VA Dump)
 !vadump 명령을 사용하면 된다. 만약 특정 메모리의 속성을 보고 싶다면 !vprot 주소 명령을 사용하면 된다.

0:000> !vadump
BaseAddress:       00000000
RegionSize:        00010000
State:             00010000  MEM_FREE
Protect:           00000001  PAGE_NOACCESS

BaseAddress:       00010000
RegionSize:        00001000
State:             00001000  MEM_COMMIT
Protect:           00000004  PAGE_READWRITE
Type:              00020000  MEM_PRIVATE


0:000> !vprot 30c191c
BaseAddress: 030c1000
AllocationBase: 030c0000
AllocationProtect: 00000080 PAGE_EXECUTE_WRITECOPY
RegionSize: 00011000
State: 00001000 MEM_COMMIT
Protect: 00000010 PAGE_EXECUTE
Type: 01000000 MEM_IMAGE


프로세스 관련
 모든 프로세스를 보기위해서는 !process 0 0 를 입력하면 된다. 디버거를 특정 프로세스에 붙이고 싶으면 .process /i [pid] 를 입력하면 된다.


lkd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS 8a3a3490  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00780000  ObjectTable: e1001c70  HandleCount: 521.
    Image: System

PROCESS 8a184158  SessionId: none  Cid: 03f0    Peb: 7ffdd000  ParentCid: 0004
    DirBase: 17a40020  ObjectTable: e163dd70  HandleCount:  20.
    Image: smss.exe

PROCESS 89df4da0  SessionId: 0  Cid: 0440    Peb: 7ffd5000  ParentCid: 03f0
    DirBase: 17a40040  ObjectTable: e1c6cb18  HandleCount: 626.
    Image: csrss.exe


구조체 내용 보기

!strct _KMUTANT ff93a330

이렇게 명령을 주면 자료구조랑 값들이 같이 출력이 된다.


WinDBG 디버깅 과정 파일로 저장하기

Windbg를 이용해서 디버깅을 하다보면,

디버깅과정을 저장할 필요가 생깁니다.
또는 아래와 같은 상황이 있을수 있을겁니다.


- 다른분의 도움을 통해 디버깅한 내용을 참고하고 싶은경우
- 수십시간동안 켜놓은 결과를 저장해야하는경우. -> 화면 버퍼를 넘어가면 그동안의  내용이 사라지죠~
- .cls 를 습관적으로 사용하는경우.    -> 제경우입니다. T.T

이때 유용한 명령어가 바로.

.logxxx 계열 명령어입니다.


.logopen logfile
    >> 디버깅 과정을 저장할 로그파일 명을 지정합니다.
          ex) .logopen “c:\dbglog\logs.txt”

.logfile
    >> 현재 기록중인 디버깅 로그파일의 상태를 표시합니다.

.logclose
    >> 기록중이던 로그를 종료(완료)합니다.



유용하게 쓰세요~
(단, .logopen 이전의 내용은 저장되지 않습니다.` ^^)
참고하세요)
.logopen 정보 역시 Windbg WorkSpace 에 함께 저장됩니다.~ ^^


출처 : 다년간의 프로그래밍 경험 및 구글 search 결과

[출처] WinDBG 명령어 정리|작성자 갱주니

'scrap' 카테고리의 다른 글

명령어1  (0) 2010.03.18
명령어2  (0) 2010.03.18
명렁어4  (0) 2010.03.18
명령어5  (0) 2010.03.18
명령어6  (0) 2010.03.18

1.심볼(pdb), 소스 파일 설정하기

(WinDbg에서 심볼은 필요할 때 로드한다. 즉 지연해서 로드한다.)

ld [심볼이름] -> 강제로 심볼 로드하는 명령어

lm -> 현재 로드 되어있는 모듈 보여준다. 지연 되어 있으면 (deffered)라고 나온다.

.reload-> 심볼다시로드


2.| (process status)

3.~ (thread status)

4.변수 확인하기

.frame 1

dv(display variable)

5.dt r (typecast) (address)

(dt -r int 0x0012f5bc)

6.wt-> 모든 함수를 계층적으로 보여주는 명령어

7.브레이크 포인트

bp -> 주소를 이용해서 설정

bu -> 심볼이름을 이용해서 설정

(bu 060630_WinDbgTest!CWinDbgTestDlg::OnBnClickedButton1)

bl -> 브레이크 포인트 리스트

be (breakpoint enable), bd(breakpoint disable)

bc (breakpoint clear)

ba -> 메모리 액세스 브레이크 포인트

8.!critsec (임계섹션 주소), !locks(잠겨진 모든 임계섹션 주소 확인), !handle(프로세스내의 핸들 정보 표시)

'scrap' 카테고리의 다른 글

명령어2  (0) 2010.03.18
명령어3  (0) 2010.03.18
명령어5  (0) 2010.03.18
명령어6  (0) 2010.03.18
C++ Project Templete Create  (0) 2010.03.18

1)!vm 명령을 사용해서 현재 컴퓨터의 메모리 사용량을 살펴 보았습니다.


kd> !vm

*** Virtual Memory Usage ***
Physical Memory:   655234   ( 2620936 Kb)
Page File: \??\C:\pagefile.sys
   Current:   2095104Kb Free Space:   1999612Kb
   Minimum:   2095104Kb Maximum:      4190208Kb
Available Pages:   130442   (  521768 Kb)
ResAvail Pages:    577917   ( 2311668 Kb)
Modified Pages:       749   (    2996 Kb)
NonPagedPool Usage: 65522   (  262088 Kb)
NonPagedPool Max:   69378   (  277512 Kb)
********** Excessive NonPaged Pool Usage *****
PagedPool 0 Usage:   4025   (   16100 Kb)
PagedPool 1 Usage:    416   (    1664 Kb)
PagedPool 2 Usage:    414   (    1656 Kb)
PagedPool 3 Usage:    416   (    1664 Kb)
PagedPool 4 Usage:    411   (    1644 Kb)
PagedPool Usage:     5682   (   22728 Kb)
PagedPool Maximum:  86016   (  344064 Kb)
Shared Commit:        978   (    3912 Kb)


현재 !vm 명령을 통해서 NonPagedPool 메모리를 거의 다 사용한 것을 알 수 있습니다. 아마 특정 디바이스 드라이버 모듈에서 메모리를 많이 사용하는 것 같습니다.


2) !poolused 명령어를 사용해서 각각 메모리 할당 내용을 살펴 봅니다.

0: kd> !poolused
   Sorting by  Tag

  Pool Used:
            NonPaged            Paged
 Tag    Allocs     Used    Allocs     Used
 1394        1      520         0        0UNKNOWN pooltag '1394', please update pooltag.txt
 1MEM        1     3368         0        0UNKNOWN pooltag '1MEM', please update pooltag.txt
 2MEM        1     3944         0        0UNKNOWN pooltag '2MEM', please update pooltag.txt
 3MEM        3      248         0        0UNKNOWN pooltag '3MEM', please update pooltag.txt
 8042        4     3944         0        0PS/2 kb and mouse , Binary: i8042prt.sys
 AGP         1      344         2      384UNKNOWN pooltag 'AGP ', please update pooltag.txt
 AcdN        2     1072         0        0TDI AcdObjectInfoG 
 AcpA        3      192         1      504ACPI Pooltags , Binary: acpi.sys
 AcpB        0        0         4      576ACPI Pooltags , Binary: acpi.sys
 AcpD       40    13280         0        0ACPI Pooltags , Binary: acpi.sys
 AcpF        6      240         0        0ACPI Pooltags , Binary: acpi.sys
 AcpM        0        0         1      128ACPI Pooltags , Binary: acpi.sys
 AcpO        4      208         0        0ACPI Pooltags , Binary: acpi.sys

...

 WmiG       30     6960         0        0Allocation of WMIGUID 
 WmiR       63     4032         0        0Wmi Registration info blocks 
 Wmip      146     3504       182    18600Wmi General purpose allocation 
 Wmit        1     4096         7    49480Wmi Trace 
 Wrpa        2      720         0        0WAN_ADAPTER_TAG 
 Wrpc        1       72         0        0WAN_CONN_TAG 
 Wrpi        1      120         0        0WAN_INTERFACE_TAG 
 Wrps        2      128         0        0WAN_STRING_TAG 
 aEoP        1      672         0        0UNKNOWN pooltag 'aEoP', please update pooltag.txt
 fEoP        1       16         0        0UNKNOWN pooltag 'fEoP', please update pooltag.txt
 hSVD        0        0         1       40Shared Heap Tag , Binary: mrxdav.sys
 hibr        0        0         1    24576UNKNOWN pooltag 'hibr', please update pooltag.txt
 iEoP        1       24         0        0UNKNOWN pooltag 'iEoP', please update pooltag.txt
 idle        2      208         0        0Power Manager idle handler 
 jEoP        1       24         0        0UNKNOWN pooltag 'jEoP', please update pooltag.txt
 mEoP        1       88         0        0UNKNOWN pooltag 'mEoP', please update pooltag.txt
 ohci        1      136         0        01394 OHCI host controller driver 
 rx..       3     1248         0        0UNKNOWN pooltag '  rx', please update pooltag.txt
 sidg        2       48         0        0GDI spooler events 
 thdd        0        0         1    20480DirectDraw/3D handle manager table 
 SeSd      18    77056         2       96UNKNOWN pooltag 'SeSd', please update pooltag.txt
 vPrt        0        0        18    68160UNKNOWN pooltag 'vPrt', please update pooltag.txt
 TOTAL     3570214 209120008     38769 13066104

usbp 태그를 사용하는 모듈이 Nonpaged를 많이 사용하고 있습니다. 


3)!poolfind를 이용해서 특정 태그 메모리 사용내역을 확인해 봅니다.

kd> !poolfind SeSd 0

Scanning large pool allocation table for Tag: SeSd (827d1000 : 827e9000)

Searching NonPaged pool (823b1000 : 82800000) for Tag: SeSd

826fa130 size:   c0 previous size:   40  (Allocated) SeSd
82712000 size:   c0 previous size:    0  (Allocated) SeSd
82715940 size:   a0 previous size:   60  (Allocated) SeSd
8271da30 size:   c0 previous size:   10  (Allocated) SeSd
82721c00 size:   10 previous size:   30  (Free)      SeSd
8272b3f0 size:   60 previous size:   30  (Allocated) SeSd
8272d770 size:   60 previous size:   40  (Allocated) SeSd
8272d7d0 size:   a0 previous size:   60  (Allocated) SeSd
8272d960 size:   a0 previous size:   70  (Allocated) SeSd
82736f30 size:   a0 previous size:   10  (Allocated) SeSd
82763840 size:   a0 previous size:   10  (Allocated) SeSd
8278b730 size:  100 previous size:  290  (Allocated) SeSd
8278b830 size:   10 previous size:  100  (Free)      SeSd
82790130 size:   a0 previous size:   20  (Allocated) SeSd
82799180 size:   a0 previous size:   10  (Allocated) SeSd
827c00e0 size:   a0 previous size:   30  (Allocated) SeSd
827c8320 size:   a0 previous size:   60  (Allocated) SeSd
827ca180 size:   a0 previous size:   50  (Allocated) SeSd
827ec140 size:   a0 previous size:   10  (Allocated) SeSd

Searching NonPaged pool (fe7c3000 : ffbe0000) for Tag: SeSd

위 결과를 보니 메모리 할당(Allocated)된 만큼 해제(free)를 하지 않고 있는것 같습니다. 메모리 릭(memory leak)이 발생한것 같습니다.


4) Tag 이름으로 문제를 발생하고 있는 드라이버 찾기

WinDbg에서 태그로 이름으로 드라이버를 찾는 명령어를 제공하지 않는것으로 알고 있습니다.

그래서 저는 www.dumpanaysis.org 사이트에 나와있는 방법으로 찾습니다. 


직접 C:\windows\system32\drivers 드라이버 폴더에 찾는다. (cmd.exe)

C:\windows\system32\drivers>findstr /S /m /l hSeSd *.sys


출처 : 다년간의 프로그램밍 경험 및 http://www.dumpanalysis.org

'scrap' 카테고리의 다른 글

명령어3  (0) 2010.03.18
명렁어4  (0) 2010.03.18
명령어6  (0) 2010.03.18
C++ Project Templete Create  (0) 2010.03.18
LinkError 추적하기  (0) 2010.03.18

안녕하세요 신경준입니다. 어제는 날씨가 여름처럼 덥던데 오늘은 비가올려고 하는지 좀 서늘하네요. 일교차가 심한데 감기 걸리지 않게 조심하세요


 WinDbg에서 제가 생각할때 가장 많이 사용하는 명령어를 간단하게 정리했습니다.


[Debugger Setup : 심볼 설정]

 .sympath : 심볼 경로를 설정하는 명령어입니다.

 .sympath SRV*f:\localsymbols*http://msdl.microsoft.com/download/symbols


 .srcpath : source 경로를 설정하는 명령어 입니다. 

 .srcpath+ \\buildmachine\workspace\project\srt


 .lsrcpath : local 컴퓨터에 있는 source 경로를 설정하는 명령어 입니다.

 .lsrcpath+ c:\workspace\project\src 


 .lines : 디버깅 할때 소스 라인 정보를 보여주거나 보여주지 않게 설정한다.

 .lines -d (disable show source information)

 .lines -e (enable show source information)


 lm : 로드되어있는 모듈 정보를 알아본다.

s이름으로 시작하는 모듈의 정보를 알아낸다.

kd> lm m s*
start    end        module name
f9f73000 f9f7fd80   sysaudio     (deferred)                
fa04b000 fa09b400   srv          (deferred)                
faab7000 faac8500   sr           (deferred)                
facac000 facbae00   serial       (deferred)                
fb008000 fb00ba80   serenum      e:\mysymbols\SereEnum.pdb\.......
fb24f000 fb250000   swenum       (deferred)                

Unloaded modules:
f9f53000 f9f61000   swmidi.sys
fb0ae000 fb0b0000   splitter.sys
fb040000 fb043000   Sfloppy.SYS


!sym noisy 시끄러운 심볼을 로드한다.(이상한 심볼을 로드한다.)

!sym noisy Activates noisy symbol loading. 소란스러운 심볼을 로드하고 적용한다.

!sym quiet Deactivates noisy symbol loading. 소란스러운 심볼을 언로드하고 적용 해제한다.


 

.enable_unicode 1 : 디버깅 과정중에 unicode 스트링을 보여 줄수 있도록한다.

dt 명령어는 물론 Locals window and the Watch window. 에 있는 유니코드도 주소값 또는 hex 값이 아닌 스트링이 보여진다.


x 심볼을 조사해 본다.(Examine Symbols)

아래 명령어 예제는 prymes모듈에서 __n으로 시작하는 함수를 모두 보여주고 해당 심볼의 데이타 타입도 보여주라는 명령어이다.
0:001> x /t prymes!__n*
00427d84 char * myModule!__nullstring = 0x00425de8 "(null)"
0042a3c0 int myModule!_nstream = 512
Type information missing error for _nh_malloc
004021c1 struct MyStruct myModule!MyStructInstance = struct MyStruct
00427d14 <NoType> myModule!_NLG_Destination = <no type information>

'scrap' 카테고리의 다른 글

명렁어4  (0) 2010.03.18
명령어5  (0) 2010.03.18
C++ Project Templete Create  (0) 2010.03.18
LinkError 추적하기  (0) 2010.03.18
SVN 사이트  (0) 2010.03.18

+ Recent posts