我目前正试图围绕一些Windows旁边列表,我看到一些令我困惑的内存地址。
根据我发布的另一个问题,由于sergmat(original 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
...
Next
的{{1}}值似乎不是有效的虚拟地址,我也尝试对其执行虚拟到物理转换,但失败了。
看起来这个值是页面的某种偏移,但我不完全确定应该如何计算地址。
列表标题中有其他数据,0x0000000001bf0003
结构,位于_SLIST_HEADER
之前。它包含以下数据:
_SINGLE_LIST_ENTRY
在初始头是一系列三个联合之后,由于这是一个64位系统,我相信应该使用Alignment: 0x1bf0003
Region: 0xfffffa8001df5b01
联合,其中包含:{/ p>
Header16
Depth: 0x3
Sequence: 0x1bf
HeaderType: 0x1
Init: 0x0
Reserved: 0x0
NextEntry: 0xfffffa8001df5b0
元素确实包含一个有效的虚拟地址,因此我不确定这是否是下一个列表元素的实际值,或其他内容。
因此,如果有人可以帮助澄清如何在64位系统上计算Header16.NextEntry
元素,我将非常感激。
谢谢
答案 0 :(得分:1)
WDK中记录了SLIST_HEADER:
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