想在Win10 x64下看下SSDT表中的函数,记得以前看雪上,某个前辈发了一篇x86下的Windbg脚本来显示SSDT函数。
今天需要使用的时候,翻出了这个脚本。但是需要修改下,但是网络上找到的公式,不适合Win10 x64系统。
自己逆向了下。

uf KiSystemServiceStart下的某一段代码, 不确定位置是否正确,但是经过验证,公式是正确的。
rax: 是索引值

r10: 是KeServiceDescriptorTable->KiServiceTable

nt!KiSystemServiceRepeat+0x35:
fffff801`12fc8c09 4d8b143a        mov     r10,qword ptr [r10+rdi]
fffff801`12fc8c0d 4d631c82        movsxd  r11,dword ptr [r10+rax*4]
fffff801`12fc8c11 498bc3          mov     rax,r11
fffff801`12fc8c14 49c1fb04        sar     r11,4
fffff801`12fc8c18 4d03d3          add     r10,r11
fffff801`12fc8c1b 83ff20          cmp     edi,20h
fffff801`12fc8c1e 7550            jne     nt!KiSystemServiceGdiTebAccess+0x49 (fffff801`12fc8c70)

翻译成代码如下:代码未经过测试。

ULONG64 SSDT_GetPfnAddr(ULONG dwIndex)
{
    PULONG lpBase  = KeServiceDescriptorTable->KiServiceTable;
    ULONG dwCount  = KeServiceDescriptorTable->Count;
    ULONG64 lpAddr = NULL;
 
    ULONG dwOffset = lpBase[dwIndex];
 
    // SAR这个指令, 以及右移4位, 决定了0xF0000000这个值。
    if ( dwOffset & 0x80000000 )
        dwOffset = (dwOffset >> 4) | 0xF0000000;
    else
        dwOffset >>= 4;
 
    lpAddr = (ULONG64)((PUCHAR)lpBase + (LONG)dwOffset);
 
    return lpAddr;
}

用这个公式,Windbg的脚本测试结果: