Windows对象句柄回调 (Object Handle Callbacks)对象句柄回调直接介入Windows对象管理器的工作流程它允许我们在其它进程对进程、线程、桌面对象进行操作的前后执行自定义的回调函数。关键函数对象句柄回调的关键函数是ObRegisterCallbacksNTSTATUSObRegisterCallbacks([in]POB_CALLBACK_REGISTRATION CallbackRegistration,// 指向 OB_CALLBACK_REGISTRATION 结构体[out]PVOID*RegistrationHandle// 返回的注册句柄用于卸载);OB_CALLBACK_REGISTRATION结构体这是注册信息的“根”结构包含了所有注册的总体信息。typedefstruct_OB_CALLBACK_REGISTRATION{USHORT Version;// 必须设置为 OB_FLT_REGISTRATION_VERSIONUSHORT OperationRegistrationCount;// 下面 OperationRegistration 数组的元素个数UNICODE_STRING Altitude;// 驱动程序的“高度”用于确定回调的优先级PVOID RegistrationContext;// 驱动定义的上下文会传递给回调函数POB_OPERATION_REGISTRATION OperationRegistration;// 指向一个结构体数组}OB_CALLBACK_REGISTRATION,*POB_CALLBACK_REGISTRATION;Altitude 字段这是一个关键的Unicode字符串它决定了当多个驱动同时注册回调时你的回调函数被调用的顺序。数值越高优先级也越高其 PreOperation 回调会更早被调用PostOperation 回调会更晚被调用。OB_OPERATION_REGISTRATION结构体这个结构体用于指定你要监控的具体对象类型、操作类型以及对应的回调函数。typedefstruct_OB_OPERATION_REGISTRATION{POBJECT_TYPE*ObjectType;// 对象类型: PsProcessType 或 PsThreadType 等OB_OPERATION Operations;// 操作类型: OB_OPERATION_HANDLE_CREATE 或 DUPLICATEPOB_PRE_OPERATION_CALLBACK PreOperation;// 操作前回调函数指针POB_POST_OPERATION_CALLBACK PostOperation;// 操作后回调函数指针}OB_OPERATION_REGISTRATION,*POB_OPERATION_REGISTRATION;ObjectType指定要监控的对象类型通常是 PsProcessType进程或 PsThreadType线程。Operations指定要拦截的操作可以是 OB_OPERATION_HANDLE_CREATE创建句柄或 OB_OPERATION_HANDLE_DUPLICATE复制句柄。示例代码下面这份代码用于防止notepad.exe进程被关闭/* * 这份代码用于测试ObRegisterCallbacks内核回调函数 * * 该份代码的作用是避免notepad.exe被终止 */#includewdm.h#includentstrsafe.hEXTERN_C NTKERNELAPI UCHAR*PsGetProcessImageFileName(IN PEPROCESS Process);// 保存ObRegisterCallbacks返回的注册句柄卸载时需要PVOID g_registrationHandlenullptr;// 该函数在每一次进程句柄创建或者复制之前被调用OB_PREOP_CALLBACK_STATUSObPreCallback(PVOID RegistrationContext,POB_PRE_OPERATION_INFORMATION OperationInformation);voidDriverUnload(PDRIVER_OBJECT pDrvObj){// 注册成功需要卸载if(g_registrationHandle!nullptr){ObUnRegisterCallbacks(g_registrationHandle);g_registrationHandlenullptr;DbgPrintEx(DPFLTR_IHVDRIVER_ID,DPFLTR_INFO_LEVEL,[ObCallback] Callback unregistered.\n);}DbgPrintEx(DPFLTR_IHVDRIVER_ID,DPFLTR_INFO_LEVEL,Uninstall driver\n);}EXTERN_C NTSTATUSDriverEntry(PDRIVER_OBJECT pDrvObj,PUNICODE_STRING pRegPath){pDrvObj-DriverUnloadDriverUnload;// 定义操作注册结构告诉系统我们要监控什么对象和什么操作OB_OPERATION_REGISTRATION opReg{0};opReg.ObjectTypePsProcessType;opReg.OperationsOB_OPERATION_HANDLE_CREATE;opReg.PreOperationObPreCallback;opReg.PostOperationnullptr;// 定义回调注册结构OB_CALLBACK_REGISTRATION cbReg{0};cbReg.VersionOB_FLT_REGISTRATION_VERSION;cbReg.OperationRegistrationCount1;RtlInitUnicodeString(cbReg.Altitude,L600000);cbReg.RegistrationContextnullptr;cbReg.OperationRegistrationopReg;// 注册回调NTSTATUS statusObRegisterCallbacks(cbReg,g_registrationHandle);if(!NT_SUCCESS(status)){DbgPrintEx(DPFLTR_IHVDRIVER_ID,DPFLTR_INFO_LEVEL,ObRegisterCallbacks failed with status 0x%X\n,status);returnstatus;}DbgPrintEx(DPFLTR_IHVDRIVER_ID,DPFLTR_INFO_LEVEL,ObRegisterCallbacks successfully\n);returnSTATUS_SUCCESS;}OB_PREOP_CALLBACK_STATUSObPreCallback(PVOID RegistrationContext,POB_PRE_OPERATION_INFORMATION OperationInformation){// 只对进程对象感兴趣虽然注册的时候指定了类型这里是为了确保安全if(OperationInformation-ObjectType!*PsProcessType){returnOB_PREOP_SUCCESS;}PEPROCESS targetProcess(PEPROCESS)OperationInformation-Object;if(!targetProcess){returnOB_PREOP_SUCCESS;}PCHAR processName(PCHAR)PsGetProcessImageFileName(targetProcess);if(!processName){returnOB_PREOP_SUCCESS;}// 检查是否为notepad.exeif(_stricmp(processName,notepad.exe)!0){returnOB_PREOP_SUCCESS;}// 检查操作类型if(OperationInformation-OperationOB_OPERATION_HANDLE_CREATE||OperationInformation-OperationOB_OPERATION_HANDLE_DUPLICATE){// 检查请求的访问掩码中包含的权限是否包含终止权限ACCESS_MASK desireAccessOperationInformation-Parameters-CreateHandleInformation.DesiredAccess;// 只检查创建句柄大部分终止操作是通过OpenProcess产生if(OperationInformation-OperationOB_OPERATION_HANDLE_CREATE){ACCESS_MASK desireOperationInformation-Parameters-CreateHandleInformation.DesiredAccess;if(desire0x0001){// 拒绝该操作返回访问被拒绝DbgPrintEx(DPFLTR_IHVDRIVER_ID,DPFLTR_INFO_LEVEL,[ObCallback] Blocked attempt to open notepad.exe \ with TERMINATE access.\n);OperationInformation-Parameters-CreateHandleInformation.DesiredAccess0;// 清空权限returnOB_PREOP_SUCCESS;}}}returnOB_PREOP_SUCCESS;}为了避免运行驱动时出现权限不足的报错我们需要在项目属性中的链接器选项页面中添加/INTEGRITYCHECK
Windows对象句柄回调 (Object Handle Callbacks)
Windows对象句柄回调 (Object Handle Callbacks)对象句柄回调直接介入Windows对象管理器的工作流程它允许我们在其它进程对进程、线程、桌面对象进行操作的前后执行自定义的回调函数。关键函数对象句柄回调的关键函数是ObRegisterCallbacksNTSTATUSObRegisterCallbacks([in]POB_CALLBACK_REGISTRATION CallbackRegistration,// 指向 OB_CALLBACK_REGISTRATION 结构体[out]PVOID*RegistrationHandle// 返回的注册句柄用于卸载);OB_CALLBACK_REGISTRATION结构体这是注册信息的“根”结构包含了所有注册的总体信息。typedefstruct_OB_CALLBACK_REGISTRATION{USHORT Version;// 必须设置为 OB_FLT_REGISTRATION_VERSIONUSHORT OperationRegistrationCount;// 下面 OperationRegistration 数组的元素个数UNICODE_STRING Altitude;// 驱动程序的“高度”用于确定回调的优先级PVOID RegistrationContext;// 驱动定义的上下文会传递给回调函数POB_OPERATION_REGISTRATION OperationRegistration;// 指向一个结构体数组}OB_CALLBACK_REGISTRATION,*POB_CALLBACK_REGISTRATION;Altitude 字段这是一个关键的Unicode字符串它决定了当多个驱动同时注册回调时你的回调函数被调用的顺序。数值越高优先级也越高其 PreOperation 回调会更早被调用PostOperation 回调会更晚被调用。OB_OPERATION_REGISTRATION结构体这个结构体用于指定你要监控的具体对象类型、操作类型以及对应的回调函数。typedefstruct_OB_OPERATION_REGISTRATION{POBJECT_TYPE*ObjectType;// 对象类型: PsProcessType 或 PsThreadType 等OB_OPERATION Operations;// 操作类型: OB_OPERATION_HANDLE_CREATE 或 DUPLICATEPOB_PRE_OPERATION_CALLBACK PreOperation;// 操作前回调函数指针POB_POST_OPERATION_CALLBACK PostOperation;// 操作后回调函数指针}OB_OPERATION_REGISTRATION,*POB_OPERATION_REGISTRATION;ObjectType指定要监控的对象类型通常是 PsProcessType进程或 PsThreadType线程。Operations指定要拦截的操作可以是 OB_OPERATION_HANDLE_CREATE创建句柄或 OB_OPERATION_HANDLE_DUPLICATE复制句柄。示例代码下面这份代码用于防止notepad.exe进程被关闭/* * 这份代码用于测试ObRegisterCallbacks内核回调函数 * * 该份代码的作用是避免notepad.exe被终止 */#includewdm.h#includentstrsafe.hEXTERN_C NTKERNELAPI UCHAR*PsGetProcessImageFileName(IN PEPROCESS Process);// 保存ObRegisterCallbacks返回的注册句柄卸载时需要PVOID g_registrationHandlenullptr;// 该函数在每一次进程句柄创建或者复制之前被调用OB_PREOP_CALLBACK_STATUSObPreCallback(PVOID RegistrationContext,POB_PRE_OPERATION_INFORMATION OperationInformation);voidDriverUnload(PDRIVER_OBJECT pDrvObj){// 注册成功需要卸载if(g_registrationHandle!nullptr){ObUnRegisterCallbacks(g_registrationHandle);g_registrationHandlenullptr;DbgPrintEx(DPFLTR_IHVDRIVER_ID,DPFLTR_INFO_LEVEL,[ObCallback] Callback unregistered.\n);}DbgPrintEx(DPFLTR_IHVDRIVER_ID,DPFLTR_INFO_LEVEL,Uninstall driver\n);}EXTERN_C NTSTATUSDriverEntry(PDRIVER_OBJECT pDrvObj,PUNICODE_STRING pRegPath){pDrvObj-DriverUnloadDriverUnload;// 定义操作注册结构告诉系统我们要监控什么对象和什么操作OB_OPERATION_REGISTRATION opReg{0};opReg.ObjectTypePsProcessType;opReg.OperationsOB_OPERATION_HANDLE_CREATE;opReg.PreOperationObPreCallback;opReg.PostOperationnullptr;// 定义回调注册结构OB_CALLBACK_REGISTRATION cbReg{0};cbReg.VersionOB_FLT_REGISTRATION_VERSION;cbReg.OperationRegistrationCount1;RtlInitUnicodeString(cbReg.Altitude,L600000);cbReg.RegistrationContextnullptr;cbReg.OperationRegistrationopReg;// 注册回调NTSTATUS statusObRegisterCallbacks(cbReg,g_registrationHandle);if(!NT_SUCCESS(status)){DbgPrintEx(DPFLTR_IHVDRIVER_ID,DPFLTR_INFO_LEVEL,ObRegisterCallbacks failed with status 0x%X\n,status);returnstatus;}DbgPrintEx(DPFLTR_IHVDRIVER_ID,DPFLTR_INFO_LEVEL,ObRegisterCallbacks successfully\n);returnSTATUS_SUCCESS;}OB_PREOP_CALLBACK_STATUSObPreCallback(PVOID RegistrationContext,POB_PRE_OPERATION_INFORMATION OperationInformation){// 只对进程对象感兴趣虽然注册的时候指定了类型这里是为了确保安全if(OperationInformation-ObjectType!*PsProcessType){returnOB_PREOP_SUCCESS;}PEPROCESS targetProcess(PEPROCESS)OperationInformation-Object;if(!targetProcess){returnOB_PREOP_SUCCESS;}PCHAR processName(PCHAR)PsGetProcessImageFileName(targetProcess);if(!processName){returnOB_PREOP_SUCCESS;}// 检查是否为notepad.exeif(_stricmp(processName,notepad.exe)!0){returnOB_PREOP_SUCCESS;}// 检查操作类型if(OperationInformation-OperationOB_OPERATION_HANDLE_CREATE||OperationInformation-OperationOB_OPERATION_HANDLE_DUPLICATE){// 检查请求的访问掩码中包含的权限是否包含终止权限ACCESS_MASK desireAccessOperationInformation-Parameters-CreateHandleInformation.DesiredAccess;// 只检查创建句柄大部分终止操作是通过OpenProcess产生if(OperationInformation-OperationOB_OPERATION_HANDLE_CREATE){ACCESS_MASK desireOperationInformation-Parameters-CreateHandleInformation.DesiredAccess;if(desire0x0001){// 拒绝该操作返回访问被拒绝DbgPrintEx(DPFLTR_IHVDRIVER_ID,DPFLTR_INFO_LEVEL,[ObCallback] Blocked attempt to open notepad.exe \ with TERMINATE access.\n);OperationInformation-Parameters-CreateHandleInformation.DesiredAccess0;// 清空权限returnOB_PREOP_SUCCESS;}}}returnOB_PREOP_SUCCESS;}为了避免运行驱动时出现权限不足的报错我们需要在项目属性中的链接器选项页面中添加/INTEGRITYCHECK