fjx16852318 发表于 2017-6-3 11:03:50

做X64 shadow SSDT HOOK引擎那些事儿~~

废话不多少 我做HOOK引擎遇到的事儿~~~

先看一下代码 ,里面有详细地址
.text:FFFFF97FFF072744 NtUserGetForegroundWindow proc near ; DATA XREF: .text:FFFFF97FFF0D20E0o
.text:FFFFF97FFF072744             ; .pdata:FFFFF97FFF2E44F0o ...
.text:FFFFF97FFF072744
.text:FFFFF97FFF072744 arg_0   = qword ptr8
.text:FFFFF97FFF072744
.text:FFFFF97FFF072744   mov , rbx
.text:FFFFF97FFF072749   pushrdi
.text:FFFFF97FFF07274A   sub rsp, 20h
.text:FFFFF97FFF07274E   mov rcx, cs:gpresUser 锁
.text:FFFFF97FFF072755   callcs:__imp_ExEnterPriorityRegionAndAcquireResourceShared 加锁
.text:FFFFF97FFF07275B   mov r11, cs:gpqForeground
.text:FFFFF97FFF072762   xor ebx, ebx

这个 ExEnterPriorityRegionAndAcquireResourceShared 函数是NTKROSNL中的导出函数 导入到win32k.sys中的 负责给临界资源加锁的

这里就不得不说道今天的事儿了 我要挂钩win32k中的窗口服务函数~然而手动复制这个代码我觉得太麻烦,不如手动写一个引擎~ 于是就有了这篇文章 ,这是一个在X64下的问题
这里牵扯到特殊的不依赖地址的寻址方式了也就是RIP+XXX 不在依赖重定位表了 RIP是指这条指令的头部 XX是偏移 我们写引擎直接复制这些函数的头部大于14字节 的不截断指令会造成一个问题 那就是 把原有函数的寻址方式改变了

例如 原函数
1111+2555这个地方存放着 1;
2222+2555这个地方存放着 2;
地址 1111: mov rax,QWORD PTR 基于 rip偏移到2555 得到一个 QWORD数据~~~ 此时RIP=1111 寻址地址=1111+2555;
此时得到1
我们的代理函数

2222: mov rax,QWORD PTR 基于 rip偏移到2555 得到一个 QWORD数据~~~ 此时RIP=2222寻址地址=2222+2555;
此时得到的是2
而不是一 这在内核中就可怕了并不能得到锁的地址 也就是不能加锁,
访问的很可能是个无效地址 造成的内存访问异常促使蓝屏
或者能得到可访问地址不能正常加锁

修复方式 save= RIP+2555
proxypointer=MOV RAX,QWORD PTR [ RIP+2555-RIP]
这是伪汇编指令 大家看看就好 关于特征码就是下面加红的三个字节 48 8B 0D C3 C1 26 00=mov rcx,
IDA中表现为 MOV RCX,CS:gpresUser(符号名)
页: [1]
查看完整版本: 做X64 shadow SSDT HOOK引擎那些事儿~~