티스토리 뷰

C++/Debugging

Windbg 사용법

엘키 2010. 3. 30. 13:47
참고 자료

Windbg Tutorial
http://www.codeproject.com/KB/debug/windbg_part1.aspx

Windows에서 디버깅을 위해 만든 작은 메모리 덤프 파일을 읽는 방법
http://support.microsoft.com/default.aspx?scid=kb;ko;315263

Windbg로 덤프 남기는법
http://msdn.microsoft.com/en-us/library/ff562428.aspx

잊지 말아야 할 점은, windbg는 symbol과 source code의 매칭을 해주지 않는다.
반드시 Symbol File Path와, Source File Path 메뉴 에서 경로를 제대로 지정해주어야, 덤프 분석시 정보가 제대로 출력된다. 

windbg shell command

덤프 생성
.dump /f C:\경로\파일명.dmp

덤프 정보 분석
!analyze [-v] 

지역변수 보기
dv 

콜스택 보기
kb 

콜스택에 번호 매겨서 보기
kn 

스택 프레임 번호에 맞추기 (0번부터 시작)
.frame [번호]

Display Exception Context Record
.ecxr

레지스터 보기
r

디스 어셈블해서 보기
u [주소]

직접 메모리 내용 보기
dd [주소]

메모리의 내용과 심벌을 일치시켜 보여준다.
dds [주소]

프로세스 리스팅
!process 0 0

프로세스 어태치 시키기
.process /i [pid]


할당된 가상메모리 덤프

올리디버거의 Memory Map윈도의 기능

!vadump [-v]


해당메모리 주소가 어떤 속성인지 알려줌

 !vprot [주소]


현재 프로세스내에 동작중인 스레드의 스택을 보여줌

 !uniqstack [-b]

-b옵션을 주면 스택에 담긴 아규먼트까지 보여준다


현재 스레드에 할당된 권한(Privilege)를 보여줌

!token


각 스레드가 동작한 시간

 !runaway


레지스트리 정보 확인

 !dreg

예) 0:000> !dreg System\CurrentControlSet\Services\Tcpip!*


해당 주소를 UNICODE_STRING구조체 형식으로 살펴봄

!ustr [주소]

 typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING;


해당 주소를 ANSI_STRING혹은 OEM_STRING구조체로 살펴봄

!str [주소]

 typedef struct _STRING {
    USHORT Length;
    USHORT MaximumLength;
    PCHAR Buffer;
} STRING;
typedef STRING ANSI_STRING;
typedef STRING OEM_STRING;



스레드 로컬 스토리지 슬롯을 살펴봄

!tls

모든 슬롯 출력

예) !tls -1

Specifies the thread environment block (TEB). If this is 0 or omitted, the current thread is used

예) !tls 0


현재 스레드의 TEB정보를 출력

!teb


현재 프로세스의 PEB정보를 출력

!peb


잘 알려진 몇몇 STL템플릿정보를 출력

!stl


로딩된 dll모듈의 베이스주소와 길이 모듈명을 출력한다

lm


해당모듈의 자세한 정보를 출력

!lmi [모듈]

예) !lmi 00400000


반복적인 디버거명령을 실행시키면서, 링크드리스트 정보를 출력함

!list

예) !list "-t ntdll!_LIST_ENTRY.Flink -e -x \"dd @$extret l4; dt ntdll!_RTL_CRITICAL_SECTION_DEBUG @$extret-0x8\" ntdll!RtlCriticalSectionList"


현재 Shared User-mode Page를 출력함

현재 타임존과 시스템루트, TickCount와 시간을 출력함

!kuser


로드된 모듈들의 리로케이션되기전의 주소를 출력한다

!imgreloc [주소]


최근 에러코드를 리턴한다

!gle


에러코드를 가지고 무슨 에러인지 설명을 보여준다

!error [에러코드번호]


글로벌 플래그를 설정 혹은 보여준다

!gflag


로드된 모듈들에 대한 커스터마이징(?)된 출력을 해준다.

!for_each_module ["명령어"]

예) !for_each_module .echo @#ModuleIndex : @#Base @#End @#ModuleName @#ImageName  @#LoadedImageName

로드된 모듈에서 MZ로 시작되는것을 찾는다
예) !for_each_module s-a @#Base @#End "MZ"


가상메모리에서 이미지헤더를 검색한다 (MZ검색)

.imgscan


표현식을 헥사, 8진수, 2진수, 시간형, Float형, Double 형으로 변환한 형태로 보여준다

.formats [표현식]

디버그 레지스터 확인
0:000> rm 0x20;r
dr0=00000000 dr1=00000000 dr2=00000000
dr3=00000000 dr6=00000000 dr7=00000000
ntdll!KiFastSystemCallRet:
7c93eb94 6a01            push    1

범용레지스터 확인
0:000> rm 0x01;r
eax=00000000 ebx=00000000 ecx=00000006 edx=7c9ac080 esi=7c93e88e edi=00000000
eip=7c93eb94 esp=0007fde8 ebp=0007fee4 iopl=0         nv up ei pl zr na pe nc
ntdll!KiFastSystemCallRet:
7c93eb94 6a01            push    1

레지스터 값 변경
r eip=7c931230 
r eax = @ebx
r zf=0


특정 주소에 어셈블 코드 삽입
a <위치>
예) a eip
00401000    sub esp, 10


특정 주소에 원하는 값 삽입
e[옵션] <주소>
예) eb <주소>
00401000 90
00401001 90
00401002 90


현재 보여주는 숫자의 진수바꾸기
n <base>
예) n 8
예) n 16       # 16진수
예) n 10       #10진수로 보여줌


메모리가 참조하고 있는 데이터를 살펴보기
예) dpa esp             현재 스택을 아스키형태로 보여줌
예) dpu esp             현재 스택을 유니코드형태로 보여줌


메모리의 내용을 심벌과 매핑시켜서 보여줌
예) dds esp            현재 콜 스택을 보여줌


댓글