• 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;
    

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

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

    代码直接拷贝编译就可以.我是使用的 WDK7600. 因为没有硬编码的方式.所以高版本WDK只要支持这些函数.就可以编译.

    #include <ntddk.h>   //很多驱动的结构体函数的声明呀.都包含在这里面
    #include <ntdef.h>
    
    #include <wdm.h>
    
    
    
    NTKERNELAPI
    NTSTATUS
    PsLookupProcessByProcessId(
    __in HANDLE ProcessId,
    __deref_out PEPROCESS *Process
    );
    
    PVOID g_pRegistrationHandle;
    
    NTKERNELAPI
    UCHAR * PsGetProcessImageFileName(__in PEPROCESS Process);
    
    EXTERN_C void InstallHook();
    OB_PREOP_CALLBACK_STATUS  ObjectPreCallback(__in PVOID  RegistrationContext,
    __in POB_PRE_OPERATION_INFORMATION  OperationInformation);
    
    
    OB_PREOP_CALLBACK_STATUS  ObjectPreCallback(__in PVOID  RegistrationContext,
    __in POB_PRE_OPERATION_INFORMATION  OperationInformation)
    {
    
    
    PEPROCESS Process;
    UCHAR *pszImageName = NULL;
    
    #define PROCESS_PROTECT 0x1
    Process = (PEPROCESS)OperationInformation->Object;
    pszImageName = PsGetProcessImageFileName(Process);
    
    if (strstr(pszImageName, "calc") != NULL)
    {
    
            if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
            {
                if
                    ((OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess &
                    PROCESS_PROTECT) == PROCESS_PROTECT)
                {
                    OperationInformation->Parameters->CreateHandleInformation.DesiredAccess
                        &= ~PROCESS_PROTECT;
                }
            }
            if (OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE)
            {
                if
                    ((OperationInformation->Parameters->DuplicateHandleInformation.OriginalDesiredAccess &
                    PROCESS_PROTECT) == PROCESS_PROTECT)
                {
                    OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &=
                        ~PROCESS_PROTECT;
                }
            }
    
    
    }
    return OB_PREOP_SUCCESS;
    }
    
    void InstallHook()
    {
        NTSTATUS status;
        OB_CALLBACK_REGISTRATION obReg;
        OB_OPERATION_REGISTRATION obOper;
    
        DbgPrint("begin protect calc");
        obOper.ObjectType = PsProcessType;
        obOper.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
        obOper.PreOperation = NULL;
        obOper.PostOperation = NULL;
    
        RtlInitUnicodeString(&obReg.Altitude, L"60000");
        obReg.Version = OB_FLT_REGISTRATION_VERSION;
        obReg.OperationRegistrationCount = 1;
        obReg.RegistrationContext = NULL;
        obOper.PreOperation = (POB_PRE_OPERATION_CALLBACK)&ObjectPreCallback; 
        obReg.OperationRegistration = &obOper;
        
        status = ObRegisterCallbacks(&obReg, &g_pRegistrationHandle);
        DbgPrint("begin protect calc end");
    }
    
    VOID  DriverUnLoad(PDRIVER_OBJECT pDriverObject);
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
    {
    
        pDriverObject->DriverUnload = DriverUnLoad;
    
        DbgPrint("Load Driver Sucess");
        //InstallHook();
        InstallHook();
        //设置通讯的方式
    
        return STATUS_SUCCESS;
    }
    
    
    
    
    //驱动卸载
    
    VOID  DriverUnLoad(PDRIVER_OBJECT pDriverObject)
    {
        ObUnRegisterCallbacks(g_pRegistrationHandle);
        DbgPrint("Unload MyDrive
    ");
    }

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

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

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

     四丶去掉保护.

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

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

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

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

    代码下载地址: WDK7600 + Notepad++ +x64Check编译. 你可以使用Free编译.我没用.

    链接:https://pan.baidu.com/s/1JDBnsznailhCw513pKsbsQ
    提取码:3uhq

  • 相关阅读:
    VMWare安装win10提示units specified don’t exist, SHSUCDX can’t install
    WinXP.Http.Post请求错误提示:基础连接已经关闭:发送时发生错误
    如何用PostMan请求WebApi
    无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_CI_AS_WS" 之间的排序规则冲突 解决
    c# Winform PropertyGrid 实现下拉框 多选
    c# Winform GridControl 给列自动生成快捷操作按钮
    Tomcat启动报内存溢出错误:java.lang.OutOfMemoryError: PermGen space异常 解决
    Net Core 项目引用Exceptionless记录使用
    .Net 开源异常日志ExceptionLess搭建
    c# AutoMapper 扩展
  • 原文地址:https://www.cnblogs.com/iBinary/p/8401469.html
Copyright © 2020-2023  润新知