📄 regmon.c
字号:
break;
case RegNtQueryKey:
queryKey = (PREG_QUERY_KEY_INFORMATION)Argument2;
regDataType = queryKey->KeyInformationClass;
regEventIsValid = GetRegistryObjectCompleteName(&RegPath, NULL, queryKey->Object);
break;
case RegNtQueryValueKey:
queryValueKey = (PREG_QUERY_VALUE_KEY_INFORMATION)Argument2;
regEventIsValid = GetRegistryObjectCompleteName(&RegPath, NULL, queryValueKey->Object);
if((regEventIsValid) && (queryValueKey->ValueName->Length > 0))
{
regDataType = queryValueKey->KeyValueInformationClass;
RtlUnicodeStringCatString(&RegPath,L"\\");
RtlUnicodeStringCat(&RegPath, queryValueKey->ValueName);
}
break;
case RegNtKeyHandleClose:
closeKey = (PREG_KEY_HANDLE_CLOSE_INFORMATION)Argument2;
regEventIsValid = GetRegistryObjectCompleteName(&RegPath, NULL, closeKey->Object);
break;
default:
break;
}
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
regEventIsValid = FALSE;
exception = TRUE;
}
if( regEventIsValid )
{
PREGISTRY_EVENT pRegistryEvent;
UINT eventSize = sizeof(REGISTRY_EVENT) + RegPath.Length + (sizeof(WCHAR)) + regDataLength;
pRegistryEvent = ExAllocatePoolWithTag(NonPagedPool, eventSize, REGISTRY_POOL_TAG);
if( pRegistryEvent != NULL )
{
pRegistryEvent->registryPathLengthB = RegPath.Length + sizeof(WCHAR);
pRegistryEvent->dataType = regDataType;
pRegistryEvent->dataLengthB = regDataLength;
//RtlStringCbCopyUnicodeString(pRegistryEvent->registryPath, pRegistryEvent->registryPathLength, ®istryPath);
RtlCopyBytes(pRegistryEvent->registryData, RegPath.Buffer, RegPath.Length);
pRegistryEvent->registryData[RegPath.Length] = '\0';
pRegistryEvent->registryData[RegPath.Length+1] = '\0';
RtlCopyBytes(pRegistryEvent->registryData+pRegistryEvent->registryPathLengthB, regData, regDataLength);
if(regData != NULL)
{
ExFreePoolWithTag(regData, REGISTRY_POOL_TAG);
}
pRegistryEvent->processId = PsGetCurrentProcessId();
RtlTimeToTimeFields(&CurrentLocalTime,&pRegistryEvent->time);
pRegistryEvent->eventType = (REG_NOTIFY_CLASS)Argument1;
if(!QueueRegistryEvent(pRegistryEvent))
{
ExFreePoolWithTag(pRegistryEvent, REGISTRY_POOL_TAG);
}
}
}
if(RegPath.Buffer != NULL)
{
ExFreePoolWithTag(RegPath.Buffer, REGISTRY_POOL_TAG);
}
/* Always return a success ... we aren't doing any filtering, just monitoring */
return STATUS_SUCCESS;
}
NTSTATUS CreateCloseDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information=0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS HandleIoctl(IN PDEVICE_OBJECT pDeviceObject, PIRP pIrp, PIO_STACK_LOCATION stack, UINT *pdwDataWritten)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
char* pOutputBuffer = pIrp->UserBuffer;
UINT dwOutputBufferSize = stack->Parameters.DeviceIoControl.OutputBufferLength;
PDEVICE_EXTENSION pde;
pde = gl_DeviceObject->DeviceExtension;
*pdwDataWritten = 0;
if(pOutputBuffer)
{
__try
{
ProbeForWrite(pOutputBuffer, stack->Parameters.DeviceIoControl.OutputBufferLength, __alignof (REGISTRY_EVENT));
if(stack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(REGISTRY_EVENT))
{
PLIST_ENTRY pRegistryListHead;
PREGISTRY_EVENT_PACKET packet;
UINT bufferSpace = dwOutputBufferSize;
UINT bufferSpaceUsed = 0;
while(!IsListEmpty(&pde->queuedRegistryEvents) && (bufferSpaceUsed < bufferSpace) && ((bufferSpace-bufferSpaceUsed) >= sizeof(REGISTRY_EVENT)))
{
UINT registryEventSize = 0;
pRegistryListHead = ExInterlockedRemoveHeadList(&pde->queuedRegistryEvents, &pde->guard);
packet = CONTAINING_RECORD(pRegistryListHead, REGISTRY_EVENT_PACKET, Link);
registryEventSize = sizeof(REGISTRY_EVENT) + packet->pRegistryEvent->registryPathLengthB + packet->pRegistryEvent->dataLengthB;
if((bufferSpace-bufferSpaceUsed) >= registryEventSize)
{
//DbgPrint("Sending-%i: %ls\n",bufferSpaceUsed, pRegistryPacket->pRegistryEvent->registryPath);
RtlCopyMemory(pOutputBuffer + bufferSpaceUsed, packet->pRegistryEvent, registryEventSize);
bufferSpaceUsed += registryEventSize;
ExFreePoolWithTag(packet->pRegistryEvent, REGISTRY_POOL_TAG);
ExFreePoolWithTag(packet, REGISTRY_POOL_TAG);
}
else
{
ExInterlockedInsertHeadList(&pde->queuedRegistryEvents, &packet->Link, &pde->guard);
break;
}
}
*pdwDataWritten = bufferSpaceUsed;
status = STATUS_SUCCESS;
}
else
{
*pdwDataWritten = sizeof(REGISTRY_EVENT);
status = STATUS_BUFFER_TOO_SMALL;
}
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
status = GetExceptionCode();
DbgPrint("CaptureRegistryMonitor: EXCEPTION IOCTL_CAPTURE_GET_REGEVENTS - %i\n", status);
}
}
return status;
}
NTSTATUS IoctlDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
UINT dwDataWritten = 0;
switch(stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_CAPTURE_GET_REGEVENTS:
UpdateLastContactTime();
status = HandleIoctl(pDeviceObject, pIrp, stack, &dwDataWritten);
break;
default:
break;
}
pIrp->IoStatus.Status = status;
if(NT_SUCCESS(status))
pIrp->IoStatus.Information = dwDataWritten;
else
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
VOID OnUnload(IN PDRIVER_OBJECT pDriverObject)
{
UNICODE_STRING device_name;
NTSTATUS status;
PDEVICE_EXTENSION pde;
/* Get the registry manager from the device extension */
pde = gl_DeviceObject->DeviceExtension;
if(pde->ready == TRUE)
{
KeCancelTimer(&pde->connectionCheckerTimer);
CmUnRegisterCallback(pde->registryCallbackCookie);
pde->ready = FALSE;
}
while(!IsListEmpty(&pde->queuedRegistryEvents))
{
PLIST_ENTRY head = ExInterlockedRemoveHeadList(&pde->queuedRegistryEvents, &pde->guard);
PREGISTRY_EVENT_PACKET packet = CONTAINING_RECORD(head, REGISTRY_EVENT_PACKET, Link);
ExFreePoolWithTag(packet->pRegistryEvent, REGISTRY_POOL_TAG);
ExFreePoolWithTag(packet, REGISTRY_POOL_TAG);
}
RtlInitUnicodeString(&device_name, L"\\DosDevices\\CaptureRegistryMonitor");
IoDeleteSymbolicLink(&device_name);
if(pDriverObject->DeviceObject != NULL)
IoDeleteDevice(pDriverObject->DeviceObject);
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegPath)
{
UNICODE_STRING device_name, sym_link;
NTSTATUS status;
PDEVICE_OBJECT device;
PDEVICE_EXTENSION dextension;
LARGE_INTEGER registryEventsTimeout;
RtlInitUnicodeString(&device_name, L"\\Device\\RegistryMonitor");
status = IoCreateDevice(pDriverObject,
sizeof(DEVICE_EXTENSION),
&device_name,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&device);
if(!NT_SUCCESS(status))
{
DbgPrint("Unable to create device! Status - 0x%.0x", status);
return status;
}
gl_DeviceObject = device;
dextension = gl_DeviceObject->DeviceExtension;
dextension->ready = FALSE;
RtlInitUnicodeString(&sym_link, L"\\DosDevices\\RegMon");
status = IoCreateSymbolicLink(&sym_link, &device_name);
if(!NT_SUCCESS(status))
{
DbgPrint("Unable to create symlink! Status - 0x%.0x", status);
IoDeleteDevice(device);
return status;
}
KeInitializeSpinLock(&dextension->guard);
InitializeListHead(&dextension->queuedRegistryEvents);
pDriverObject->DriverUnload = OnUnload;
pDriverObject->MajorFunction[IRP_MJ_CREATE] =
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = CreateCloseDispatch;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoctlDispatch;
status = CmRegisterCallback(RegistryCallback, dextension, &dextension->registryCallbackCookie);
if(!NT_SUCCESS(status))
{
DbgPrint("CmRegisterCallback failed! Status - 0x%.0x", status);
return status;
}
UpdateLastContactTime();
/* Create a DPC routine so that it can be called periodically */
KeInitializeDpc(&dextension->connectionCheckerFunction, (PKDEFERRED_ROUTINE) ConnectionChecker, dextension);
KeInitializeTimer(&dextension->connectionCheckerTimer);
registryEventsTimeout.QuadPart = 0;
/* Set the ConnectionChecker routine to be called every so often */
KeSetTimerEx(&dextension->connectionCheckerTimer, registryEventsTimeout,
(USERSPACE_CONNECTION_TIMEOUT+(USERSPACE_CONNECTION_TIMEOUT/2))*1000,
&dextension->connectionCheckerFunction);
dextension->ready = TRUE;
DbgPrint("RegistryMonitor successfully loaded at <%s> <%s>", __TIME__, __DATE__);
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -