WinDBG遍歷 LIST ENTRY鍊錶

2021-09-28 19:11:40 字數 4281 閱讀 1214

因為window不同版本的核心資料結構有所不同,先宣告實驗環境。本實驗在window7 32位系統下並且執行運算器(calc.exe)測試。為了顯示的資訊不至於冗長,在開始實驗前先講講dt命令的-y引數及exptimerresolutionlisthead全域性變數。

1、dt命令檢視_eprocess結構及-y引數

lkd> dt nt!_eprocess

+0x000 pcb              : _kprocess

.....

+0x0e4 sessionprocesslinks : _list_entry

.....

+0x16c imagefilename    : [15] uchar

+0x17b priorityclass    : uchar

......

+0x2a8 timerresolutionlink : _list_entry

+0x2b0 requestedtimerresolution : uint4b

+0x2b4 activethreadshighwatermark : uint4b

+0x2b8 smallesttimerresolution : uint4b

+0x2bc timerresolutionstackrecord : ptr32 _po_diag_stack_record

+0x2c0 sequencenumber   : uint8b

+0x2c8 createinterrupttime : uint8b

+0x2d0 createunbiasedinterrupttime : uint8b

注意偏移量為+0x16c imagefilename    : [15] uchar和 +0x2a8 timerresolutionlink : _list_entry

-y表示匹配[imagef*]的列出來,不使用-y引數就是必須全匹配

lkd> dt nt!_eprocess imagefilename

+0x16c imagefilename : [15] uchar

lkd> dt nt!_eprocess -y image

+0x16c imagefilename : [15] uchar

+0x19c imagepathhash : uint4b

+0x270 imagenotifydone : pos 22, 1 bit

用命令dt顯顯示我們關注的兩個域

lkd>  dt nt!_eprocess imagefilename  timerresolutionlink

+0x16c imagefilename       : [15] uchar

+0x2a8 timerresolutionlink : _list_entry

2、exptimerresolutionlisthead全域性變數

+0x2a8 timerresolutionlink域是將所有修改過定時器解析度的程序,通過雙向鍊錶exptimerresolutionlisthead連線起來。在_eprocess中雙向鍊錶域很多比如:activeprocesslinks、joblinks等,而timerresolutionlink 這個域資料量比較小便於顯示。

3、dt遍歷list_entry

dt  [module!]name [[-searchopts] field] [address] [-l list]  address是 [module!]name的首位址,list是網域名稱

例如:lkd> dt _eprocess -y imagef exptimerresolutionlisthead-2a8 -l timerresolutionlink.flink 

ntdll!_eprocess

timerresolutionlink.flink at 0x83f47438

---------------------------------------------

+0x16c imagefilename : [15]  "???"

+0x2a8 timerresolutionlink :  [ 0x889545f8 - 0x87470880 ]

timerresolutionlink.flink at 0x88954350

---------------------------------------------

+0x16c imagefilename : [15]  "calc.exe"

+0x2a8 timerresolutionlink :  [ 0x87470880 - 0x83f476e0 ]

0x83f47438不是鍊錶的位址,而是鍊錶所在的_eprocess 的首位址 。通過dt -l命令就可以把修改過定時器解析度的程序遍歷出來。

我們也可以用別的域遍歷如:activeprocesslinks

lkd> dt _eprocess -y imagef poi(psinitialsystemprocess) -l activeprocesslinks.flink

結果比較長不展示了。

4、!list命令遍歷list_entry

以遍歷所有修改過定時器解析度的程序為例。程序結構體中有一域timerresolutionlink,它可以把所有修改過定時器解析度的程序連線起來的雙向鍊錶,而該雙向鍊錶的表頭exptimerresolutionlisthead全域性變數。

lkd> !list -t nt!_list_entry.flink -e -x "dt nt!_eprocess -y imagef @$extret-2a8" nt!exptimerresolutionlisthead

dt nt!_eprocess -y imagef @$extret-2a8 

+0x16c imagefilename : [15]  "???"

dt nt!_eprocess -y imagef @$extret-2a8 

+0x16c imagefilename : [15]  "calc.exe"

nt!_list_entry.flink遍歷的資料型別,-e每次找到乙個節點就執行引號裡面的命令,-x "dt nt!_eprocess -y imagef @$extret-2a8"要執行的命令是顯示程序結構體中的imagefilename 資訊, @$extret是乙個偽暫存器,表示每次找到乙個節點後,list_entry在該節點中的具體位址就是@$extret的值,而2a8就是該域相對_eprocess的偏移。nt!exptimerresolutionlisthead就是煉表頭。

還可以用這個命令來做,只是這個命令解釋起來比較拗口

lkd> !list -t nt!_eprocess.timerresolutionlink.flink -e -x "dt nt!_eprocess -y imagef @$extret" nt!exptimerresolutionlisthead-2a8

dt nt!_eprocess -y imagef @$extret 

+0x16c imagefilename : [15]  "???"

dt nt!_eprocess -y imagef @$extret 

+0x16c imagefilename : [15]  "calc.exe"

nt!exptimerresolutionlisthead-2a8這個是_eprocess的位址,nt!_eprocess.timerresolutionlink.flink是list_entry結構,是_eprocess下的特定結構,@$extret偽暫存器的值就變成了_eprocess節點。

也可以嘗試這個命令lkd> !list -t nt!_list_entry.flink -e -x "dt nt!_eprocess -y imagef @$extret-b8" nt!psactiveprocesshead顯示活動程序。

網上有些把引數雜糅在一起的命令,如:!list -t nt!_eprocess.timerresolutionlink.flink -e -x "dt nt!_eprocess -y imagef @$extret-2a8" nt!exptimerresolutionlisthead

執行起來就預想不到結果了:

lkd> !list -t nt!_eprocess.timerresolutionlink.flink -e -x "dt nt!_eprocess -y imagef @$extret-2a8" nt!exptimerresolutionlisthead

dt nt!_eprocess -y imagef @$extret-2a8 

+0x16c imagefilename : [15]  "???"

有興趣的朋友也可以把!list命令中的type、偽暫存器、偏移和首位址進行試驗,更能理解!list命令的引數意義。

windbg遍歷程序頁表檢視記憶體

2016 12 09 近期想檢視下系統分配了的頁的頁表項的標誌位,但是發現資料較少,所以還是記錄下,希望可以對某些朋友有所幫助!系統 win7 32位虛擬機器 平台 kvm虛擬化平台 win7 32位預設是開啟了pae分頁模式的,pae分頁模式本質上和普通的32位分頁並無區別,只是頁表結構和虛擬位址...

windbg 用WinDbg探索ruby的奧秘

寫這篇文章是受 url 從main.c開始走進ruby 登上除錯ruby之旅 url 的啟發,不同的是該文章用的是gdb,gdb雖然很強大,但是畢竟是命令列,在除錯的時候,可能同時需要檢視許多資訊,比如call statck,彙編 源 等等,命令列就有點力不從心,所以續寫一篇,改gdb為同樣強大的w...

Windbg斷點命令

windbg斷點命令 1 bu bp bm設定軟體斷點 a bp設定位址關聯的斷點 b bu設定符號關聯的斷點 c bm支援設定含萬用字元的斷點,可以一次建立乙個或多個bu或bp bm d 斷點 bp和bu的主要區別 a bp所設斷點和位址關聯,如果模組把該位址的指令移到其它地方,斷點不會隨之移動,...