WindowsAPI编程核心技术-对象监控
碎碎念
对象监控指的是线程句柄对象、进程句柄对象、桌面句柄对象的监控。
这个技术病毒木马常用。病毒木马的对象监控回调常用来会自行线程或进程的保护,保护指定程序不被杀毒软件或用户强制结束运行。结束进程时要获取打开的进程句柄,所以病毒木马通过对进程对象进行监控,使系统获取句柄失败,从而实现进程保护。
前置芝士
ObRegisterCallbacks
注册线程、进程和桌面句柄操作的回调函数。驱动程序必须有数字签名。
1 2 3 4
| NTSTATUS ObRegisterCallbacks( _In_ POB_CALLBACK_REGISTER CallBackRegistration, _Out_ PVOID* RegistrationHandle )
|
用ObUnRegisterCallbacks
注销回调例程。
OB_CALLBACK_REGISTRATION
1 2 3 4 5 6 7
| typedef struct _OB_CALLBACK_REGISTRATION { _In_ USHORT Version; _In_ USHORT OperationRegistrationCount; _In_ UNICODE_STRING Altitude; _In_ PVOID RegistrationContext; _In_ OB_OPERATION_REGISTRATION *OperationRegistration; } OB_CALLBACK_REGISTRATION, *POB_CALLBACK_REGISTRATION;
|
OB_OPERATION_REGISTRATION
1 2 3 4 5 6
| typedef struct _OB_OPERATION_REGISTRATION { _In_ POBJECT_TYPE *ObjectType; _In_ OB_OPERATION Operations; _In_ POB_PRE_OPERATION_CALLBACK PreOperation; _In_ POB_POST_OPERATION_CALLBACK PostOperation; } OB_OPERATION_REGISTRATION, *POB_OPERATION_REGISTRATION;
|
实现方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| NTSTATUS SetProcessCallbacks(VOID) { NTSTATUS status = STATUS_SUCCESS; OB_CALLBACK_REGISTRATION obCallbackReg = { 0 }; OB_OPERATION_REGISTRATION obOperationReg = { 0 }; RtlZeroMemory(&obCallbackReg, sizeof(OB_CALLBACK_REGISTRATION)); RtlZeroMemory(&obOperationReg, sizeof(OB_OPERATION_REGISTRATION)); obCallbackReg.Version = ObGetFilterVersion(); obCallbackReg.OperationRegistrationCount = 1; obCallbackReg.RegistrationContext = NULL; RtlInitUnicodeString(&obCallbackReg.Altitude, L"321000"); obCallbackReg.OperationRegistration = &obOperationReg; obOperationReg.ObjectType = PsProcessType; obOperationReg.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE; obOperationReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)(&ProcessPreCall); status = ObRegisterCallbacks(&obCallbackReg, &g_obProcessHandle); if (!NT_SUCCESS(status)) { DbgPrint("ObRegisterCallbacks Error[0x%X]\n", status); return status; }; return status; };
|
想要拒绝结束线程对象或进程对象的操作时,在操作类型句柄信息中去掉响应结束线程对象或结束进程对象操作权限即可。
1 2 3 4
| pObPreOperationInfo->Parameters->CreateHandleInformation.DesiredAccess = 0;
pObPreOperationInfo->Parameters->DuplicateHandleInformation.DesiredAccess = 0;
|
通过线程对象或进程对象pObPreOperationInfo->Object
判断是否保护线程或进程。对于进程对象,用PsGetProcessImageFileName
从进程结构对象中获取进程名称判断。对于线程对象,用IoThreadToProcess
从线程对象获取相应进程对象,再同进程对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| OB_PREOP_CALLBACK_STATUS ProcessPreCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pObPreOperationInfo) { PEPROCESS pEProcess = NULL; if (*PsProcessType != pObPreOperationInfo->ObjectType) return OB_PREOP_SUCCESS; pEProcess = (PEPROCESS)pObPreOperationInfo->Object; if (IsProtectProcess(pEProcess)) { if (OB_OPERATION_HANDLE_CREATE == pObPreOperationInfo->Operation) { if (1 == (1 & pObPreOperationInfo->Parameters->CreateHandleInformation.OriginalDesiredAccess)) pObPreOperationInfo->Parameters->CreateHandleInformation.DesiredAccess = 0; } else if (OB_OPERATION_HANDLE_DUPLICATE == pObPreOperationInfo->Operation) { if (1 == (1 & pObPreOperationInfo->Parameters->DuplicateHandleInformation.OriginalDesiredAccess)) pObPreOperationInfo->Parameters->DuplicateHandleInformation.DesiredAccess = 0; }; }; return OB_PREOP_SUCCESS; };
|
源代码
Driver.h:
1 2 3 4 5 6 7 8 9 10 11 12
| #ifndef _DRIVER_H_ #define _DRIVER_H_
#include <ntddk.h>
VOID DriverUnload(PDRIVER_OBJECT pDriverObject); NTSTATUS DriverDefaultHandle(PDEVICE_OBJECT pDevObj, PIRP pIrp);
#endif
|
NotifyRoutine.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #ifndef _NOTIFY_ROUTINE_H_ #define _NOTIFY_ROUTINE_H_
#include <ntifs.h> #include <ntddk.h>
PUCHAR PsGetProcessImageFileName(PEPROCESS pEProcess);
BOOLEAN BypassCheckSign(PDRIVER_OBJECT pDriverObject);
NTSTATUS SetProcessCallbacks();
NTSTATUS SetThreadCallbacks();
VOID RemoveProcessCallbacks();
VOID RemoveThreadCallbacks();
OB_PREOP_CALLBACK_STATUS ProcessPreCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pObPreOperationInfo);
OB_PREOP_CALLBACK_STATUS ThreadPreCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pObPreOperationInfo);
BOOLEAN IsProtectProcess(PEPROCESS pEProcess);
HANDLE g_obProcessHandle;
HANDLE g_obThreadHandle;
#endif
|
Driver.c:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include "NotifyRoutine.h" #include "Driver.h"
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath) { DbgPrint("Enter DriverEntry\n");
NTSTATUS status = STATUS_SUCCESS; pDriverObject->DriverUnload = DriverUnload; for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { pDriverObject->MajorFunction[i] = DriverDefaultHandle; }
SetProcessCallbacks();
SetThreadCallbacks();
DbgPrint("Leave DriverEntry\n"); return status; }
VOID DriverUnload(PDRIVER_OBJECT pDriverObject) { RemoveProcessCallbacks();
RemoveThreadCallbacks(); }
NTSTATUS DriverDefaultHandle(PDEVICE_OBJECT pDevObj, PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = 0; IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status; }
|
NotifyRoutine.c:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
| #include "NotifyRoutine.h"
BOOLEAN BypassCheckSign(PDRIVER_OBJECT pDriverObject) { #ifdef _WIN64 typedef struct _KLDR_DATA_TABLE_ENTRY { LIST_ENTRY listEntry; ULONG64 __Undefined1; ULONG64 __Undefined2; ULONG64 __Undefined3; ULONG64 NonPagedDebugInfo; ULONG64 DllBase; ULONG64 EntryPoint; ULONG SizeOfImage; UNICODE_STRING path; UNICODE_STRING name; ULONG Flags; USHORT LoadCount; USHORT __Undefined5; ULONG64 __Undefined6; ULONG CheckSum; ULONG __padding1; ULONG TimeDateStamp; ULONG __padding2; } KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY; #else typedef struct _KLDR_DATA_TABLE_ENTRY { LIST_ENTRY listEntry; ULONG unknown1; ULONG unknown2; ULONG unknown3; ULONG unknown4; ULONG unknown5; ULONG unknown6; ULONG unknown7; UNICODE_STRING path; UNICODE_STRING name; ULONG Flags; } KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY; #endif
PKLDR_DATA_TABLE_ENTRY pLdrData = (PKLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection; pLdrData->Flags = pLdrData->Flags | 0x20;
return TRUE; }
NTSTATUS SetProcessCallbacks() { NTSTATUS status = STATUS_SUCCESS; OB_CALLBACK_REGISTRATION obCallbackReg = { 0 }; OB_OPERATION_REGISTRATION obOperationReg = { 0 };
RtlZeroMemory(&obCallbackReg, sizeof(OB_CALLBACK_REGISTRATION)); RtlZeroMemory(&obOperationReg, sizeof(OB_OPERATION_REGISTRATION));
obCallbackReg.Version = ObGetFilterVersion(); obCallbackReg.OperationRegistrationCount = 1; obCallbackReg.RegistrationContext = NULL; RtlInitUnicodeString(&obCallbackReg.Altitude, L"321000"); obCallbackReg.OperationRegistration = &obOperationReg;
obOperationReg.ObjectType = PsProcessType; obOperationReg.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE; obOperationReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)(&ProcessPreCall);
status = ObRegisterCallbacks(&obCallbackReg, &g_obProcessHandle); if (!NT_SUCCESS(status)) { DbgPrint("ObRegisterCallbacks Error[0x%X]\n", status); return status; }
return status; }
NTSTATUS SetThreadCallbacks() { NTSTATUS status = STATUS_SUCCESS; OB_CALLBACK_REGISTRATION obCallbackReg = { 0 }; OB_OPERATION_REGISTRATION obOperationReg = { 0 };
RtlZeroMemory(&obCallbackReg, sizeof(OB_CALLBACK_REGISTRATION)); RtlZeroMemory(&obOperationReg, sizeof(OB_OPERATION_REGISTRATION));
obCallbackReg.Version = ObGetFilterVersion(); obCallbackReg.OperationRegistrationCount = 1; obCallbackReg.RegistrationContext = NULL; RtlInitUnicodeString(&obCallbackReg.Altitude, L"321001"); obCallbackReg.OperationRegistration = &obOperationReg;
obOperationReg.ObjectType = PsThreadType; obOperationReg.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE; obOperationReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)(&ThreadPreCall);
status = ObRegisterCallbacks(&obCallbackReg, &g_obThreadHandle); if (!NT_SUCCESS(status)) { DbgPrint("ObRegisterCallbacks Error[0x%X]\n", status); return status; }
return status; }
VOID RemoveProcessCallbacks() { if (NULL != g_obProcessHandle) { ObUnRegisterCallbacks(g_obProcessHandle); g_obProcessHandle = NULL; } }
VOID RemoveThreadCallbacks() { if (NULL != g_obThreadHandle) { ObUnRegisterCallbacks(g_obThreadHandle); g_obThreadHandle = NULL; } }
OB_PREOP_CALLBACK_STATUS ProcessPreCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pObPreOperationInfo) { PEPROCESS pEProcess = NULL;
if (*PsProcessType != pObPreOperationInfo->ObjectType) { return OB_PREOP_SUCCESS; } pEProcess = (PEPROCESS)pObPreOperationInfo->Object; if (IsProtectProcess(pEProcess)) { if (OB_OPERATION_HANDLE_CREATE == pObPreOperationInfo->Operation) { if (1 == (1 & pObPreOperationInfo->Parameters->CreateHandleInformation.OriginalDesiredAccess)) { pObPreOperationInfo->Parameters->CreateHandleInformation.DesiredAccess = 0; } } else if (OB_OPERATION_HANDLE_DUPLICATE == pObPreOperationInfo->Operation) { if (1 == (1 & pObPreOperationInfo->Parameters->DuplicateHandleInformation.OriginalDesiredAccess)) { pObPreOperationInfo->Parameters->DuplicateHandleInformation.DesiredAccess = 0; } } }
return OB_PREOP_SUCCESS; }
OB_PREOP_CALLBACK_STATUS ThreadPreCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pObPreOperationInfo) { PEPROCESS pEProcess = NULL;
if (*PsThreadType != pObPreOperationInfo->ObjectType) { return OB_PREOP_SUCCESS; } pEProcess = IoThreadToProcess((PETHREAD)pObPreOperationInfo->Object); if (IsProtectProcess(pEProcess)) { if (OB_OPERATION_HANDLE_CREATE == pObPreOperationInfo->Operation) { if (1 == (1 & pObPreOperationInfo->Parameters->CreateHandleInformation.OriginalDesiredAccess)) { pObPreOperationInfo->Parameters->CreateHandleInformation.DesiredAccess = 0; } } else if (OB_OPERATION_HANDLE_DUPLICATE == pObPreOperationInfo->Operation) { if (1 == (1 & pObPreOperationInfo->Parameters->DuplicateHandleInformation.OriginalDesiredAccess)) { pObPreOperationInfo->Parameters->DuplicateHandleInformation.DesiredAccess = 0; } } }
return OB_PREOP_SUCCESS; }
BOOLEAN IsProtectProcess(PEPROCESS pEProcess) { PUCHAR pProcessName = PsGetProcessImageFileName(pEProcess); if (NULL != pProcessName) { if (0 == _stricmp(pProcessName, "520.exe")) { DbgPrint("[Protect]"); return TRUE; }
DbgPrint("ProcessName=%s\n", pProcessName); } return FALSE; }
|
反对象监控
基本原理
与反注册表监控很像,这里不细讲了。
系统所有ObRegisterCallbacks
对象回调函数的地址存储在系统中以CallbackList
为表头的双向链表中,包括操作前后回调地址和对象回调句柄信息。
CallbackList
双向链表指向的数据结构:
1 2 3 4 5 6 7 8 9 10
| #pragma pack(1) typedef struct _OB_CALLBACK { LIST_ENTRY ListEntry; ULONGLONG Unknown; HANDLE ObHandle; PVOID ObTypeAddr; PVOID PreCall; PVOID PostCall; }OB_CALLBACK, * POB_CALLBACK; #pragma pack()
|
获取CallbackList
地址方法:直接从对象类型中导出。从*PsProcessType
中获取进程对象回调函数双向链表信息,从*PsThreadType
中获取线程对象回调函数双向链表信息。这俩数据结构类型分别为POBJECT_TYPE和POBJECT_TYPE,这俩定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| typedef struct _OBJECT_TYPE { LIST_ENTRY TypeList; UNICODE_STRING Name; PVOID DefaultObject; UCHAR Index; ULONG TotalNumberOfObjects; ULONG TotalNumberOfHandles; ULONG HighWaterNumberOfObjects; ULONG HighWaterNumberOfHandles; OBJECT_TYPE_INITIALIZER TypeInfo; EX_PUSH_LOCK TypeLock; ULONG Key; LIST_ENTRY CallbackList; }OBJECT_TYPE, * POBJECT_TYPE;
|
其中OBJECT_TYPE_INITIALIZER结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| typedef struct _OBJECT_TYPE_INITIALIZER { USHORT Length; UCHAR ObjectTypeFlags; ULONG ObjectTypeCode; ULONG InvalidAttributes; GENERIC_MAPPING GenericMapping; ULONG ValidAccessMask; ULONG RetainAccess; POOL_TYPE PoolType; ULONG DefaultPagedPoolCharge; ULONG DefaultNonPagedPoolCharge; PVOID DumpProcedure; PVOID OpenProcedure; PVOID CloseProcedure; PVOID DeleteProcedure; PVOID ParseProcedure; PVOID SecurityProcedure; PVOID QueryNameProcedure; PVOID OkayToCloseProcedure; #if (NTDDI_VERSION >= NTDDI_WINBLUE) ULONG WaitObjectFlagMask; USHORT WaitObjectFlagOffset; USHORT WaitObjectPointerOffset; #endif }OBJECT_TYPE_INITIALIZER, * POBJECT_TYPE_INITIALIZER;
|
其实系统在wdm.h中已经为程序导入了*PsProcessType
和*PsThreadType
:
1 2 3 4 5 6 7 8 9 10 11 12
| extern POBJECT_TYPE *CmKeyObjectType; extern POBJECT_TYPE *IoFileObjectType; extern POBJECT_TYPE *ExEventObjectType; extern POBJECT_TYPE *ExSemaphoreObjectType; extern POBJECT_TYPE *TmTransactionManagerObjectType; extern POBJECT_TYPE *TmResourceManagerObjectType; extern POBJECT_TYPE *TmEnlistmentObjectType; extern POBJECT_TYPE *TmTransactionObjectType; extern POBJECT_TYPE *PsProcessType; extern POBJECT_TYPE *PsThreadType; extern POBJECT_TYPE *PsJobType; extern POBJECT_TYPE *SeTokenObjectType;
|
但是这俩获取方式还不大一样,分别为:
1 2
| LIST_ENTRY CallbackList = ((POBJECT_TYPE)(*PsProcessType))->CallbackList; LIST_ENTRY CallbackList = ((POBJECT_TYPE)(*PsThreadType))->CallbackList;
|
以下是枚举系统进程对象回调函数的实现代码,线程改一下链表表头地址的获取即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| BOOLEAN EnumProcessObCallback(VOID) { POB_CALLBACK pObCallback = NULL; LIST_ENTRY CallbackList = ((POBJECT_TYPE)(*PsProcessType))->CallbackList; pObCallback = (POB_CALLBACK)CallbackList.Flink; do { if (FALSE == MmIsAddressValid(pObCallback)) break; if (NULL != pObCallback->ObHandle) { DbgPrint("[PsProcessType]pObCallback->ObHandle = 0x%p\n", pObCallback->ObHandle); DbgPrint("[PsProcessType]pObCallback->PreCall = 0x%p\n", pObCallback->PreCall); DbgPrint("[PsProcessType]pObCallback->PostCall = 0x%p\n", pObCallback->PostCall); }; pObCallback = (POB_CALLBACK)pObCallback->ListEntry.Flink; } while (CallbackList.Flink != (PLIST_ENTRY)pObCallback); return TRUE; };
|
删除对象回调函数:
1 2 3 4 5
| NTSTATUS RemoveObCallback(PVOID RegistrationHandle) { ObUnRegisterCallbacks(RegistrationHandle); return STATUS_SUCCESS; };
|
源代码
Driver.h:
1 2 3 4 5 6 7 8 9 10 11 12
| #ifndef _DRIVER_H_ #define _DRIVER_H_
#include <ntddk.h>
VOID DriverUnload(PDRIVER_OBJECT pDriverObject); NTSTATUS DriverDefaultHandle(PDEVICE_OBJECT pDevObj, PIRP pIrp);
#endif
|
EnumRemove.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| #ifndef _ENUM_REMOVE_H_ #define _ENUM_REMOVE_H_
#include <ntifs.h> #include <wdm.h>
typedef struct _OBJECT_TYPE_INITIALIZER { USHORT Length; UCHAR ObjectTypeFlags; ULONG ObjectTypeCode; ULONG InvalidAttributes; GENERIC_MAPPING GenericMapping; ULONG ValidAccessMask; ULONG RetainAccess; POOL_TYPE PoolType; ULONG DefaultPagedPoolCharge; ULONG DefaultNonPagedPoolCharge; PVOID DumpProcedure; PVOID OpenProcedure; PVOID CloseProcedure; PVOID DeleteProcedure; PVOID ParseProcedure; PVOID SecurityProcedure; PVOID QueryNameProcedure; PVOID OkayToCloseProcedure; #if (NTDDI_VERSION >= NTDDI_WINBLUE) ULONG WaitObjectFlagMask; USHORT WaitObjectFlagOffset; USHORT WaitObjectPointerOffset; #endif }OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
typedef struct _OBJECT_TYPE { LIST_ENTRY TypeList; UNICODE_STRING Name; PVOID DefaultObject; UCHAR Index; ULONG TotalNumberOfObjects; ULONG TotalNumberOfHandles; ULONG HighWaterNumberOfObjects; ULONG HighWaterNumberOfHandles; OBJECT_TYPE_INITIALIZER TypeInfo; EX_PUSH_LOCK TypeLock; ULONG Key; LIST_ENTRY CallbackList; }OBJECT_TYPE, *POBJECT_TYPE;
#pragma pack(1) typedef struct _OB_CALLBACK { LIST_ENTRY ListEntry; ULONGLONG Unknown; HANDLE ObHandle; PVOID ObTypeAddr; PVOID PreCall; PVOID PostCall; }OB_CALLBACK, *POB_CALLBACK; #pragma pack()
BOOLEAN EnumProcessObCallback();
BOOLEAN EnumThreadObCallback();
NTSTATUS RemoveObCallback(PVOID RegistrationHandle);
#endif
|
Driver.c:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #include "EnumRemove.h" #include "Driver.h"
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath) { DbgPrint("Enter DriverEntry\n");
NTSTATUS status = STATUS_SUCCESS; pDriverObject->DriverUnload = DriverUnload; for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { pDriverObject->MajorFunction[i] = DriverDefaultHandle; }
EnumProcessObCallback();
EnumThreadObCallback();
DbgPrint("Leave DriverEntry\n"); return status; }
VOID DriverUnload(PDRIVER_OBJECT pDriverObject) { }
NTSTATUS DriverDefaultHandle(PDEVICE_OBJECT pDevObj, PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = 0; IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status; }
|
EnumRemove.c:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| #include "EnumRemove.h"
VOID ShowError(PCHAR lpszText, NTSTATUS ntStatus) { DbgPrint("%s Error[0x%X]\n", lpszText, ntStatus); }
BOOLEAN EnumProcessObCallback() { POB_CALLBACK pObCallback = NULL;
LIST_ENTRY CallbackList = ((POBJECT_TYPE)(*PsProcessType))->CallbackList;
pObCallback = (POB_CALLBACK)CallbackList.Flink; do { if (FALSE == MmIsAddressValid(pObCallback)) { break; } if (NULL != pObCallback->ObHandle) { DbgPrint("[PsProcessType]pObCallback->ObHandle = 0x%p\n", pObCallback->ObHandle); DbgPrint("[PsProcessType]pObCallback->PreCall = 0x%p\n", pObCallback->PreCall); DbgPrint("[PsProcessType]pObCallback->PostCall = 0x%p\n", pObCallback->PostCall); } pObCallback = (POB_CALLBACK)pObCallback->ListEntry.Flink; } while (CallbackList.Flink != (PLIST_ENTRY)pObCallback);
return TRUE; }
BOOLEAN EnumThreadObCallback() { POB_CALLBACK pObCallback = NULL;
LIST_ENTRY CallbackList = ((POBJECT_TYPE)(*PsThreadType))->CallbackList;
pObCallback = (POB_CALLBACK)CallbackList.Flink; do { if (FALSE == MmIsAddressValid(pObCallback)) { break; } if (NULL != pObCallback->ObHandle) { DbgPrint("[PsThreadype]pObCallback->ObHandle = 0x%p\n", pObCallback->ObHandle); DbgPrint("[PsThreadType]pObCallback->PreCall = 0x%p\n", pObCallback->PreCall); DbgPrint("[PsThreadType]pObCallback->PostCall = 0x%p\n", pObCallback->PostCall); } pObCallback = (POB_CALLBACK)pObCallback->ListEntry.Flink;
} while (CallbackList.Flink != (PLIST_ENTRY)pObCallback);
return TRUE; }
NTSTATUS RemoveObCallback(PVOID RegistrationHandle) { ObUnRegisterCallbacks(RegistrationHandle); return STATUS_SUCCESS; }
|