'리버싱' 카테고리의 다른 글
windbg 사용법 (0) | 2016.12.13 |
---|---|
pydbg, python으로 디버거 만들기(1) (0) | 2016.10.12 |
windbg 사용법 (0) | 2016.12.13 |
---|---|
pydbg, python으로 디버거 만들기(1) (0) | 2016.10.12 |
잘 정리됨 ~
http://jangpd007.tistory.com/203
window dump파일 분석법
dll 로딩 시점 bp 걸기
sxe ld (dll이름)
[명령어]
k : 콜스택 보기
.ecxr : 예외가 발생한 상황에 저장된 컨텍스트 레코드를 보여준다(eax, ebx, ecx 등등...)
!analyze -v : Windebug가 자동분석을 해서 많은 정보를 보여준다.
u 주소값: 어셈보기
Command | option | usage | Desc |
종료 | |||
q | 디버깅 종료 | ||
qd | 디버깅 종료;연결해제 | ||
디버깅 환경정보 | |||
vertarget | 타겟 컴퓨터 정보 표시 | ||
version | 디버그 환경 정보 표시 | ||
.lastevent | 마지막 디버그 이벤트 정보 표시 | ||
|| | 디버깅 세션 정보 표시 | ||
sumble & sorurce | |||
.symfix | MS 심볼경로 설정 | ||
.sympath | 심볼경로 확인/설정 | ||
.sym noisy | 심볼파일 검색 과정을 출력 | ||
.srcpath | 소스경로 설정 | ||
.srcnoisy | .srcnoisy 1 | 소스경로 검색 과정을 출력 | |
모듈 | |||
lm | l | 로드된 모듈만 표시 | |
m [pattern] | 패턴과 일치되는 모듈만 표시 | ||
v | 모듈 상세정보 표시 | ||
!lmi | !lmi ntdll.dll | 모듈 상세정보 표시 | |
.reload | /f [m_name] | 심볼을 즉시 로드 | |
x | X ntdll!* | /v | 심볼 타입을 표시. |
X *!*abc* | /t | 데이터 타입을 표시 | |
/n | 이름순으로 정렬 | ||
ln | ln [address] | 해당 주소에 근접한 심볼의 정보 표시 | |
레지스터 | |||
r | 레지스터 정보 표시 | ||
r $proc | 현재 프로세스의 PEB주소( user-mode) | ||
현재 프로세스의 EPROcESS주소( kernel-mode) | |||
r $thread | 현재 스레드의 TEB주소( user-mode) | ||
현재 스레드의 ETHREAD주소( kernel-mode) | |||
r $tpid | 현재 프로세스 ID(PID) | ||
r $tid | 현재 스레드 ID(TID) | ||
언어셈블 | |||
u | 언어셈블 | ||
f | 언어셈블(함수전체) | ||
b | 언어셈블(ip이전의 8개 명령어) | ||
콜스택 | |||
k | [n] | 콜스택 정보표시 | |
p | 함수정보 출력 | ||
b | 인자표시 | ||
n | 프레임번호 | ||
v | FPO정보 표시 | ||
f | 스택 사용량 표시 | ||
break point | |||
bp | bp 0x123456 | bp 설정 | |
bl | bp 리스트 출력 | ||
bc | bc * | [frame_no] | bp 삭제 | |
bd,be | bc * | [frame_no] | bp disable/enable | |
bm | bm notepad!*Win* | 패턴과 일치하는 모든심볼에 bp설정 | |
bu | bu aaa!bbb | 로드되지 않은 심볼에 대한 bp설정 | |
ba | 특정 주소에 access시 bp | ||
지역변수 | |||
dv | dv modulr!test* | ||
/i | 심볼유형과 인자유형 표시 | ||
/V | 변수저장 위치 표시( register or address ) | ||
데이터유형 | |||
dt | df _EPROCESS 0xaddr | 주소를 특정 데이터 형으로 변환해서 표시 | |
du | Unicode string 표시 | ||
da | Ansi string 표시 | ||
dc | |||
db | |||
dy | |||
!address | !address | ||
!address [address] | |||
프로세스 & 스레드 정보 | |||
!peb | PEB(Process Environment Block)표시 | ||
!teb | TEB(Thread Environment Block) 표시 | ||
!gle | API의 마지막 에러코드 표시 | ||
실행 제어 | |||
t | Trace | ||
~.t | 다른 스레드를 중지시킨 상태에서 하나의 statementt실행 | ||
g | |||
p | Step Over | ||
gu | gu | 현재함수가 복귀할 때 까지 실행 | |
~0 gu | 스레드 0을 제외한 모든 스레드를 freeze함 | ||
wt | 내부에서 호출된 함수와 함수호출 횟수등의 정보 표시 | ||
.cxr | 컨텍스트 변경 | ||
!ready | |||
.thread | |||
!thread | |||
.trap | |||
.process | |||
!process | |||
ed | |||
eb | eb .-6 90 90 90 90 90 90 | 6byte를 NOP(0x90)으로 변경 | |
!error | !error [error code] | 에러코드 정보표시 |
출처 : http://blog.naver.com/process3
[심볼관련 사용하는 주요 명령어]
심볼을 로드할 때 사용하는 명령입니다.
보통은 심볼패스를 설정한 후에 .reload 와 같이 사용합니다.
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 에 함께 저장됩니다.~ ^^
GUI환경의 디버깅툴인 windbg 사용법을 알아보자.
일단 각 필요파일들을 download해야겠지?
◎ 필요한 파일들
* windbg 다운로드
32bit버전 : http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx
64bit버전 : http://www.microsoft.com/whdc/devtools/debugging/install64bit.mspx
* 심볼파일 다운로드
http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx
위의 링크에서 각 OS에 맞는 파일 다운로드하여 설치
◎ 설치할때 특별하게 주의할 점은 없다. 모르겠다 싶으면 그냥 "다음(Next)" 버튼만 눌러라.
단, 기억할것은 심볼파일을 설치할때 어디에 설치했는지 잘 봐두도록..
기본설치 위치는 해당 OS폴더 밑의 Symbols이다. 예를 들면 XP인 경우는
"C:\Windows\Symbols"에 설치된다.
◎ 실행방법 및 심볼파일 경로 설정
1. 실행창에서
시작 -> 실행 창 또는 명령프롬프트 창에서 아래와 같이 입력
windbg -y 심볼파일경로 -i OS이미지경로 -z 덤프파일경로
예> windbg -y SRV*C:\Windows\Symbols*http://msdl.microsoft.com/download/symbols -i d:\i386 -z c:\windows\memory.dmp
2. 시작 -> 모든 프로그램 -> Debugging Tools for Windows -> WinDbg 실행
File -> Symbol File Path... 실행
Symbol Search Path창이 뜨면 아래 경로 입력하고 확인 클릭
경로 : SRV*C:\Windows\Symbols*http://msdl.microsoft.com/download/symbols
File -> Image File Path... 실행
OS 이미지 경로입력 (OS CD의 i386에 있음)
File -> Open Crash Dump... 실행
Dump파일 경로 입력
◎ Remote Debugging 방법
* Debugger사용하는 방법
- 서버, 클라이언트 모두 windbg를 설치, 서버측에 심볼파일 설치
1. 서버(debug하려는 기계)셋팅 :
복수사용자(클라이언트) : 콘솔창 : WinDbg -server npipe:pipe=pipename
단일사용자 : WinDbg실행 -> 명령창: .server npipe=pipename
2. 클라이언트 셋팅:
1) WinDbg -remote npipe:server=Server, pipe=Pipename[,password=password]
2) WinDbg 실행 -> File-> Connect to Remote Session 선택
npipe:server=Server,pipe=PipeName[,password=Password]입력
* Remote.exe 사용하는 방법
- 서버, 클라이언트 모두 debugging tool 설치, 심볼파일은 클라이언트 설치
◎ 주요 명령어
참조 :
1. MSDN
2. 네이버 윈도우시스템프로그래밍 카페
할당된 가상메모리 덤프
올리디버거의 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 [표현식]
디버그 레지스터 확인
출처: http://jangpd007.tistory.com/203 [참 놀라운 세상]
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/bp--bu--bm--set-breakpoint-
peach fuzzer (0) | 2016.12.13 |
---|---|
pydbg, python으로 디버거 만들기(1) (0) | 2016.10.12 |
peach fuzzer (0) | 2016.12.13 |
---|---|
windbg 사용법 (0) | 2016.12.13 |