又开始学内核编程
注册表回调保护
使用系统API CmRegisterCallback
1 2 3 4 5
| NTSTATUS CmRegisterCallback( [in] PEX_CALLBACK_FUNCTION Function, [in, optional] PVOID Context, [out] PLARGE_INTEGER Cookie );
|
指向LARGE_INTEGER变量的指针,该变量接收标识回调例程的值。 注销回调例程时,请将此值作为 Cookie 参数传递给 CmUnRegisterCallback
指向要注册的 RegistryCallback 例程的指针。
配置管理器将作为 CallbackContext 参数传递给 RegistryCallback 例程的驱动程序定义值
指向LARGE_INTEGER变量的指针,该变量接收标识回调例程的值。 注销回调例程时,请将此值作为 Cookie 参数传递给 CmUnRegisterCallback。
设置注册表回调参数
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
| #include <ntifs.h>
LARGE_INTEGER cookie = {0};
NTSTATUS RegCallback(PVOID callbackContext, PVOID optType, PVOID optData) { REG_NOTIFY_CLASS tempclass = (REG_NOTIFY_CLASS)optType; switch (tempclass) { case RegNtPreOpenKey: case RegNtPreOpenKeyEx: case RegNtPreCreateKeyEx: case RegNtPreCreateKey: { DbgPrint("Create/Open Key\n"); PREG_CREATE_KEY_INFORMATION pkey = (PREG_CREATE_KEY_INFORMATION)optData; __try { DbgPrint("key: <%wZ>\n", pkey->CompleteName); } __except(1){ DbgPrint("bad memory\n"); }
break; } default: break; } return STATUS_SUCCESS; }
VOID DriverUnload(PDRIVER_OBJECT DriverObject) { UNREFERENCED_PARAMETER(DriverObject); DbgPrint("Driver Stopping -> %wZ\n", &DriverObject->DriverName); CmUnRegisterCallback(cookie); }
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { UNREFERENCED_PARAMETER(RegistryPath);
DbgPrint("Driver Running -> %wZ\n", &DriverObject->DriverName); DriverObject->DriverUnload = DriverUnload;
NTSTATUS status = STATUS_SUCCESS; status = CmRegisterCallback(RegCallback, (PVOID)0x123456, &cookie);
return STATUS_SUCCESS; }
|

进行拦截操作,就是稍微匹配一下
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
| NTSTATUS RegCallback(PVOID callbackContext, PVOID optType, PVOID optData) { NTSTATUS status = STATUS_SUCCESS; REG_NOTIFY_CLASS tempclass = (REG_NOTIFY_CLASS)optType;
UNICODE_STRING tempname = { 0 }; RtlInitUnicodeString(&tempname, L"*DRIVERTEST");
switch (tempclass) { case RegNtPreOpenKey: case RegNtPreOpenKeyEx: case RegNtPreCreateKeyEx: case RegNtPreCreateKey: { PREG_CREATE_KEY_INFORMATION pkey = (PREG_CREATE_KEY_INFORMATION)optData; __try { if (FsRtlIsNameInExpression(&tempname, pkey->CompleteName, TRUE, NULL)) { DbgPrint("can't create such reg\n"); status = STATUS_UNSUCCESSFUL; } } __except(1){ DbgPrint("bad memory\n"); }
break; } default: break; } return status; }
|

对象/进程回调
也就是注册一个 对 进程对象 的回调函数
1 2 3 4 5 6 7
| typedef struct _OB_CALLBACK_REGISTRATION { USHORT Version; USHORT OperationRegistrationCount; UNICODE_STRING Altitude; PVOID RegistrationContext; OB_OPERATION_REGISTRATION *OperationRegistration; } OB_CALLBACK_REGISTRATION, *POB_CALLBACK_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 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
| #include <ntifs.h> #include <windef.h>
PCHAR PsGetProcessImageFileName(PEPROCESS EProcess);
typedef struct _LDR_DATA_TABLE_ENTRY { LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; USHORT LoadCount; USHORT TlsIndex; union { LIST_ENTRY HashLinks; struct { PVOID SectionPointer; ULONG CheckSum; }; }; union { ULONG TimeDateStamp; PVOID LoadedImports; }; PVOID EntryPointActivationContext; PVOID PatchInformation; } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
PVOID Handle = NULL;
static OB_PREOP_CALLBACK_STATUS ProtectProcess( _In_ PVOID RegistrationContext, _Inout_ POB_PRE_OPERATION_INFORMATION OperationInformation ) { PUCHAR imageFileName = PsGetProcessImageFileName(OperationInformation->Object); DbgPrint("open/duplicate process: %s\n", imageFileName); return OB_PREOP_SUCCESS; }
VOID DriverUnload(PDRIVER_OBJECT DriverObject) { UNREFERENCED_PARAMETER(DriverObject); DbgPrint("Driver Stopping -> %wZ\n", &DriverObject->DriverName); ObUnRegisterCallbacks(Handle); }
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { UNREFERENCED_PARAMETER(RegistryPath);
DbgPrint("Driver Running -> %wZ\n", &DriverObject->DriverName); DriverObject->DriverUnload = DriverUnload;
NTSTATUS status = STATUS_SUCCESS;
PLDR_DATA_TABLE_ENTRY ldr = (PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection; ldr->Flags |= 0x20; OB_CALLBACK_REGISTRATION ob = { 0 }; OB_OPERATION_REGISTRATION obReg = { 0 }; UNICODE_STRING altitude = { 0 }; RtlInitUnicodeString(&altitude, L"32199"); ob.Version = ObGetFilterVersion(); ob.OperationRegistrationCount = 1; ob.OperationRegistration = &obReg; ob.Altitude = altitude; ob.RegistrationContext = NULL;
obReg.ObjectType = PsProcessType; obReg.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE; obReg.PreOperation = ProtectProcess; obReg.PostOperation = NULL;
status = ObRegisterCallbacks(&ob, &Handle); return status; }
|

设置访问等级可以让进程不会被关闭
1 2 3 4 5 6 7 8 9 10 11 12
| static OB_PREOP_CALLBACK_STATUS ProtectProcess( _In_ PVOID RegistrationContext, _Inout_ POB_PRE_OPERATION_INFORMATION OperationInformation ) { PUCHAR imageFileName = PsGetProcessImageFileName(OperationInformation->Object); if (strstr(imageFileName, "Calc")) { OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = 0; OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = 0; } return OB_PREOP_SUCCESS; }
|

同时也可以保护进程内存不被访问到
