首页
社区
课程
招聘
[原创]新手无hook进程保护及过签名分析
发表于: 2015-4-27 14:48 16571

[原创]新手无hook进程保护及过签名分析

2015-4-27 14:48
16571

无hook实现进程保护
     第一部分:ObRegisterCallbacks使用
     第二部分:跳过签名限制分析

ObRegisterCallbacks使用
本文在windows7 内核太中实现无hook进程保护。现在网上找的例子基本上都是针对windows 32位系统的,也基本上都是教你用ssdt hook,inline hook去挂钩NtOpenProcess,NtTerminateProcess等系统调用,百度一大堆。当然在windows 64位系统中是不可能的,在64位系统中加载驱动必须要有签名。而且不可能去hook SSDT  GDT等,否则将触发异常 紧接着系统蓝屏。因为PG(PatchGuard)保护着系统内核,除非能跳过验证。
在系统中还是用标准的回调注册函数ObRegisterCallbacks()比较好,这个函数只在XP以后才添加进去(还有对应的ObUnRegisterCallbacks删除回调),查看WDK对该函数的描述
   ObRegisterCallbacks
The ObRegisterCallbacks routine registers a list of callback routines for thread and process handle operations.
NTSTATUS 
  ObRegisterCallbacks(
    IN POB_CALLBACK_REGISTRATION  CallBackRegistration,
    OUT PVOID  *RegistrationHandle
    );
  Parameters
CallBackRegistration 
A pointer to an OB_CALLBACK_REGISTRATION structure that specifies the list of callback routines and other registration information. 
RegistrationHandle 
A pointer to a variable that receives a value that identifies the set of registered callback routines. The caller passes this value to the ObUnRegisterCallbacks routine to unregister the set of callbacks. 

再看看这个函数的一个参数OB_CALLBACK_REGISTRATION结构

typedef struct _OB_CALLBACK_REGISTRATION {
  __in USHORT  Version;
  __in USHORT  OperationRegistrationCount;
  __in UNICODE_STRING  Altitude;
  __in PVOID  RegistrationContext;
  __in OB_OPERATION_REGISTRATION  *OperationRegistration;
} OB_CALLBACK_REGISTRATION, *POB_CALLBACK_REGISTRATION;

这个结构内部还有个OB_CALLBACK_REGISTERATION

typedef struct _OB_OPERATION_REGISTRATION {
  __in POBJECT_TYPE  *ObjectType;
  __in OB_OPERATION  Operations;
  __in POB_PRE_OPERATION_CALLBACK  PreOperation;
  __in POB_POST_OPERATION_CALLBACK  PostOperation;
} OB_OPERATION_REGISTRATION, *POB_OPERATION_REGISTRATION;
第一个成员msdn上要求填写PsProcessType或者 PsThreadType
第二个成员OB_OPERATION_HANDLE_CREATE或者OB_OPERATION_HANDLE_DUPLICATTE。
第三个成员是操作前回调函数指针,这个是我们要关注的 别的自己看msdn去都有。定义如下

OB_PREOP_CALLBACK_STATUS 
  ObjectPreCallback(
    __in PVOID  RegistrationContext,
    __in POB_PRE_OPERATION_INFORMATION  OperationInformation
    );

第四个成员是操作后回调函数指针。定义如下

VOID 
  ObjectPostCallback(
    __in PVOID  RegistrationContext,
    __in POB_POST_OPERATION_INFORMATION  OperationInformation
    );

下面附上一段设置回调函数的

void SetCallback()
{
  NTSTATUS status;
  OB_CALLBACK_REGISTRATION obReg;
  OB_OPERATION_REGISTRATION opReg;

  memset(&obReg,0,sizeof(obReg));
  obReg.Version=ObGetFilterVersion();
  obReg.OperationRegistrationCount=1;
  obReg.RegistrationContext=NULL;
  RtlInitUnicodeString(&obReg.Altitude,L"321000");
  memset(&opReg,0,sizeof(opReg));//Init Struct
  opReg.ObjectType=PsProcessType;
  opReg.Operations=OB_OPERATION_HANDLE_CREATE|OB_OPERATION_HANDLE_DUPLICATE;
  opReg.PreOperation=(POB_PRE_OPERATION_CALLBACK)&preCall;
//  opReg.PostOperation=(POB_POST_OPERATION_CALLBACK)&PostCall;
  obReg.OperationRegistration=&opReg;
  status=ObRegisterCallbacks(&obReg,&obHandle);
  if(status==STATUS_SUCCESS)  
    DbgPrint("回调创建号成功\n");
  else
    DbgPrint("回调创建失败%X",status);
}

回调函数代码



编译好运行起来



跳过签名限制分析

发现创建回调的时候失败了 返回了错误码0xC0000022查看msdn
The callback routines do not reside in a signed kernel binary image. 
这个回调函数得签名过才能正确添加回调函数,其实这个限制也只针对32系统,因为在正常情况下x64的必须要签名过才能加载驱动程序^_^。
bp ObRegisterCallbacks 

跟进去经过调试发现在函数内部调用_MmVerifyCallbackFunction()然后就跳出去设置eax等于0xc0000022就返回了。
 windbg 看代码不方便,直接IDA反汇编ntoskrnl.exe



再跟进这个函数,这个函数代码不多 简单的从这个函数的函数最后面的eax寄存器逆推回去 选中后面的变量逆推到代码



不知道这个MiLookupDataTableEntry是干什么用的,eax也不知道返回了点什么,逆向水平有限(而且在ReactOs里找到了源码^_^)直接在ReactOs观赏源码原来是返回了PLDR_DATA_TABLE_ENTRY  这个结构的头通过windbg查看该结构 +0x34处是Flag
也就说判断这个flag是否为0x20
那么就只需要修改下标志位就可以了代码如下



这样驱动加载进去回调就设置成功了
这种方法过验证 自己玩玩还是可以的 但是用到
产品中还是老实点买个签名比较好况且代码中也用了
好多硬编码。

效果如下



我是一枚菜,我知道大神不喜欢喷人所以才来分享点心得
待会儿我就整理成文档和源码一起上传


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 4
支持
分享
最新回复 (17)
雪    币: 81
活跃值: (73)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
源码和程序已经附上
无hook进程保护及过签名分析 .pdf

源码及程序.zip
上传的附件:
2015-4-27 14:58
0
雪    币: 144
活跃值: (335)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
支持一个 谢谢分享
2015-4-27 15:14
0
雪    币: 160
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
支持!很牛x的方法!学习了 感谢楼主~
2015-4-27 16:00
0
雪    币: 212
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
谢谢 学习一下
2015-4-27 17:54
0
雪    币: 60
活跃值: (449)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
6
感谢分享学习了
2015-4-27 18:29
0
雪    币: 9771
活跃值: (2596)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
新手无hook进程保护及过签名分析
mark
2015-4-27 18:41
0
雪    币: 81
活跃值: (73)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
8
有pdf文档 帖子里没啥格式
2015-4-27 19:56
0
雪    币: 22
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
MARK
2015-4-27 21:18
0
雪    币: 719
活跃值: (777)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
10
前排~~
2015-4-27 21:35
0
雪    币: 391
活跃值: (717)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
11
支持一下!谢谢楼主分享!
2015-4-27 22:49
0
雪    币: 81
活跃值: (73)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
12
奇叔不逗
2015-4-27 23:05
0
雪    币: 764
活跃值: (147)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
赞一个!
2015-4-28 04:42
0
雪    币: 557
活跃值: (449)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
14
你写的这篇文章,我也写过类似的。有些部分内容,相似。
参考我写的把,如果我的文章有什么不好的地方,还请指点。 如下所示:

发表时间: 2013年4月10日
文章名: 教你在64位Win7系统下使用ObRegisterCallbacks内核函数来实现进程保护

网页链接: http://bbs.pediy.com/showthread.php?t=168023
2015-4-28 09:17
0
雪    币: 81
活跃值: (73)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
15
其实就那么点东西 我就后面分析了下过那个签名的 前面部分代码是在网上复制粘贴的 嘿嘿
2015-4-28 10:16
0
雪    币: 81
活跃值: (73)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
16
后来又浅显分析了下添加上去的那个回调函数各种调用时机 下次一起发上来 ,
其实过签名没必要这么麻烦 链接那里添加个 /INTEGRITYCHECK就可以了
2015-4-28 10:36
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
mack
2017-8-29 10:26
0
雪    币: 145
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
感谢感谢,终于明白为什么会出错了,原来是因为结构体用成64位的了
2018-9-28 10:13
0
游客
登录 | 注册 方可回帖
返回
//