如果是 Hook SSDT 表中的 Nt* 函数,我们可以直接通过 Zw* 函数地址加偏移1字节的地方获取到索引号。但 Shadow SSDT表的函数则不然,每个 win32k.sys 有关的图形函数开头的汇编代码都不一致,因此 Hook SSDT 表所使用的方法在这里派不上用场了。但我们通过下面的方法依然能快速的查找 Shadow SSDT 表中的函数索引号。(记得加载 Windows 系统描述符号)
以查找 NtGdiBitBlt 函数的索引号为例:
先获取 Shadow SSDT 结构体的地址,
kd> dd nt!KeServiceDescriptorTableShadow L8 80553f60 80502b8c 00000000 0000011c 80503000 80553f70 bf999b80 00000000 0000029b bf99a890
后 16 字节开头的 bf999b80 就是 Shadow SSDT 表的地址,接着直接使用 dds 命令获取每项对应的函数名:
kd> dds bf999b80 L0000029b bf999b80 bf935f7e win32k!NtGdiAbortDoc bf999b84 bf947b29 win32k!NtGdiAbortPath ... bf999bb4 bf809fdf win32k!NtGdiBitBlt bf999bb8 bf948f31 win32k!NtGdiCancelDC bf999bbc bf94a72d win32k!NtGdiCheckBitmapBits bf999bc0 bf900c15 win32k!NtGdiCloseFigure
(输出太多的时候,可以使用 Ctrl + F 输入关键字快速定位)
可以看到,bf999bb4 处就存放着 NtGdiBitBlt 函数的地址,将这个地址与表中第一项的地址 bf999b80 相减,再除以 4 ,就成功得到我们想要的函数在表中的索引号了:
NtGdiBitBlt 函数的索引号:(bf999bb4 - bf999b80)/4 = 0x34/0x4 = 0xD = 13
索引号到手,接着就能愉快的进行 Shadow SSDT Hook 了。