1

我目前正試圖圍繞一些Windows旁視列表進行封裝,並且我看到一些內存地址讓我感到困惑。Windows x64(侵入)單鏈表

從另一個問題我貼出來,一些代碼所產生,這要歸功於sergmatoriginal question):

lkd> !lookaside iopsmallirplookasidelist 
Lookaside "" @ 82d5ffc0 "Irps" 
.... 
lkd> dt _SINGLE_LIST_ENTRY 82d5ffc0 
nt!_SINGLE_LIST_ENTRY 
+0x000 Next    : 0x86737e30 _SINGLE_LIST_ENTRY 
.... 
lkd> !pool 0x86737e30 
Pool page 86737e30 region is Nonpaged pool 
*86737e28 size: a0 previous size: 48 (Allocated) *Irp 
    Pooltag Irp : Io, IRP packets 

本質上講可以從上面WinDbg的輸出可以看到,是有在地址單鏈表0x82d5ffc0。此輸出是在32位Windows 7系統上生成的。

但是,這是我感到困惑,在Windows 7 64位系統上執行相同的操作時,這是輸出(地址是明顯不同):

lkd> !lookaside iopsmallirplookasidelist 
Lookaside "" @ fffff80002a14800 "Irps" 
.... 
lkd> dt _SINGLE_LIST_ENTRY fffff80002a14800 
ntdll!_SINGLE_LIST_ENTRY 
    +0x000 Next 0x00000000'01bf0003 
.... 
!pool 0x0000000001bf0003 
Pool page 000000001bf0003 region is unknown  
... 

這樣看來, 0x0000000001bf0003Next值不是一個有效的虛擬地址,我也嘗試在其上執行虛擬到物理的轉換,失敗。

它看起來像這個值是某種頁面偏移量,但我不完全確定如何計算地址。

列表標題中有其他數據,_SLIST_HEADER結構在_SINGLE_LIST_ENTRY之前。它包含以下數據:

Alignment: 0x1bf0003 
Region: 0xfffffa8001df5b01 

初始頭是經過一系列的三個工會,並因爲這是一個64位系統,我相信Header16工會應使用,其中包含此:

Depth: 0x3 
Sequence: 0x1bf 
HeaderType: 0x1 
Init: 0x0 
Reserved: 0x0 
NextEntry: 0xfffffa8001df5b0 

Header16.NextEntry元素確實包含有效的虛擬地址,所以我不確定這是否是下一個列表元素的實際值,或其他。

因此,如果任何人都可以幫助澄清如何在64位系統上計算_SINGLE_LIST_ENTRY.Next元素,我將不勝感激。

感謝

回答

1

的SLIST_HEADER在WDK記載:

typedef union DECLSPEC_ALIGN(16) _SLIST_HEADER { 
    struct { // original struct 
     ULONGLONG Alignment; 
     ULONGLONG Region; 
    } DUMMYSTRUCTNAME; 
    struct { // 8-byte header 
     ULONGLONG Depth:16; 
     ULONGLONG Sequence:9; 
     ULONGLONG NextEntry:39; 
     ULONGLONG HeaderType:1; // 0: 8-byte; 1: 16-byte 
     ULONGLONG Init:1;  // 0: uninitialized; 1: initialized 
     ULONGLONG Reserved:59; 
     ULONGLONG Region:3; 
    } Header8; 
    struct { // ia64 16-byte header 
     ULONGLONG Depth:16; 
     ULONGLONG Sequence:48; 
     ULONGLONG HeaderType:1; // 0: 8-byte; 1: 16-byte 
     ULONGLONG Init:1;  // 0: uninitialized; 1: initialized 
     ULONGLONG Reserved:2; 
     ULONGLONG NextEntry:60; // last 4 bits are always 0's 
    } Header16; 
    struct { // x64 16-byte header 
     ULONGLONG Depth:16; 
     ULONGLONG Sequence:48; 
     ULONGLONG HeaderType:1; // 0: 8-byte; 1: 16-byte 
     ULONGLONG Reserved:3; 
     ULONGLONG NextEntry:60; // last 4 bits are always 0's 
    } HeaderX64; 
} SLIST_HEADER, *PSLIST_HEADER; 

所以,你要的HeaderX64。另外,NextEntry地址在結構中只有60位,並且根據註釋,最後四位始終爲零。所以,這裏是從我的系統中的實例(清理了一下):

1: kd> dt nt!_SLIST_HEADER 0xfffff80001862800 HeaderX64. 
    +0x000 HeaderX64 : 
     +0x000 Depth  : (0x2) 
     +0x000 Sequence : (0x58) 
     +0x008 HeaderType : 0x1 
     +0x008 Reserved : 0x0 
     +0x008 NextEntry : (0xfffffa80038556b) 

添加歸零蠶食到最後:

1: kd> !pool 0xfffffa80038556b0 2 
Pool page fffffa80038556b0 region is Nonpaged pool 
*fffffa80038556a0 size: 130 previous size: 80 (Allocated) *Irp 
     Pooltag Irp : Io, IRP packets