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\n"); }
通过上面的代码,我们的计算器则会被保护.那么此时我们编译之后安装驱动那么软件就和刚开始那样,不能进行关闭进程了.
你如果关闭计算器,重新打开则打开不了了,
如果你启动计算器之后,在安驱动,那么计算机就同上图所示,关闭不了了.
四丶去掉保护.
去掉保护,那么我们就要逆向 设置对象回调的这个API了.
那么简单的演示则是用PChunter去掉.我们的程序就可以关闭了.
如果有时间,则逆向一下,找到数组. 找到表,抹掉即可.
去掉之后则可以退出了. 包括xxx杀毒.
代码下载地址: WDK7600 + Notepad++ +x64Check编译. 你可以使用Free编译.我没用.
链接:https://pan.baidu.com/s/1JDBnsznailhCw513pKsbsQ
提取码:3uhq