iT邦幫忙

2026 iThome 鐵人賽

DAY 21
0
Security

《Nyahello!從零開始的 30 天 malware 學習日誌》系列 第 21

【Day 21】WinDbg 基本介紹:從 User Mode Debugging 走向 Windows Kernel

  • 分享至 

  • xImage
  •  

前言

前面在學習 Malware Analysis 的過程中接觸到的 debugger 主要是 OllyDbg 與 x64dbg。透過這些工具,我們可以暫停惡意程式、設定 breakpoint、single step 執行指令、觀察 register、stack 和 memory,甚至直接修改 instruction,進一步理解惡意程式實際執行時的行為。

但如果繼續往 Windows Malware Analysis、DFIR,甚至更底層的 Rootkit、Driver 分析前進,就會遇到另一個很重要的工具:WinDbg。

WinDbg 是 Microsoft 提供的 Windows debugger。相較於 OllyDbg 或 x64dbg,它最大的特色之一,就是除了能進行一般的 User Mode Debugging,還可以進行 Kernel Mode Debugging

【聲明】由於時間問題本日文章由 AI 生成QQ


什麼是 WinDbg?

WinDbg 全名可以理解為 Windows Debugger,是 Microsoft Debugging Tools for Windows 中最重要的除錯工具之一。

一般 debugger 的核心概念其實都差不多:

程式原本會由 CPU 不斷執行 instruction,而 debugger 可以介入這個過程,讓我們:

  • 暫停程式
  • 設定 breakpoint
  • 一次執行一條 instruction
  • 查看 CPU registers
  • 查看 stack
  • 查看 memory
  • 反組譯程式碼
  • 觀察 function call
  • 檢查 exception

因此,如果已經使用過 x64dbg 或 OllyDbg,WinDbg 並不是完全不同的世界,真正的差異主要在於它能夠觀察的層級更深

例如使用 x64dbg 分析 malware.exe 時,我們通常是在觀察:

malware.exe
    ↓
Windows API
    ↓
Windows Kernel

我們主要待在 malware.exe 所在的 User Mode。

但有些問題並不能只從 User Mode 看出來。

例如:

Process
Thread
Virtual Memory
Handle
Driver
Kernel Object
System Call
Exception

這些東西都與 Windows 作業系統本身密切相關。

WinDbg 的價值就在這裡。


User Mode 與 Kernel Mode

要理解 WinDbg,首先一定要理解 Windows 的:

User Mode 與 Kernel Mode。

Windows 不會讓一般程式直接擁有最高權限。

一般應用程式,例如:

Chrome
Discord
notepad.exe
malware.exe

基本上都執行在 User Mode

而 Windows 核心以及大部分 Driver 則執行在:

Kernel Mode

可以簡化成:

User Mode
------------------------
malware.exe
notepad.exe
browser.exe
Windows DLL
------------------------
        ↓
   System Call
        ↓
------------------------
Kernel Mode
------------------------
Windows Kernel
Device Driver
Kernel Objects
Memory Manager
Process Manager
------------------------

User Mode 的程式受到很多限制,例如一個普通程式不能隨便讀取 Kernel Memory,也不能直接控制硬體。

Kernel Mode 則具有非常高的權限,這也是為什麼 Kernel Malware / Rootkit / Malicious Driver 特別危險,如果攻擊者成功把惡意程式碼放到 Kernel Mode,它能做到的事情就比普通 User Mode Malware 多很多。

而 WinDbg 正是分析這一層的重要工具。


WinDbg 跟 x64dbg、OllyDbg 有什麼不同?

如果只看基本 debugging 功能,三者其實有不少重疊。

例如都可以:

Disassemble
Breakpoint
Step Into
Step Over
Inspect Registers
Inspect Memory
Inspect Stack

但是定位不同。

OllyDbg 是比較早期、經典的 Windows User Mode Debugger,PMA 使用它作為主要教學工具,x64dbg 則可以視為現在 Reverse Engineering / Malware Analysis 中非常常見的 User Mode Debugger,介面也相對直覺。

WinDbg 的特色則是:

它和 Windows 本身的整合程度非常高。

除了 User Mode Debugging,WinDbg 還能進一步處理:

Kernel Debugging
Crash Dump Analysis
Driver Debugging
Windows Internals
Memory Analysis
Exception Analysis

因此可以簡單理解成:

OllyDbg / x64dbg
        ↓
偏向程式本身的 Reverse Engineering

WinDbg
        ↓
程式 + Windows Operating System

這並不是說 WinDbg 一定比 x64dbg「高級」,而是它們適合的場景不同。

如果只是想快速分析一個普通 Windows Malware,可以先使用 x64dbg。

但如果研究開始碰到:

Windows Internals
Kernel
Driver
Crash Dump
Rootkit
Memory Forensics

WinDbg 的重要性就會快速增加。


Symbol:使用 WinDbg 很重要的概念

第一次使用 WinDbg 時,很容易遇到一個問題:

為什麼畫面裡全部都是地址?

例如:

00007ffb`12345678

單看地址幾乎沒有意義。

我們真正希望看到的是:

kernel32!CreateFileW
ntdll!NtCreateFile
nt!NtCreateProcess

這就需要 Symbol

Symbol 可以幫助 debugger 把:

Memory Address

轉換成:

Module
Function
Variable

之類比較有意義的名稱。

Microsoft 提供 Symbol Server,可以讓 WinDbg 下載 Windows 系統元件需要的 symbol。

WinDbg 常見的 symbol 設定方式是:

.symfix
.reload

.symfix 可以協助設定 Microsoft Symbol Server。

.reload 則重新載入 symbol。

如果 symbol 沒有正確載入,後續分析可能會變得非常痛苦。

所以看到:

*** WARNING: Unable to verify checksum
*** ERROR: Module load completed but symbols could not be loaded

這類訊息時,就要開始注意是不是 symbol 出問題了。


WinDbg 的基本畫面

WinDbg 和 x64dbg 最大的使用體驗差異之一,就是:

WinDbg 非常依賴 Command。

x64dbg 很多事情可以透過 GUI 點擊完成。

WinDbg 雖然也有 GUI,但實際分析時,大量操作還是會直接輸入 command。

例如:

r

查看 registers。

k

查看 call stack。

u

反組譯程式碼。

g

繼續執行。

一開始會覺得很像在背指令,但熟悉之後其實非常快。


Registers

最基本的操作之一就是查看 CPU registers:

r

如果是 x64 process,可能會看到:

rax
rbx
rcx
rdx
rsp
rbp
rsi
rdi
rip

其中最重要的幾個概念包括:

RIP → 下一個要執行的 instruction
RSP → Stack Pointer
RBP → 常被用來協助管理 stack frame
RAX → 常用於 function return value

如果之前已經學過 x86 assembly,這裡的概念基本上是一樣的。

只是 64-bit Windows 會看到:

RAX
RBX
RCX

而不是:

EAX
EBX
ECX

Disassembly

要查看目前附近的 assembly,可以使用:

u

也就是 Unassemble

例如:

u rip

代表從目前 RIP 指向的位置開始進行反組譯。

可能會看到:

mov rax,rcx
test rax,rax
je ...
call ...

這時候做的事情其實就跟 x64dbg 的 Disassembly Window 很像。

我們要觀察:

現在執行到哪裡?
接下來 call 哪個 function?
conditional jump 是否成立?
register 裡面裝了什麼?

Step Into 與 Step Over

Debugger 最基本的操作當然少不了 Single Step。

WinDbg 中常見:

t

代表 Trace

可以理解成 Step Into。

如果目前 instruction 是:

call function

使用 t 就會進入 function。

另一個則是:

p

代表 Step

它的效果比較接近 Step Over。

也就是遇到:

call function

時,不一定要進去 function 裡面一條一條看,而是讓 function 執行完,再停在下一條 instruction。

這和之前在 x64dbg 學到的:

Step Into
Step Over

概念完全相同。


Breakpoint

分析 Malware 時,我們不可能從 Entry Point 開始一條一條執行到最後。

所以 breakpoint 非常重要。

WinDbg 可以使用:

bp address

設定 software breakpoint。

例如:

bp 00007ff6`12345678

但如果 symbol 已經正確載入,更方便的方法是:

bp kernel32!CreateFileW

這樣程式呼叫 CreateFileW 時就會停下來。

對 Malware Analysis 而言這非常有用。

例如懷疑 malware 正在建立檔案,就可以觀察:

CreateFile
WriteFile
DeleteFile

如果懷疑它修改 Registry,就可以進一步追蹤相關 API。

如果懷疑它建立 process,也可以針對 process creation 相關函式進行觀察。

列出目前 breakpoint:

bl

刪除 breakpoint:

bc

Disable breakpoint:

bd

Enable breakpoint:

be

因此可以記成:

bp → breakpoint
bl → breakpoint list
bc → breakpoint clear
bd → breakpoint disable
be → breakpoint enable

查看 Memory

Malware Analysis 中另一個非常重要的能力就是:

看 Memory。

WinDbg 提供很多 d 開頭的 command。

例如:

db

以 byte 顯示。

dw

以 word 顯示。

dd

以 double word 顯示。

dq

以 quad word 顯示。

如果想看字串,也可以使用:

da

查看 ASCII string。

或者:

du

查看 Unicode string。

這在 Malware Analysis 特別實用。

例如 register 裡面出現一個 pointer:

RCX = 000001F234567890

單看地址沒有意義。

這時候可以:

du rcx

如果結果出現:

C:\Users\...\AppData\malware.exe

就知道 RCX 指向的是一段 Unicode string。

因此分析 assembly 時不要只看:

RCX = 0x000001F234567890

而要繼續追:

這個 address 指向什麼?

這就是 debugger 中非常重要的思考方式。


Call Stack

另一個非常重要的 command 是:

k

它會顯示目前 thread 的 Call Stack

假設看到:

malware!FunctionC
malware!FunctionB
malware!FunctionA
kernel32!BaseThreadInitThunk
ntdll!RtlUserThreadStart

我們就可以大概理解:

FunctionA
   ↓
FunctionB
   ↓
FunctionC
   ↓
現在停在這裡

這比只看目前 RIP 有用很多。

因為 RIP 只能告訴我們:

「現在在哪。」

Call Stack 則可以幫助回答:

「我是怎麼走到這裡的?」

這對 Reverse Engineering 和 Malware Analysis 都非常重要。


Module

Windows Process 通常不只有自己的 EXE。

還會載入大量 DLL,例如:

ntdll.dll
kernel32.dll
KernelBase.dll
user32.dll
advapi32.dll

WinDbg 可以使用:

lm

查看 Loaded Modules。

lm 可以理解成:

List Loaded Modules

如果只想看特定 module,也可以搭配其他參數進一步查詢。

在 Malware Analysis 中,module 資訊可以幫助我們理解:

程式載入了哪些 DLL?
目前 address 屬於哪個 module?
某個 function 位於哪裡?
是否出現可疑 module?

Exception 與 Crash Dump

WinDbg 還有一個非常重要的用途:

Crash Analysis。

Windows 發生:

Access Violation
Blue Screen
Application Crash
Driver Crash

時,可以產生 dump file。

WinDbg 可以直接分析這些 dump。

其中最有名的 command 大概就是:

!analyze -v

它會針對目前的 crash 資訊進行分析,提供:

Exception
Faulting Module
Stack
可能的問題位置

這也是 WinDbg 在 Malware Analysis 之外,被 Windows Developer、Driver Developer、Incident Responder 使用的重要原因。


Extension Commands

前面有些 WinDbg command 前面有:

!

例如:

!analyze

這些通常屬於 Extension Commands

在 Kernel Debugging 中,會大量看到這類 command。

例如可以查詢:

Process
Thread
Handle
Virtual Memory
Kernel Object

這也是 WinDbg 真正開始展現威力的地方。

當分析不再只是:

這一條 MOV 在做什麼?

而開始變成:

這個 Process 的 Windows 結構是什麼?
這個 Thread 現在在哪?
這段 Virtual Memory 屬於誰?
這個 Driver 載入在哪?

就已經開始從單純的 Reverse Engineering,逐漸進入 Windows Internals 的領域。


WinDbg 對 Malware Analysis 有什麼用?

學到這裡可能會有一個問題:

如果 x64dbg 已經可以分析 malware,為什麼還要學 WinDbg?

我的理解是,兩者並不是替代關係。

如果分析普通 User Mode Malware:

Static Analysis
        ↓
IDA / Ghidra

Dynamic Analysis
        ↓
x64dbg

其實已經可以完成大量工作。

但如果研究方向逐漸往:

Advanced Malware
Rootkit
Kernel Malware
Malicious Driver
EDR
Windows Internals
Memory Forensics

發展,就會越來越需要理解 Windows 底層。

例如 Malware 可能透過:

Process Injection
API Hooking
Direct System Call
Driver
Kernel Manipulation

來逃避偵測。

如果只停留在 Windows API 層,很容易只看到:

「Malware 呼叫了某個 API。」

但不知道這個 API 往下究竟發生了什麼事情。

WinDbg 則提供了一條繼續往下看的路。


WinDbg 與 Threat Hunting

WinDbg 和 Threat Hunting 看起來好像距離很遠。

Threat Hunter 通常不會每天開 WinDbg 分析 endpoint。

但是理解 WinDbg 背後的概念,對 Threat Hunting 仍然非常重要。

因為很多 endpoint telemetry 最後都與 Windows Internals 有關:

Process
Thread
Module
Handle
Memory
Token
Driver
Registry
System Call

如果不知道 Windows 怎麼管理這些東西,就容易只停留在:

看到 Event ID → 查 Event ID
看到 Alert → 查 Alert

而比較深入的 Threat Hunting,需要進一步理解:

這個 telemetry 為什麼會產生?
正常 Windows 行為應該長什麼樣子?
Malware 改變了哪個行為?
EDR 又是從哪一層看到這件事情?

結語

從 x86/x64 Assembly 開始,到 Registers、Stack、Memory、Breakpoint、Single Step、Call Stack,這些概念全部都可以直接延續到 WinDbg。

從中增加的是:

我們開始不只分析一支程式,而是開始理解這支程式所在的 Windows。

前面的問題可能是:

這支 Malware 做了什麼?

但繼續深入之後,可以去探討:

它利用 Windows 的什麼機制做到這件事?

甚至進一步變成:

如果我是 Defender,我可以從 Windows 留下的哪些 artifacts 或 telemetry 發現這個行為?

參考資料

  • Practical Malware Analysis (Chapter 10)
  • chatGPT

本日貓味

https://ithelp.ithome.com.tw/upload/images/20260916/20183878BbNIL2jKoa.jpg


上一篇
【Day 20】雜談:想成為 malware analyst 的 roadmap
下一篇
【Day 22】Kernel Debugging in Practice:實際追蹤 User Mode 與 Kernel Mode 的惡意程式行為
系列文
《Nyahello!從零開始的 30 天 malware 學習日誌》28
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言