在32位driver中,获取SSDT表中的函数可根据以下固定的公式(64位下获取KeServiceDescriptorTable参见Win64 Driver开发问题记录二)
SSDTTableBase=(PVOID)((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase;
ULONG_PTR func_addr = (ULONG)SSDTTableBase+index*4
但是64位下,SSDT表中存的其实是函数的偏移并非实际的函数地址, 因此函数地址 = SSDTTableBase + 偏移地址
此外, win7和vista 64位下SSTD的函数偏移是28位,而其他64位下SSTD的函数偏移是32位(且最后8位对齐)
他们之所以这么设计 (要算位移) 的原因是,他们开始取消了 nt!KiArgumentTable,
那么参数表放哪里了呢? 答案就是和"偏移"拼在一起了,微软认定 SSDT 例程地址是对齐的。
后来估计是觉得这样算一下影响效率? 就又恢复了 nt!KiArgumentTable(参见http://bbs.dbgtech.net/forum.php?mod=viewthread&tid=360)
因此, vista以前的64位计算SSDT数地址:
SSDTTableBase=(PVOID)((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase;
ULONG_PTR FuncAddr = (ULONG_PTR)SSDTTableBase + (((*(ULONG_PTR *)((ULONG_PTR)SSDTTableBase+(index-1)*4)) >> 32) & 0xFFFFFFF0);
vista和win7 64位计算SSDT函数地址:
SSDTTableBase=(PVOID)((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase;
ULONG_PTR FuncAddr = (ULONG_PTR)SSDTTableBase + ((*(ULONG_PTR *)((ULONG_PTR)SSDTTableBase+(index-1)*4)) >> 36)