现在的位置: 首页 > 综合 > 正文

驱动保护中的ObjectType_Callback探索

2013年08月06日 ⁄ 综合 ⁄ 共 3488字 ⁄ 字号 评论关闭

最近学习驱动保护,有点小小心德与大家分享下。
当前环境:VM中的win7 32 保护程序是某游戏的驱动保护。
具体现象是:在用PCHunter工具查看object钩子时发现如下的信息:

 点击图片以查看大图图片名称:	1.jpg查看次数:	1文件大小:	17.2 KB文件 ID :	84119

疑问点1:在HOOK列显示的是ObjectType_Callback,以前只听说过ObjectType HOOK没听说过这个呀,这个是什么呢?

疑问点2:Object类型列显示的是“Process” 查阅了《windows内核原理与实现》的55页WRK中的全局类型对象变量,发现不是系统创建的类型,难道这个对象类型是自己创建的?或者说是PCHunter大牛对这类HOOK的一种描述?

疑问点3:就是这种类型的HOOK是怎么注册的呢,又应该怎么卸载了。
带着几个疑问搜索了下ObjectType_Callback 没有发现相关信息,所以决定自己探索一下。

首先来确定疑问点2,这个思路是:对比有HOOK和无HOOK的情况下 查看win7中的ObTypeIndexTable表,看元素是否有增加,如果是自创类型的,在这个表中,应该有增加一项。
这里顺便提一下ObTypeIndexTable表,是从WIN7(具体什么时候新增的我也不知道,总之XP没有)开始新增加的,存放的是对象类型,可以在windbg查看,具体信息原理可以百度搜索“Win7 OBJECT_HEADER之TypeIndex解析”得到解答。

当前有HOOK的情况下WINDBG中显示如下:

 名称:  2.jpg查看次数: 0文件大小:  86.5 KB

其中为了验证,取第三项86a4e7c8来看,可以发现的确是存放的对象类型,前两项是无效。
然后我重启WIN7 在没有HOOK的情况下显示如图:

 名称:  3.jpg查看次数: 0文件大小:  46.4 KB

可以看出数量是没有变化的,从而可以推断疑问2这个HOOK不是新增加对象类型来完成的,只是软件作者对其一种描述吧,那这个东西到底是什么呢?

重新运行游戏以后,HOOK又出现了:

 点击图片以查看大图图片名称:	4.jpg查看次数:	0文件大小:	29.2 KB文件 ID :	84122

接着解决疑问1,思路是:断点其中的函数,看函数什么时候被调用,看看栈回溯,具体在分析下经历过的函数。
首先反汇编下这两个地址,第一个如下:

 名称:  5.jpg查看次数: 0文件大小:  22.8 KB

第二个函数如下:

 点击图片以查看大图图片名称:	6.png查看次数:	0文件大小:	7.9 KB文件 ID :	84124

第一个函数是空的,第二个函数有内容,断点第二个函数,然后运行,很快断下来了,查看栈回溯如图:

 点击图片以查看大图图片名称:	7.png查看次数:	0文件大小:	30.8 KB文件 ID :	84125

可以看到调用NtOpenProcess的时候就会调用到他,这正起到了保护作用,其中最接近他的ObpCallPreOperationCallbacks函数和ObpPreInterceptHandleCreate函数在WRK中都没有,只有ObpCreateHandle在WRK中可以查到,这个函数解释为:This function creates a new handle to an existing object。相当于为了引用一个对象,新建一个句柄,这个句柄就是这个对象的引用方式。至此我们知道了,是引用一个对象的时候才会触发到这个保护函数,看来PCHunter大牛还是很强大的,把它分到了object钩子这类里边很精确。

由于WRK(假想为XP)中没有这两个函数,所以为了弄清楚什么时候调用的他必须要反汇编以上两个函数,由于才入此道功力尚浅用WINDBG看着费力,所以改为IDA反汇编看,IDA打开内核文件ntkrnlpa.exe 在左侧列表中搜索ObpPreInterceptHandleCreate函数反汇编如图:

点击图片以查看大图图片名称:	8.png查看次数:	0文件大小:	25.6 KB文件 ID :	84126 

引入眼帘的就是对象类型表ObTypeIndexTable,想象一下对象类型的HOOK,看来还是还对象类型有关。再往下看记录找到调用ObpCallPreOperationCallbacks函数的地方

 点击图片以查看大图图片名称:	9.png查看次数:	0文件大小:	31.8 KB文件 ID :	84127

可以看到在开头不远处,发现这个函数代码量也很小,继续跟进这个函数,定位CALL相关的代码,寻找保护函数调用点,一直往下都是系统调用直到这里:

 点击图片以查看大图图片名称:	10.png查看次数:	0文件大小:	14.8 KB文件 ID :	84128

在WINDBG中栈回溯显示的是
9d158758 840df832 xxxx!SampleDouble+0xcdf8
9d1587a0 840dfa1f nt!ObpCallPreOperationCallbacks+0x163
9d1587e8 8402dbfb nt!ObpPreInterceptHandleCreate+0x6f
对比下代码看看是不是这个地方,也可以计算下位置看看是不是这个地方,我比较懒就直接对比下吧,如图:

 点击图片以查看大图图片名称:	11.png查看次数:	0文件大小:	8.4 KB文件 ID :	84129

看来应该这就是调用点,再从CALL EAX中的EAX反推回去,看看怎么来的。通过IDA的鼠标点击变量寄存器变色可以轻松定位出以下过程EAX-》
006D581F                 mov     eax, [edi+18h]-》
006D572C                 mov     edi, [eax]-》
006D5729                 mov     eax, [ebp+var_C]-》
006D56E7                 mov     [ebp+var_C], eax-》
006D56DF                 lea     eax, [edi+80h]-》
006D56DD                 mov     edi, eax
说明在这个函数调用时 EAX就是关键所在了,分析上一个函数入调用点
通过前边的截图可以看到 EAX-》
006D5A12                 mov     eax, edx-》
006D59C0                 mov     edx, _ObTypeIndexTable[eax*4]
看来一切原因都来自于对象类型。
006D5A12位置的EAX是一个_OBJECT_TYPE WINDBG中看看WIN7中的结构成员

 名称:  12.png查看次数: 0文件大小:  9.0 KB

可以推测006D56DF中的EAX就是一个CallbackList了,看看这个名字再看看PCHunter中的ObjectType_Callback真是完全一样啊,回想先前也看了下_OBJECT_TYPE结构但是没注意到这个成员,想必一定是他保存了回调,这是一个双链表。现在就来看看这个对象类型里边的具体内容,想必就应该可以找到保护函数的地址了。

通过前边的分析可以知道再调用ObpCallPreOperationCallbacks函数时的EAX就是当前对象类型的地址,所以在这里设置断点,当然也有可能是其它的函数调用它,虽然知道不正确但是也只有赌一把了,具体操作如下:

 名称:  13.png查看次数: 0文件大小:  13.5 KB

可以看到名称是Process这和工具里边显示的是一样,感觉应该就是它了,在具体查看一下CallbackList 看看链表的内容
 名称:  14.png查看次数: 0文件大小:  11.6 KB
第一项链表头节点指向首节点a83175f8,首节点也指向首节点86ad3f30,看来只有双向链表中只有一项,查看内容发现红框处就是保护函数的地址,双链表结构也说明还可以增加其他的callback函数。

整体回顾一下 当NtOpenProcess被调用时就会调用到保护函数,这个函数是放在进程对象类型中的CallbackList中的,系统会调用它,且这个结构是双链表,还可以增加其他函数,至此疑问1基本就解决了。

接着来看疑问3,既然知道系统有这么一个机制,肯定应该有相应的系统函数吧,总不可能手工来添加删除吧,既然知道了这个新成员名称就应该搜索下,看看有什么信息 GOOGLE搜索下发现有以下内容 

点击图片以查看大图图片名称:	15.png查看次数:	0文件大小:	72.9 KB文件 ID :	84133

再翻译了下大致就是说ObRegisterCallbacks函数来注册的回调,MSDN搜索发现有这样的解释:The ObRegisterCallbacks routine registers a list of callback routines for thread and process handle operations.
这和我们遇到的情况一样,看来保护函数就是用这个函数来添加的了,怎么卸载呢?看看MSDN的左侧栏

 名称:  16.png查看次数: 0文件大小:  4.6 KB

发现一个对应的UN函数 点击查看解释:The ObUnRegisterCallbacks routine unregisters a set of callback routines that were registered with the ObRegisterCallbacks routine.
看来就是它了,两个函数的参数和进程创建卸载的系统回调差不多,具体可以参考《教你在64位Win7系统下使用ObRegisterCallbacks内核函数来实现进程保护》http://bbs.pediy.com/showthread.php?t=168023

到此这几个疑问就解决了,至于后边的是删除还是修改保护函数就看到自己的想法了。

抱歉!评论已关闭.