64位内核第二讲,进程保护之对象钩子

         64位内核第二讲,进程保护.

一丶什么是保护.

什么是保护. 比如我们安装了xxx杀毒软件.那么此时你用任务管理器关闭.是关闭不了的.原因是内核已经做了保护.

那么去掉保护的前提就是你要给自己的软件做保护.

比如我们给计算器做保护. 例如下图.

做保护.以前的病毒作者.都是想要退出xxx杀毒软件. 什么方法都能做. 所以杀软为了防止这一情况发生,直接把打开进程的API进行HOOK即可.

但是别忘了.还可以拷贝句柄.所以杀软防不住.只能在内核做保护.

二丶给软件添加保护熟悉API和结构体

给软件添加保护很简单. 也是调用API进行操作.

API:

  ObRegisterCallbacks  注册进程和线程处理回调

NTSTATUS 
  ObRegisterCallbacks(
    IN POB_CALLBACK_REGISTRATION  CallBackRegistration,
    OUT PVOID  *RegistrationHandle
    );

第一个是个结构体,我们想要进行的操作都放在这个结构中

第二个是个二级指针,我们给一个即可

结构体:

typedef struct _OB_CALLBACK_REGISTRATION {
  __in USHORT  Version;                  //版本号
  __in USHORT  OperationRegistrationCount;       //回调个数. 可以一次蹙着多个回调. 和最后一个参数绑定的. 如果一次注册多个.则最后一个参数需要给数组保存,最后参数是一个结构体.
  __in UNICODE_STRING  Altitude;            // 指定的驱动程序的Uncode字符串. 可以看WDK文档给.
  __in PVOID  RegistrationContext;           // 回调函数的参数.如果你给可以在这里给.
  __in OB_OPERATION_REGISTRATION  *OperationRegistration;//回调函数信息结构体,如果个数有多个,你需要定义为数组.
} OB_CALLBACK_REGISTRATION, *POB_CALLBACK_REGISTRATION;

结构体中回调函数结构体.

typedef struct _OB_OPERATION_REGISTRATION {
  __in POBJECT_TYPE  *ObjectType;        //对象的类型.你注册回调函数的类型 PsProcessType 和 PsThreadType 分别是进程回调和线程回调.
  __in OB_OPERATION  Operations;         //注册回调的操作方式, 一个是创建进程. 一个是拷贝进程句柄.  OB_OPERATION_HANDLE_CREATEA  ,OB_OPERATION_HANDLE_DUPLICATE 
  __in POB_PRE_OPERATION_CALLBACK  PreOperation;//创建之前回调函数的地址,在这里给. 每一个回调都包含什么信息在这个结构体中给出.
  __in POB_POST_OPERATION_CALLBACK  PostOperation;//创建之后回调函数的地址. 和上面不一样,一个是创建之前,你的回调回来,一个是创建之后你的回调函数回来.
} OB_OPERATION_REGISTRATION, *POB_OPERATION_REGISTRATION;

回调函数原型

OB_PREOP_CALLBACK_STATUS 
  ObjectPreCallback(
    __in PVOID  RegistrationContext,    //回调函数的参数,上面通过结构体给的.
    __in POB_PRE_OPERATION_INFORMATION  OperationInformation //进程或者线程创建的信息结构体
    );

进程或者线程信息结构体.

typedef struct _OB_PRE_OPERATION_INFORMATION {
  __in OB_OPERATION  Operation;    //句柄的操作类型, 是上面我们给的.
  union {
    __in ULONG  Flags;
    struct {
      __in ULONG  KernelHandle:1;
      __in ULONG  Reserved:31;
    };
  };
  __in PVOID  Object;        //对象指针,如果你给的是监控进程,那么这个对象就是EPROCESS,如果是线程,那么这个对象就是ETHREAD
  __in POBJECT_TYPE  ObjectType; //对象类型. 可能是PsThreadType 也可能是 PsProcessType
  __out PVOID  CallContext;
  __in POB_PRE_OPERATION_PARAMETERS  Parameters; //创建或者创建之后的参数信息结构体.
} OB_PRE_OPERATION_INFORMATION, *POB_PRE_OPERATION_INFORMATION;

参数信息结构体

typedef union _OB_PRE_OPERATION_PARAMETERS {
  __inout OB_PRE_CREATE_HANDLE_INFORMATION  CreateHandleInformation;        //创建句柄,则成员会给这个赋值
  __inout OB_PRE_DUPLICATE_HANDLE_INFORMATION  DuplicateHandleInformation;    //拷贝句柄,则给这个成员赋值.
   } OB_PRE_OPERATION_PARAMETERS, *POB_PRE_OPERATION_PARAMETERS;

创建句柄结构体

typedef struct _OB_PRE_CREATE_HANDLE_INFORMATION {
  __inout ACCESS_MASK  DesiredAccess;                        //创建的权限是什么. 如果我们给 0则没有任何权限,则进程不能创建.
  __in ACCESS_MASK  OriginalDesiredAccess;                     //原始的权限.
} OB_PRE_CREATE_HANDLE_INFORMATION, *POB_PRE_CREATE_HANDLE_INFORMATION;

拷贝句柄结构体信息

  __inout ACCESS_MASK  DesiredAccess;                      //权限,我们自己控制
  __in ACCESS_MASK  OriginalDesiredAccess;                   //原始权限
  __in PVOID  SourceProcess;                           //拷贝句柄的时候,源对象指针.
  __in PVOID  TargetProcess;                           //目的对象指针.
} OB_PRE_DUPLICATE_HANDLE_INFORMATION, * POB_PRE_DUPLICATE_HANDLE_INFORMATION;

结构体看着挺多,其实挺简单的.

三丶给软件添加权限保护代码.

void InstallHook()
{
  NTSTATUS status;              //NT状态
  OB_CALLBACK_REGISTRATION obReg;
  OB_OPERATION_REGISTRATION obOper;

  obOper.ObjectType = PsProcessType;   //监控的类型
  obOper.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;  //监控创建还是拷贝(创建包括打开)
  obOper.PreOperation = ObjectPreCallback;//创建的时候回调函数地址
  obOper.PostOperation = NULL;       //创建后的回调函数地址


  RtlInitUnicodeString(&obReg.Altitude, L"60000");//初始化驱动类型
  obReg.Version = OB_FLT_REGISTRATION_VERSION;  //指定版本.
  obReg.OperationRegistrationCount = 1;      //回调结构体(里面放着回调函数指针)的个数
  obReg.RegistrationContext = NULL;        //回调函数的参数
  obReg.OperationRegistration = &obOper;     //回调函数结构体
  

  //注册对象回调
  status = ObRegisterCallbacks(&obReg, &g_pRegistrationHandle);
  dprintf("[Hello] ObRegisterCallbacks status=%d\r\n", status);
PVOID g_pRegistrationHandle;

OB_PREOP_CALLBACK_STATUS  ObjectPreCallback(__in PVOID  RegistrationContext,
                    __in POB_PRE_OPERATION_INFORMATION  OperationInformation)
{
  PEPROCESS Process;          
  UCHAR *pszImageName = NULL;
  
  Process = OperationInformation->Object;        //因为监控的对象类型是进程,所以对象则是EPROCESS
  pszImageName = PsGetProcessImageFileName(Process);  //获取名字
  
  if (strstr(pszImageName, "calc") != NULL)      //判断我们的进程
  {
    if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)//判断句柄操作是不是创建.
    {  
      OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = 0; //如果是创建或者打开,则权限则给0,那么我们的程序就不会关闭了.
      dprintf("[ObjectPreCallback] Create ImageName=%s\r\n", pszImageName);
    }
    else if (OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE)   //判断是否是拷贝句柄.
    {
      OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = 0;//同上.
       dprintf("[ObjectPreCallback] Duplicate ImageName=%s\r\n", pszImageName);
    }
  }

  return OB_PREOP_SUCCESS;  //如果是驱动,必须返回这个.
}

通过上面的代码,我们的计算器则会被保护.那么此时我们编译之后安装驱动那么软件就和刚开始那样,不能进行关闭进程了.

你如果关闭计算器,重新打开则打开不了了, 

如果你启动计算器之后,在安驱动,那么计算机就同上图所示,关闭不了了.

 四丶去掉保护.

去掉保护,那么我们就要逆向 设置对象回调的这个API了.

那么简单的演示则是用PChunter去掉.我们的程序就可以关闭了.

如果有时间,则逆向一下,找到数组. 找到表,抹掉即可.

去掉之后则可以退出了. 包括xxx杀毒.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏cloudskyme

OTL技术应用

什么是OTL:OTL 是 Oracle, Odbc and DB2-CLI TemplateLibrary 的缩写,是一个操控关系数据库的C++模板库,它目前几...

6176
来自专栏Android开发与分享

【Android】Realm详解

69511
来自专栏JackieZheng

探秘Tomcat——启动篇

tomcat作为一款web服务器本身很复杂,代码量也很大,但是模块化很强,最核心的模块还是连接器Connector和容器Container。具体请看下图: ? ...

4857
来自专栏雪胖纸的玩蛇日常

Uncaught SyntaxError: Unexpected token ' in JSON at position 1

1K3
来自专栏ChaMd5安全团队

HCTF2018 WriteUp

不断fuzz,发现\u0075nion在json_decode后,会变成union,从而达到bypass的目的。 脚本:

2524
来自专栏JetpropelledSnake

SNMP学习笔记之SNMP报文协议详解

简单网络管理协议(SNMP)是TCP/IP协议簇的一个应用层协议。在1988年被制定,并被Internet体系结构委员会(IAB)采纳作为一个短期的网络管理解决...

1322
来自专栏西二旗一哥

iOS - autoreleasepool and @autoreleasepool

+ 在一个自动引用计数的环境中(并不是垃圾回收机制),一个包含了多个对象的 NSAutoreleasePool 对象能够接收 autorelease 消息并且...

1534
来自专栏游戏杂谈

as3与php 上传单个图片demo

1、单个上传使用FileReference,一次可选择多张图片可使用FileReferenceList,在flash player 10+可使用load方法可实...

1873
来自专栏ASP.NETCore

MVVM绑定多层级数据到TreeView并设置项目展开

昨天在做项目的时候碰到了这个问题,发现通常我们定义的数据不法绑定到控件上,接下来我将讲一下我是怎么解决这个问题的。

1352
来自专栏潇涧技术专栏

Pury Project Analysis

Pury的源码:https://github.com/NikitaKozlov/Pury

912

扫码关注云+社区

领取腾讯云代金券