Windows64位下关于SSDT寄存器

想要对SSDT进行HOOK,首先要找到SSDT表,修改表的内容,但是64位情况却有些不同。

  • 64位关于SSDT的KeServiceDescriptorTable并没有导出,无法使用extend来使用
  • 64位关于SSDT无法直接修改,有PG保护,甚至不能inline HOOK (触发蓝屏)

解决方法:

  • 使用PG补丁,强行将PG disable
  • 使用MSR接管,重新生成一份SSDT表,在自己的表中HOOK

无论是方案1还是方案2,在没有KeServiceDescriptorTable的情况下只能通过特征码搜索SSDT表

其中,关键函数就是KiSystemCall64,该函数的地址可以通过读取c0000082寄存器来获取
windbg

1
rdmsr c0000082

1
2
PUCHAR pKiSystemCall64 = (PUCHAR)__readmsr(0xC0000082);  // 读
__writemsr(0xC0000082, pKiSystemCall64); //写

获取到KiSystemCall64函数地址后,通过特征码来搜索SSDT表

1
2
3
4
5
6
fffff800`04082772 4c8d15c7202300  lea     r10,[nt!KeServiceDescriptorTable (fffff800`042b4840)]             //SSDT
fffff800`04082779 4c8d1d00212300 lea r11,[nt!KeServiceDescriptorTableShadow (fffff800`042b4880)] //ShadowSSDT
fffff800`04082ac1 488d3dd81d2300 lea rdi,[nt!KeServiceDescriptorTableShadow+0x20 (fffff800`042b48a0)] //ShadowSSDT+20

fffff800`04082b71 488b45b0 mov rax,qword ptr [rbp-50h] //定位函数末尾
fffff800`04082b75 e959fdffff jmp nt!KiSystemServiceCopyEnd+0x13 (fffff800`040828d3) //定位函数末尾

方案1可以需要SSDT表即可,方案2需要将整份KiSystemCall64复制并修复偏移信息来达到接管MSR(将 msr c0000082 寄存器的值替换为新地址的值)