共用方式為


對應符號 當 PEB 分頁時

若要載入符號,偵錯工具會查看作業系統所載入的模組清單。 使用者模式模組清單的指標是程式環境區塊中儲存的其中一個專案, (PEB) 。

若要回收記憶體,記憶體管理員可能會分頁出使用者模式資料,讓其他進程或核心模式元件有空間。 分頁出的使用者模式資料可能包含 PEB 資料結構。 如果沒有此資料結構,偵錯工具就無法判斷要載入符號的影像。

注意 這只會影響使用者模式模組的符號檔。 核心模式模組和符號不會受到影響,因為它們會在不同的清單中追蹤。

假設使用者模式模組已對應到目前的進程,而您想要修正它的符號。 在模組的虛擬位址範圍內尋找任何位址。 例如,假設模組對應到包含位址 7f78e9e000F 的虛擬位址範圍。 輸入下列命令。

3: kd> !vad 7f78e9e000F 1

命令輸出會顯示模組的虛擬位址描述元 (VAD) 的相關資訊。 命令輸出也包含重載命令字串,可用來載入模組的符號。 Reload 命令字串包含記事本模組 (000007f7'8e9e0000) 和大小 (32000) 。

VAD @ fffffa80056fb960
...
Reload command: .reload notepad.exe=000007f7`8e9e0000,32000

若要載入符號,請輸入重載命令字串中提供的命令。

.reload notepad.exe=000007f7`8e9e0000,32000

以下是另一個使用稍微不同技巧的範例。 此範例示範如何在分頁 PEB 時使用 !vad 延伸模組來對應符號。基本概念是尋找相關 DLL 的起始位址和大小,以便您接著使用 .reload 命令載入必要的符號。 假設目前進程的位址0xE0000126'01BA0AF0,而且您想要修正它的符號。 首先,使用 !process 命令來取得虛擬位址描述元, (VAD) 根位址:

kd> !process e000012601ba0af0 1
PROCESS e000012601ba0af0
    SessionId: 2  Cid: 0b50    Peb: 6fbfffde000  ParentCid: 0efc
    DirBase: 079e8461  ObjectTable: e000000600fbceb0  HandleCount: 360.
    Image: explorer.exe
    VadRoot e000012601a35e70 Vads 201 Clone 0 Private 917. Modified 2198. Locked 0.
...

然後使用 !vad 延伸模組來列出與進程相關聯的 VAD 樹狀結構。 標示為「EXECUTE_WRITECOPY」的 VAD 屬於程式碼模組。

kd> !vad e000012601a35e70
VAD     level      start      end    commit
...
e0000126019f9790 ( 6)      3fff0    3fff7        -1 Private      READONLY
e000012601be1080 ( 7)   37d9bd30 37d9bd3e         2 Mapped  Exe  EXECUTE_WRITECOPY  <-- these are DLLs
e000012600acd970 ( 5)   37d9bec0 37d9bece         2 Mapped  Exe  EXECUTE_WRITECOPY
e000012601a5cba0 ( 7)   37d9c910 37d9c924         2 Mapped  Exe  EXECUTE_WRITECOPY
...

然後再次使用 !vad 擴充功能來尋找分頁記憶體的起始位址和大小,其中包含感興趣的 DLL。 這會確認您已找到正確的 DLL:

kd> !vad e000012601be1080 1

VAD @ e000012601be1080
  Start VPN:      37d9bd30  End VPN: 37d9bd3e  Control Area:  e00001260197b8d0
  First ProtoPte: e0000006013e00a0  Last PTE fffffffffffffffc  Commit Charge         2 (2.)
  Secured.Flink          0  Blink           0  Banked/Extend:        0
  File Offset   0
   ImageMap ViewShare EXECUTE_WRITECOPY

...
        File: \Windows\System32\ExplorerFrame.dll

[啟動 VPN] 欄位 - 在此案例中,0x37D9BD30 - 表示起始的虛擬頁碼。 這必須轉換成實際位址,方法是將它乘以頁面大小。 您可以使用 ? (Evaluate Expression) 命令,將此值乘以 0x2000,這是範例所來自 Itanium 電腦的頁面大小。

kd> ? 37d9bd3e*2000 
Evaluate expression: 7676040298496 = 000006fb`37a7c000

然後,範圍的大小可以轉換成位元組:

kd> ? 37d9bd3e-37d9bd30+1 <--   computes the number of pages
Evaluate expression: 15 = 00000000`0000000f
kd> ? f*2000
Evaluate expression: 122880 = 00000000`0001e000        

因此,ExplorerFrame.dll 從位址0x000006Fb'37A7C000 開始,且0x1E000位元組很大。 您可以使用:

kd> .reload /f ExplorerFrame.dll=6fb`37a7c000,1e000