看流星社区

 找回密码
 注册账号
查看: 2363|回复: 0

利用ObRegisterCallbacks保护进程并附上突破ObRegisterCallbacks的方法[未更新]

[复制链接]

该用户从未签到

发表于 2017-6-1 13:32:46 | 显示全部楼层 |阅读模式
写上未更新的原因是我觉得 当初写这篇文章的时候理解的还是不够彻底,现在又了新的认识,待老夫有时间的时候在来重写一次
这里附上新的突破方法 我已经我写的时候已经写上了
今天发到博客的时候才发现没写,来补上
可以看我发到梦老大论坛的帖子,直接看第三种方法就行,前面两种我都服了,这样获取对象类型,太年轻啊
http://www.mengwuji.net/forum.php?mod=viewthread&tid=2323&page=1

简单说下就是讲线程对象中的SupportsObjectCallbacks域置0
随便说一说一字节anti创建进程线程等回调
这个不是我知道的,这是论坛一哥们发的
http://www.mengwuji.net/forum.php?mod=viewthread&tid=2498&page=1

需要注意的是梦老大的留言
然后我搜了搜论坛
看到老大说了
  1. PspNotifyEnableMask这个可以控制的,其中第0位代表是否开启模块回调,第一位代表是否开启进程回调(调用PsSetCreateProcessNotifyRoutine设置的情况),第二位代表是否开启进程回调(调用PsSetCreateProcessNotifyRoutineEx设置的情况),第三位代表是否开启线程回调。
  2. 如果你想让进程回调失效,就把PspNotifyEnableMask的第一位和第二位设置为零就行了,只是这样做所有的进程回调就会失效,不过也无所谓啦
复制代码
那它到底控制多少呢?IDA一看就知道了
  1. 方向 种类 地址                                  文本                                
  2. ---- ---- ----                                  ----                                
  3. 上   r    PspExitProcess+55                     mov     ebp, cs:PspNotifyEnableMask
  4. 上   r    PspExitProcess+5B                     mov     eax, cs:PspNotifyEnableMask
  5. 上   r    PspExitThread+BE                      mov     eax, cs:PspNotifyEnableMask
  6. 上   r    PspInsertThread+3B0                   mov     r11d, cs:PspNotifyEnableMask
  7. 上   r    PspInsertThread+4A6                   mov     ecx, cs:PspNotifyEnableMask
  8. 上   r    PspInsertThread+4B6                   mov     eax, cs:PspNotifyEnableMask
  9. 上   r    DbgkCreateThread:loc_14036BD05        mov     ecx, cs:PspNotifyEnableMask
  10. 上   r    MiMapViewOfImageSection:loc_1403990D6 mov     eax, cs:PspNotifyEnableMask
  11. 上   r    PsCallImageNotifyRoutines+2C          mov     eax, cs:PspNotifyEnableMask
  12. 上   r    MmLoadSystemImage+250                 mov     eax, cs:PspNotifyEnableMask
  13. 上   r    PsSetLoadImageNotifyRoutine+55        mov     eax, cs:PspNotifyEnableMask
  14. 上   w    PsSetLoadImageNotifyRoutine+5F        lock bts cs:PspNotifyEnableMask, 0  
  15. 上   r    PsSetCreateThreadNotifyRoutine+55     mov     eax, cs:PspNotifyEnableMask
  16. 上   w    PsSetCreateThreadNotifyRoutine+5F     lock bts cs:PspNotifyEnableMask, 3  
  17.      r    PspSetCreateProcessNotifyRoutine+1BB  mov     eax, cs:PspNotifyEnableMask
  18. 下   w    PspSetCreateProcessNotifyRoutine+1C5  lock bts cs:PspNotifyEnableMask, 1  
  19. 下   r    PspSetCreateProcessNotifyRoutine+1D7  mov     eax, cs:PspNotifyEnableMask
  20. 下   w    PspSetCreateProcessNotifyRoutine+1E1  lock bts cs:PspNotifyEnableMask, 2  
复制代码
大概看一下是创建进线程回调,模块加载回调,很多都是重复,那么就是sub


众所周知如果不patch DSE KPP 是不能在x64下进程SSDT HOOK的,那以前x86保护进程都是SSDT HOOK NtOpenprocess 保护线程HOOK NtOpenThread 很有游戏保护也是这么做的到了x64,这样的作法是不可行的,那么如何保护进程呢,微软给我们提供了一个API
ObRegisterCallbacks 注册一个Object回调
先看下原型:


<ol style="word-wrap:break-word; margin:0px 0px 0px 10px!important; padding:0px!important">
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
NTSTATUS
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
ObRegisterCallbacks(
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  IN POB_CALLBACK_REGISTRATIONCallBackRegistration,
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  OUT PVOID*RegistrationHandle
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  );</ol>

复制代码
再看下参数:提供一个POB_CALLBACK_REGISTRATION的结构体,输出一个句柄这里需要2个结构体


<ol style="word-wrap:break-word; margin:0px 0px 0px 10px!important; padding:0px!important">
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
typedef struct _OB_CALLBACK_REGISTRATION {
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
USHORT      Version;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
USHORT      OperationRegistrationCount;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
UNICODE_STRING    Altitude;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
PVOID       RegistrationContext;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
OB_OPERATION_REGISTRATION *OperationRegistration;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
} OB_CALLBACK_REGISTRATION, *POB_CALLBACK_REGISTRATION;</ol>

复制代码


<ol style="word-wrap:break-word; margin:0px 0px 0px 10px!important; padding:0px!important">
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
typedef struct _OB_OPERATION_REGISTRATION {
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
__in POBJECT_TYPE*ObjectType;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
__in OB_OPERATIONOperations;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
__in POB_PRE_OPERATION_CALLBACKPreOperation;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
__in POB_POST_OPERATION_CALLBACKPostOperation;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
} OB_OPERATION_REGISTRATION, *POB_OPERATION_REGISTRATION;</ol>

复制代码
首先我们要初始化这个结构体
Version调用 ObGetFilterVersion()即可
OperationgRegistrationgCount 这个一般为1
Altitude为这个要使用RtlInitUnicodeString初始化一个字符串,我的理解是回调的名字?
最后一个参数就传入一个OB_OPERATION_REGISTRATION指针就OK啦
下面来初始化OB_OPERATION_REGISTRATION
ObjectType是指我们要监视的对象类型
进程是PsProcessType 线程是PsThreadType
Operations是指句柄怎么方式
是直接创建呢 还是复制句柄这里一般填OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
最后一个回调函数地址
这里我们要构建一个我们规则 也就是这个回调函数


<ol style="word-wrap:break-word; margin:0px 0px 0px 10px!important; padding:0px!important">
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
OB_PREOP_CALLBACK_STATUS
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
precessCallBack(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pOperationInformation)
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
{
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  HANDLE pid = PsGetProcessId((PEPROCESS)pOperationInformation-&gt;Object);
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  char szProcName[16]={0};
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  UNREFERENCED_PARAMETER(RegistrationContext);
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  strcpy(szProcName,GetProcessNameByProcessId(pid));
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  if( !_stricmp(szProcName,&quot;calc.exe&quot;) )
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  {
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  if (pOperationInformation-&gt;Operation == OB_OPERATION_HANDLE_CREATE)
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  {
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
    if ((pOperationInformation-&gtarameters-&gt;CreateHandleInformation.OriginalDesiredAccess &amp; PROCESS_TERMINATE) == PROCESS_TERMINATE)//进程终止
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
    {
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
      pOperationInformation-&gtarameters-&gt;CreateHandleInformation.DesiredAccess &amp;= ~PROCESS_TERMINATE;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
    }
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
    if ((pOperationInformation-&gtarameters-&gt;CreateHandleInformation.OriginalDesiredAccess &amp; PROCESS_VM_OPERATION) == PROCESS_VM_OPERATION)//openprocess
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
    {
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
      pOperationInformation-&gtarameters-&gt;CreateHandleInformation.DesiredAccess &amp;= ~PROCESS_VM_OPERATION;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
    }
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
    if ((pOperationInformation-&gtarameters-&gt;CreateHandleInformation.OriginalDesiredAccess &amp; PROCESS_VM_READ) == PROCESS_VM_READ)//内存读
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
    {
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
      pOperationInformation-&gtarameters-&gt;CreateHandleInformation.DesiredAccess &amp;= ~PROCESS_VM_READ;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
    }
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
    if ((pOperationInformation-&gtarameters-&gt;CreateHandleInformation.OriginalDesiredAccess &amp; PROCESS_VM_WRITE) == PROCESS_VM_WRITE)//内存写
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
    {
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
      pOperationInformation-&gtarameters-&gt;CreateHandleInformation.DesiredAccess &amp;= ~PROCESS_VM_WRITE;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
    }
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  }
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  }
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
  return OB_PREOP_SUCCESS;
<li style="word-wrap:break-word; margin:0px 0px 0px 2em; padding:0px 0px 0px 10px; list-style-type:decimal-leading-zero; font-family:Monaco,Consolas,'Lucida Console','Courier New',serif; font-size:12px; line-height:1.8em">
}</ol>

复制代码
构建完之后我们填上这个函数的地址即可
然后我们就可以注册回调了
ObRegisterCallbacks(初始化的结构指针, 谁接收注册成功的回调句柄);
当然最好要判断一下啦~等会卸载的时候要用到
这只是对进程的监视,一般也要对线程进行监视,很多保护都是这么做的..
一般都是注册2个回调 一个线程一个进程
卸载很容易啦~直接调用ObUnRegisterCallacks 参数为注册成功后的第二个参数~
现在讲下回调函数
在回调函数逇pOperationInformation-&gt;object
可以得到进程对象或线程对象
如果是我们要保护的进程,就可以干一些事啦~比如上面的禁止读写 禁止终止等等


这里以保护calc为例子 不能关闭,不能读写内存



好啦~保护到这里结束 我们来将如果干掉这种保护
对象回调的句柄肯定是保存在一个对线结构体里
这里是保存在ObjectType结构的callbacklist链表里面 进去看了后并没有发现句柄 回调函数地址等等信息
后来在看雪上面看到说是在Callbacklist的第二项之后,也就是CallBackList-&gt;Flink指向的地址是一个结构体链表
而这个结构并没有被导出 不过已经有高人逆向出来啦~(TA)

<blockquote style="word-wrap:break-word; display:inline-block; margin:0px; padding:0px 65px 5px 0px; line-height:1.6; zoom:1">
typedef struct _OB_CALLBACK
{
  LIST_ENTRY  ListEntry;
  ULONG64      Unknown;
  ULONG64      ObHandle;
  ULONG64      ObjTypeAddr;
  ULONG64      PreCall;
  ULONG64      PostCall;
} OB_CALLBACK, *POB_CALLBACK;</blockquote>


那么下面就是枚举啦~枚举大家应该都会的,这里就不说了,我们来说怎么做掉这种保护,我想到的有2种,一是注销回调 有了回调句柄就可以用ObUnRegisterCallacks注销啦~第二种是有了函数地址,我们可以对函数头retn
第一种很简单,但存在一个问题,我们注销了这个句柄,进程不能正常结束了..有待解决
第二种也很简单啦~写入0xC3即可~这个问题很明显啦~如果有CRC呢?相信这么这个已不是什么问题,找到CRC FUCK之即可~
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 18:57

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表