Windbg 指令與分析之教學筆記

追朔根源就是微軟的工具, 因此必須閱讀官方手冊:
1. 微軟教學:Debugging Tools for Windows (WinDbg, KD, CDB, NTSD)
2. 微軟教學: ACPI Debugging
3. 微軟教學: Getting Started with WinDbg (Kernel-Mode)
4. 微軟說明:debugger commands

有幾個系列的影片教學, 可以身歷其境的感受一下 windbg的強大, 分別是:
1. 影片教學: WinDbg Basics for Malware Analysis
2. 影片教學: Windows Kernel Programming Tutorials for Beginners

3. 教學 Remote debugging

4. 微軟教學影片: Debugging KMDF Drivers

其他在網路上的先進們分享知識的 Windbg專欄部落格:
1. hgy413的专栏windbg
2. 匠心十年: WinDbg 命令手册

或是特別說明一些其他技巧與步驟, 小軟體工具之類:
1. symbol: WinDbg 設定 symbol file path 的四種方法

先知道格式吧:
srv*{cache path}*{symbol server}

我的寫法填入Windbg GUI下拉的Sympol File Path:
srv*C:\Symbol*https://msdl.microsoft.com/download/symbols

2. symbol: 使用SymChk獲取符號文件
3. PDB: 你可能會想知道的關於 .PDB 檔的一些事
4. break point: WinDBG 技巧:设断点命令详解(bp, bu, bm, ba 以及bl, bc, bd, be)
5. BSOD情況分析: Trace BSOD with WinDbg
6. 如何進安全模式:幾種 Windows 10 進入安全模式的方法
因為有時候無法開機的原因,可能是系統中的某些驅動程式出了問題,或是在載入某些開機時要一起載入的程式,導致無法開機。而當我們選用安全模式啟動時,僅載入開機時最必要的檔案,其它多餘的檔案、驅動程式一律都不載入,因此如果無法進入Windows桌面是這方面問題所導致的,那麼用安全模式就應該可以順利排除問題,讓你可以進入Windows系統桌面。

7.什麼是SysWow64: SysWow64檔夾,是64位Windows用來存放32位元Windows系統檔的地方。
8.win10的快速啟動是什麼:win10電腦的「快速啟動」模式你知多少?
9.基本:9招解決 Windows 系統問題或故障,不用靠別人、自己來搞定

一些有用的工具:

1. 小軟體: BlueScreenview
2. 小軟體: Windows Repair
3. 小軟體: CCleaner
4. 微軟 Process explorer: 類似Windows「工作管理員」的程式,主要功能就是列出目前電腦中正在運行的全部程式以及跟運行中程式相關的全部詳細資料

5. 微軟 Process dump: 命令行工具, 它的主要目的是監控應用程序的CPU異常動向, 並在此異常時生成crash dump文件, 供研發人員和管理員確定問題發生的原因.你還可以把它作為生成dump的工具使用在其他的腳本中.ProcDump與Procexp一樣是Windows平台上的內部調試工具,Procexp採用圖形界面體現系統整體及個別進程的性能信息,而ProcDump則與我們在Unix平台上使用的性能分析工具類似使用CLI命令行界面。

6. 微軟 LiveKD:使用Microsoft內核調試器檢查系統。

Windbg 基本操作指令:

  • 開啟crash dump檔案路徑為 File > Open crash dump
  • 以下指令載入symbols:
  • .symfix C:\symbols: 設定local端的symbol目錄位置
  • .reload : 重載一次
  • .sympath : 顯示目前的symbol path

Windbg一般與幫助指令:

指令: ?
顯示說明基本的各種輸入常規指令

指令: .help
說明系統指令
第一排還有快速連結個字母開頭的

指令:.chain
列出所有已加載的調試器擴展 (List Debugger Extensions)

指令: .extmatch
.extmatch /D /e XXXXX * 顯示由當前加載的與指定模式匹配的擴展DLL導出的擴展命令

指令:.hh
打開 WinDbg 的幫助文件

指令: .restart
重新啟動被調試的應用程式(Restart Target Application)

指令: version
顯示調試器版本信息和已加載的調試器擴展

指令: vercommand
顯示調試器啟動文件的路徑

指令: vertarget
顯示目標機器Microsoft Windows操作系统版本資訊

指令: .effmach
顯示目標機器的處理器模資訊
.effmach .
.effmach #
.effmach x86 | amd64 | ia64 | ebc

指令: .cls
清理螢幕

指令: .echo
輸出字串 e.g. .echo “Hello World”

指令: .time
顯示系統記錄的各種時間

組合鍵: ctrl+alt+v
能切換詳細模式的打開和關閉
打開詳細模式後,一些顯示命令會產生更詳細的輸出,發送給調試器的每個模塊加載操作都會被顯示出來
並且操作系統每次加載驅動或都DLL也會提示

Windbg 模塊Module加载命令

指令: lm
列出已載入模塊(List Loaded Modules)
lm: List modules
lmv: List module versions
lmvm: List specific module versions
lm m ModuleName

指令: !dlls
列出所有加載的模塊和加載數量

指令: !lmi
显示模块的详细信息,包括加载符号信息
!lmi Module

Windbg 符号Symbol加载命令

指令 ld
加載指定模塊的符號 (Load Symbols), 注意藥此symbol的module是已經載入, 若未載入就先lm該module吧 (範例參考:lm ld x)
ld * 加載所有模塊的符號

指令 x
搜尋匹配的符号資訊(Examine Symbols)
x [Options] ModuleName!SymbolName 以!為界module與symbol
用法:
x *! 列出所有模块Module

x ntdll!a* 列出 ntdll 模块底下所有a開頭的symbol

指令!sym
獲取符號加載狀態
!sym noisy 讓調試器顯示符號搜索詳細信息
!sym quiet 默認項,不顯示符號搜索信息

指令.sympath
顯示和設置符號搜索路徑
.sympath+ 增加符號搜索路徑
.sympath+ C:\Symbols

指令.symfix
設置符號庫路徑
.sym+ DownstreamStore 添加符號庫路徑

指令 .reload
重新加載符號信息

Windbg 異常分析指令:

指令: dump
.dump d:/test.dump
也就是說可以透過windbg來產生dump檔案
e.g.
產生完整Kernel Mode Dump :
.dump /f C:\memory.dmp

產生 user mode Dump:
.dump /m C:\memory.dmp

產生 User mode + 其他資訊:
.dump /mfh C:\memory.dmp

指令: !analyze
!analyze -v
顯示當前異常的詳細信息
e.g. !analyze –v d:\test.dump

!analyze -hang
診斷線程調用棧上是否有任何線程阻塞了其他線程

!analyze -f
查看異常分析信息,儘管調試器並未診斷出異常

指令: .lastevent
显示最近一次发生的异常或事件

指令: .load wow64exts
指令: !wow64exts.sw
從64位模式切換到了32位

指令: !locks
顯示目前 locks 鎖

指令: !qlocks
顯示目前 spinlock鎖

Windbg 關於memory的指令

指令dt (Display Type)
dt ntdll!*IMAGE* :查找有什麼Headers
以下例子是 notepad在memory查找出PE header的位址, 然後透過dt指令就可以查到定義的結構內容:

指令: .Dvalloc
讓 Windows 以分配到目標進程的更多memory。

指令: r
显示或修改寄存器、浮点寄存器、标志位、伪寄存器和预定义别名。直接用r,会显示当前线程的寄存器状态

指令: d*
显示给定范围memory的内容。
da ASCII 字符
db 字节值和ASCII字符

指令: e*
e命令和d命令非常相似,一個讀取一個寫入編輯
ea ASCII 字符串(不以NULL结尾)。
eb 字节值。

指令u* :
命令显示指定的内存中的程序代码的反汇编。如果要反汇编某一个地址,直接用u命令加地址
ub 指示要反汇编的区域是向后计算的。
uf 命令显示内存中指定函数的反汇编代码。

指令x:
命令显示所有上下文中匹配指定模板的符号。可用字符通配符

指令: s (Search Memory)
搜索内存查找指定模板

指令: dt:
命令显示局部变量、全局变量或数据类型的信息。它也可以仅显示数据类型。即结构和联合(union)的信息
dt最方便处是查找结构体,查找结构体一定要使用dt,不要使用x
PE文件解析
1.dos头:
0:001> dt IMAGE_DOS_HEADER 01230000
2.nt头
e_lfanew定义了真正的PE文件头的相对偏移量RVA
0:001> da 01230000 +0n224
012300e0 “PE”
0:001> dt IMAGE_NT_HEADERS 01230000 +0n224
3.文件头
0:001> dt IMAGE_FILE_HEADER 01230000 +0n224+0x4
4.扩展文件头
0:001> dt _IMAGE_OPTIONAL_HEADER 01230000 +0n224+0x18

指令: dh
!dh 擴展顯示指定映像的頭部。

指令:!address
顯示整個地址空間和使用摘要的信息

指令: !vadump : 這個會顯示所有的虛擬內存區域和它的保護屬性

指令: !runaway : 顯示每個Thread消費的時間
  Bit 0 (0x1) 讓調試器顯示每個Thread消耗的用戶模式時間(user time),默認不加就是0x1
  Bit 1 (0x2) 顯示每個Thread消耗的內核時間(kernel time)。
  Bit 2 (0x4) 顯示每個Thread從創建開始經歷了多少時間。

Windbg 關於process的指令:

指令: |
顯示當前Process的信息

指令: !dml_proc
顯示當前Process的信息

指令: .tlist
顯示本機當前所有Process

指令: process
!process 0 0 顯示進程列表

Windbg 關於thread的指令:

指令: ~ (Thread Status):
波形符(~) 命令显示指定线程或当前进程中的所有线程的信息, ~和~*还是有点区别的,~*会把入口函数和优先级都打印出来

指令: ~
顯示所有thread信息

指令: ~*
顯示所有thread

指令: ~.
顯示當下thread

指令: ~# 引發當前事件或異常的thread
指令: ~Number 顯示指定序號的thread
指令: ~* k 顯示所有thread的調用棧
指令: ~2 f 凍結2號thread
指令: ~# f 凍結引發異常的thread
指令: ~3 u 解除對3號thread的凍結
指令: ~2 k 顯示2號thread的調用棧
指令: ~0s 切換到 thread 0

指令: !thread
擴展顯示目標系統中線程包括ETHREAD塊在內的摘要信息。該命令只能在內核模式調試下使用

Windbg 關於Stack的指令

指令: k*:
命令顯示給定Thread的調用Stack,以及其他相關信息
~0 k表示顯示0號Thread的調用Stack,直接用k表示打印當前Thread的調用堆棧
kb 顯示傳遞給Stack回溯中的每個函數的前三個參數
kp 顯示傳遞給Stack回溯中的每個函數的所有參數

指令: !findstack
擴展查找包含指定符號或模塊的所有stack

Windbg腳本

指令: .foreach
分析一個或多個命令的輸出並將該輸出中每一個值作為另一個或多個命令的輸入
.foreach [Options] ( Variable { InCommands } ) { OutCommands }

指令: .printf
和C中的printf 语句类似

各種分析情況劇情:

可參考: ephrain
分析 Stack overflow (recursive)
分析 .NET framework process crash
分析 WoW64 process
分析 memory leak
分析 infinite wait
分析 kernel dump
分析 kernel dump for memory problem
分析 complete kernel dump

發表迴響