在笔者上一篇文章《驱动开发:内核枚举进程与线程ObCall回调》
简单介绍了如何枚举系统中已经存在的进程与线程
回调,本章LyShark
将通过对象回调实现对进程线程的句柄
监控,在内核中提供了ObRegisterCallbacks
回调,使用这个内核回调
函数,可注册一个对象
回调,不过目前该函数只能
监控进程与线程句柄操作,通过监控进程或线程句柄,可实现保护指定进程线程不被终止的目的。
由于目前对象回调
只能监控进程与线程,而这个监控是通过ObjectType
这么一个成员控制的,如果成员是PsProcessType
则代表监控进程,反之PsThreadType
则是监控线程,无论监控进程还是线程都调用ObRegisterCallbacks
这个函数来完成注册。
函数ObRegisterCallbacks
其微软对他的定义是这样的,用户传入OB_OPERATION_REGISTRATION
结构,以及OB_CALLBACK_REGISTRATION
回调结构,其中PreOperation
则是传入的回调函数,也是最重要的,其次是ObjectType
指定成进程回调。
NTSTATUS ObRegisterCallbacks(
[in] POB_CALLBACK_REGISTRATION CallbackRegistration,
[out] PVOID *RegistrationHandle
);
首先来实现一个检测的案例,注册一个进程回调对象MyLySharkComObjectCallBack
,通过ObRegisterCallbacks
注册的回调只需要传入一个填充好的OB_CALLBACK_REGISTRATION
回调结构体,以及一个全局句柄即可,这个全局句柄的作用仅仅只是在程序结束时,调用ObUnRegisterCallbacks
卸载监控而已,实现代码如下所示。
// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com
#include <ntddk.h>
#include <ntstrsafe.h>
PVOID Globle_Object_Handle;
// 绕过签名检测
void BypassCheckSign(PDRIVER_OBJECT pDriverObj)
{
typedef struct _LDR_DATA
{
struct _LIST_ENTRY InLoadOrderLinks;
struct _LIST_ENTRY InMemoryOrderLinks;
struct _LIST_ENTRY InInitializationOrderLinks;
VOID* DllBase;
VOID* EntryPoint;
ULONG32 SizeOfImage;
UINT8 _PADDING0_[0x4];
struct _UNICODE_STRING FullDllName;
struct _UNICODE_STRING BaseDllName;
ULONG32 Flags;
}LDR_DATA, *PLDR_DATA;
PLDR_DATA ldr;
ldr = (PLDR_DATA)(pDriverObj->DriverSection);
ldr->Flags |= 0x20;
}
// 自定义回调
OB_PREOP_CALLBACK_STATUS MyLySharkComObjectCallBack(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
DbgPrint("[lyshark] 执行回调函数... \n");
return STATUS_SUCCESS;
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
ObUnRegisterCallbacks(Globle_Object_Handle);
DbgPrint("回调卸载完成... \n");
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
DbgPrint("hello lyshark.com \n");
BypassCheckSign(Driver);
OB_OPERATION_REGISTRATION Base; // 回调函数结构体
OB_CALLBACK_REGISTRATION CallbackReg; // 回调函数
CallbackReg.RegistrationContext = NULL; // 注册上下文(你回调函数返回参数)
CallbackReg.Version = OB_FLT_REGISTRATION_VERSION; // 注册回调版本
CallbackReg.OperationRegistration = &Base; // 回调结构体
CallbackReg.OperationRegistrationCount = 1; // 操作计数(下钩数量)
RtlUnicodeStringInit(&CallbackReg.Altitude, L"600000"); // 长度
Base.ObjectType = PsProcessType; // 进程操作类型.此处为进程操作
Base.Operations = OB_OPERATION_HANDLE_CREATE; // 操作句柄创建
Base.PreOperation = MyLySharkComObjectCallBack; // 你自己的回调函数
Base.PostOperation = NULL;
// 注册回调
if (ObRegisterCallbacks(&CallbackReg, &Globle_Object_Handle))
{
DbgPrint("[lyshark message] 回调注册成功...");
}
Driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
当驱动程序被加载以后,一旦有进程运行则会执行我们自己的MyLySharkComObjectCallBack
回调,而在回调函数内则可以执行任意功能,运行如下所示。
如上所示只是演示基本的回调申请流程,回调函数通常需要包含两个值,其一RegistrationContext
用于标注上下文,其二POB_PRE_OPERATION_INFORMATION
则用于标注进程或者线程创建的信息结构体。
OB_PREOP_CALLBACK_STATUS MyLySharkComObjectCallBack(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
那么如何实现拦