|
本帖最后由 tangptr@126.com 于 2015-10-6 04:27 编辑
鉴于大批伸手党的存在,今日起TP的学习笔记中的代码需回帖方可见,附件需回帖方能下载。
用过PCHunter的朋友们应该都看到过“内核钩子”->“Object钩子”吧,但是却从来不知道这里面的函数如何挂钩。这些天里看了些对象相关的文章后,理解并开始自己尝试写代码。
首先我们要关注一下我们要关心什么对象,那就是进程和线程。进程对象类型是PsProcessType,线程对象类型是PsThreadType。这个是一个OBJECT_TYPE结构的地址。首先先用WinDbg查看其结构。
OBJECT_TYPE的结构
再看看OBJECT_TYPE_INITIALIZER结构体:
OBJECT_TYPE_INITIALIZER
其中,我们只要修改掉SecurityProcedure就可以实现在打开进程的过程中经过自己的检查。而根据资料所写,原始的SecurityProcedure这个过程就是未导出函数SeDefaultObjectMethod。而SeDefaultObjectMethod这个函数,没有任何的文档描述过。根据资料所写的东西可知,这个函数返回值是NTSTATUS,调用约定是__stdcall,第一个参数是Object,剩余还有八个参数,均是未知的。因此可猜到该函数的原型是:
- typedef NTSTATUS(__stdcall *SEDEFAULTOBJECTMETHOD)
- (
- PVOID Object,
- ULONG SystemArgument1,
- ULONG SystemArgument2,
- ULONG SystemArgument3,
- ULONG SystemArgument4,
- ULONG SystemArgument5,
- ULONG SystemArgument6,
- ULONG SystemArgument7,
- ULONG SystemArgument8
- );
复制代码
于是我们挂钩的时候就这么写代码:
而处理用的伪过程就像普通Hook一样,不过我们只在意第一个参数Object,代码如下:
做一个杀进程杀线程的测试并用PCHunter v1.35检查Object Hook:
先测试一下杀进程,其中Ring3版的是直接ZwOpenProcess+ZwTerminateProcess,Ring0版的是ObOpenObjectByPointer+ZwTerminateProcess并用头五字节硬编码的方式恢复ObOpenObjectByPointer的头五个字节。
杀进程测试
再测试一下杀线程,原理差不多,但不知为何,Ring0级杀正常线程的时候在NtTerminateThread这一层被驳回,返回了STATUS_ACCESS_DENIED这个值。知道原因的人帮忙回帖解答。
杀线程测试
最后看看PCHunter的钩子状况
检测钩子的结果
到这里,我们的Object Hook方式实现保护进线程貌似是可以到此为止了,不过这里还是有两点要说:
1.OBJECT_TYPE和OBJECT_TYPE_INITIALIZER两个结构体在各个系统中均不一样,本文提供了XP下可用的demo。故本文所使用的硬编码也是XP可用而其他系统不可用。其中win7的硬编码是0x28+0x44,2k3的硬编码是0x60+0x40。大家可以用WinDbg来查看。
2.由于这种方式可以阻止ObOpenObjectByPointer打开进程,故NtOpenProcess,NtGetNextProcess这两个函数打开进程的方式对此保护均无效,但复制句柄则可以。线程方面则同理。
p.s:杀进程用的东西无聊的加了个Call Hook PspTerminateThreadByPointer->KeInsertQueueApc的进程保护 |
|