- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
废话不多少 我做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 [rsp+arg_0], rbx
.text:FFFFF97FFF072749 push rdi
.text:FFFFF97FFF07274A sub rsp, 20h
.text:FFFFF97FFF07274E mov rcx, cs:gpresUser 锁
.text:FFFFF97FFF072755 call cs:__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] 基于 rip偏移到2555 得到一个 QWORD数据~~~ 此时RIP=1111 寻址地址=1111+2555;
此时得到1
我们的代理函数
2222: mov rax,QWORD PTR [rip+2555] 基于 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, [RIP +0026C1C3]
IDA中表现为 MOV RCX,CS:gpresUser(符号名) |
|