Windows x64(侵入式)单一链接列表

我目前正试图绕过一些Windows旁观列表,我看到一些内存地址让我感到困惑。

从我发布的另一个问题,一些代码被生成,感谢sergmat ( 原始问题 ):

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元素,我将不胜感激。

谢谢

    WDST中记录了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