⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 regmon.c

📁 RegistryMonitor as driver, lang:C
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <ntddk.h>
#include <ntstrsafe.h>
#include <ntifs.h>

//NTSTATUS  
//RtlUnicodeStringCopy(    
//					 OUT PUNICODE_STRING  DestinationString,    
//					 IN PCUNICODE_STRING  SourceString    );
//
//NTSTATUS  
//RtlUnicodeStringCatString(    
//						  IN OUT PUNICODE_STRING  DestinationString,    
//						  IN LPCTSTR  pszSrc    );
//
//NTSTATUS  
//RtlUnicodeStringCat(    
//					IN OUT PUNICODE_STRING  DestinationString,    
//					IN PCUNICODE_STRING  SourceString    );

#define USERSPACE_CONNECTION_TIMEOUT 10
#define NTSTRSAFE_UNICODE_STRING_MAX_CCH  2147483647
#define REGISTRY_POOL_TAG 'pRE'
#define FILE_DEVICE_UNKNOWN     0x00000022
#define IOCTL_CAPTURE_GET_REGEVENTS     CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_NEITHER,FILE_READ_DATA | FILE_WRITE_DATA)
typedef unsigned int UINT;

PDEVICE_OBJECT gl_DeviceObject;

typedef struct _DEVICE_EXTENSION
{
	BOOLEAN ready;
	KSPIN_LOCK guard;
	LIST_ENTRY queuedRegistryEvents;
	LARGE_INTEGER  registryCallbackCookie;
	KTIMER connectionCheckerTimer;
	KDPC connectionCheckerFunction;
	ULONG lastContactTime;
		
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;

typedef struct  _REGISTRY_EVENT 
{
        REG_NOTIFY_CLASS eventType;
        TIME_FIELDS time;
        HANDLE processId;
        ULONG dataType;
        ULONG dataLengthB;
        ULONG registryPathLengthB;
        UCHAR registryData[];
} REGISTRY_EVENT, * PREGISTRY_EVENT;

typedef struct  _REGISTRY_EVENT_PACKET 
{
    LIST_ENTRY     Link;
    PREGISTRY_EVENT pRegistryEvent;
} REGISTRY_EVENT_PACKET, * PREGISTRY_EVENT_PACKET;



ULONG GetCurrentTime()
{
    LARGE_INTEGER currentSystemTime;
    LARGE_INTEGER currentLocalTime;
    ULONG time;
    KeQuerySystemTime(&currentSystemTime);
    ExSystemTimeToLocalTime(&currentSystemTime,&currentLocalTime);
    RtlTimeToSecondsSince1970(&currentLocalTime, &time);
    return time;
}

VOID UpdateLastContactTime()
{
   PDEVICE_EXTENSION pde;
   pde = gl_DeviceObject->DeviceExtension;
   pde->lastContactTime = GetCurrentTime();
}

VOID ConnectionChecker(PKDPC  Dpc, IN PVOID  DeferredContext, IN PVOID  SystemArgument1, IN PVOID  SystemArgument2)
{

	 PDEVICE_EXTENSION pde = (PDEVICE_EXTENSION)DeferredContext;
     if((GetCurrentTime() - pde->lastContactTime) > (USERSPACE_CONNECTION_TIMEOUT+(USERSPACE_CONNECTION_TIMEOUT/2)))
     {
         DbgPrint("RegistryMonitor: WARNING Userspace IOCTL timeout, clearing old queued registry events\n");
         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);
         }
     }
}

BOOLEAN GetRegistryObjectCompleteName(PUNICODE_STRING RegPath, PUNICODE_STRING PartialRegPath, PVOID RegObject)
{
	 PDEVICE_EXTENSION pde = gl_DeviceObject->DeviceExtension;
     BOOLEAN foundCompleteName = FALSE;
     BOOLEAN partial = FALSE;
	 if((!MmIsAddressValid(RegObject)) || (RegObject == NULL))
     {
            return FALSE;
     }
	 if(PartialRegPath != NULL)
     {
           if(     (((PartialRegPath->Buffer[0] == '\\') || (PartialRegPath->Buffer[0] == '%')) ||
                        ((PartialRegPath->Buffer[0] == 'T') && (PartialRegPath->Buffer[1] == 'R') && (PartialRegPath->Buffer[2] == 'Y') && (PartialRegPath->Buffer[3] == '\\'))) )
             {
                    RtlUnicodeStringCopy(RegPath, PartialRegPath);
                    partial = TRUE;
                    foundCompleteName = TRUE;
             }
     }
     if(!foundCompleteName)
     {
                /* Query the object manager in the kernel for the complete name */
           NTSTATUS  status;
           ULONG     returnedLength;
           PUNICODE_STRING pObjectName = NULL;
           status = ObQueryNameString(RegObject, (POBJECT_NAME_INFORMATION)pObjectName, 0, &returnedLength );
           if(status == STATUS_INFO_LENGTH_MISMATCH)
           {
                  pObjectName = ExAllocatePoolWithTag(NonPagedPool, returnedLength, REGISTRY_POOL_TAG);
                  status = ObQueryNameString(RegObject, (POBJECT_NAME_INFORMATION)pObjectName, returnedLength, &returnedLength );
                  if(NT_SUCCESS(status))
                  {
                       RtlUnicodeStringCopy(RegPath, pObjectName);
                       foundCompleteName = TRUE;
                  }
                  ExFreePoolWithTag(pObjectName, REGISTRY_POOL_TAG);
            }
        }
        //ASSERT(foundCompleteName == TRUE);
        return foundCompleteName;

}

BOOLEAN QueueRegistryEvent(PREGISTRY_EVENT pRegistryEvent)
{
    PDEVICE_EXTENSION pde = gl_DeviceObject->DeviceExtension;
    /* Check the last contact time of the user space program before queuing */
    if( (GetCurrentTime() - pde->lastContactTime) <= USERSPACE_CONNECTION_TIMEOUT)
    {
         PREGISTRY_EVENT_PACKET pRegistryEventPacket = ExAllocatePoolWithTag(NonPagedPool, sizeof(REGISTRY_EVENT_PACKET), REGISTRY_POOL_TAG);
         pRegistryEventPacket->pRegistryEvent = pRegistryEvent;
               /* Queue registry event */
         ExInterlockedInsertTailList(&pde->queuedRegistryEvents, &pRegistryEventPacket->Link, &pde->guard);
         return TRUE;
    }
    return FALSE;
}

NTSTATUS RegistryCallback(IN PVOID CallbackContext, IN PVOID  Argument1, IN PVOID  Argument2)
{
	BOOLEAN regEventIsValid = FALSE;
	BOOLEAN exception = FALSE;
	LARGE_INTEGER CurrentSystemTime;
	LARGE_INTEGER CurrentLocalTime;
	PREG_POST_CREATE_KEY_INFORMATION createKey = NULL;
	PREG_POST_OPEN_KEY_INFORMATION openKey = NULL;
	PREG_DELETE_VALUE_KEY_INFORMATION deleteValueKey = NULL;
	PREG_DELETE_KEY_INFORMATION deleteKey = NULL;
	PREG_SET_VALUE_KEY_INFORMATION setValueKey = NULL;
	PREG_ENUMERATE_KEY_INFORMATION enumerateKey = NULL;
	PREG_ENUMERATE_VALUE_KEY_INFORMATION enumerateValueKey = NULL;
	PREG_QUERY_KEY_INFORMATION queryKey = NULL;
	PREG_QUERY_VALUE_KEY_INFORMATION queryValueKey = NULL;
	PREG_KEY_HANDLE_CLOSE_INFORMATION closeKey = NULL;

	TIME_FIELDS TimeFields;
	int type;
	UNICODE_STRING RegPath;
    PUCHAR regData = NULL;
	ULONG regDataLength = 0;
	ULONG regDataType = 0;
	
	RegPath.Length = 0;
	RegPath.MaximumLength = NTSTRSAFE_UNICODE_STRING_MAX_CCH * sizeof(WCHAR);
	RegPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, RegPath.MaximumLength, REGISTRY_POOL_TAG);

	KeQuerySystemTime(&CurrentSystemTime);
    ExSystemTimeToLocalTime(&CurrentSystemTime,&CurrentLocalTime);

	type = (REG_NOTIFY_CLASS)Argument1;
	__try
	{
		switch(type)
		{
			case RegNtPostCreateKey:
				createKey = (PREG_POST_CREATE_KEY_INFORMATION)Argument2;
				if(NT_SUCCESS(createKey->Status))
				{
					PVOID* registryObject = createKey->Object;
					regEventIsValid = GetRegistryObjectCompleteName(&RegPath, createKey->CompleteName, *registryObject);
				}
				break;
			case RegNtPostOpenKey:
				openKey = (PREG_POST_OPEN_KEY_INFORMATION)Argument2;
				if(NT_SUCCESS(openKey->Status))
				{
					PVOID* registryObject = openKey->Object;
					regEventIsValid = GetRegistryObjectCompleteName(&RegPath, openKey->CompleteName, *registryObject);
				}
				break;
			case RegNtPreDeleteKey:
				deleteKey = (PREG_DELETE_KEY_INFORMATION)Argument2;
				regEventIsValid = GetRegistryObjectCompleteName(&RegPath, NULL, deleteKey->Object);
				break;
			case RegNtDeleteValueKey:
				deleteValueKey = (PREG_DELETE_VALUE_KEY_INFORMATION)Argument2;
				regEventIsValid = GetRegistryObjectCompleteName(&RegPath, NULL, deleteValueKey->Object);
				if((regEventIsValid) && (deleteValueKey->ValueName->Length > 0))
				{
					RtlUnicodeStringCatString(&RegPath, L"\\");
					RtlUnicodeStringCat(&RegPath, deleteValueKey->ValueName);
				}
				break;
			case RegNtPreSetValueKey:
				setValueKey = (PREG_SET_VALUE_KEY_INFORMATION)Argument2;
				regEventIsValid = GetRegistryObjectCompleteName(&RegPath, NULL, setValueKey->Object);
				if((regEventIsValid) && (setValueKey->ValueName->Length > 0))
				{
						regDataType = setValueKey->Type;
						regDataLength = setValueKey->DataSize;
						regData = ExAllocatePoolWithTag(NonPagedPool, regDataLength, REGISTRY_POOL_TAG);
						if(regData != NULL)
						{
								RtlCopyBytes(regData,setValueKey->Data,setValueKey->DataSize);
						} 
						else 
						{
								DbgPrint("RegistryMonitor: ERROR can't allocate memory for setvalue data\n");
						}
						RtlUnicodeStringCatString(&RegPath, L"\\");
						RtlUnicodeStringCat(&RegPath, setValueKey->ValueName);
				}
				break;
			case RegNtEnumerateKey:
				enumerateKey = (PREG_ENUMERATE_KEY_INFORMATION)Argument2;
				regDataType = enumerateKey->KeyInformationClass;
				regEventIsValid = GetRegistryObjectCompleteName(&RegPath, NULL, enumerateKey->Object);
				break;
			case RegNtEnumerateValueKey:
				enumerateValueKey = (PREG_ENUMERATE_VALUE_KEY_INFORMATION)Argument2;
				regDataType = enumerateValueKey->KeyValueInformationClass;
				regEventIsValid = GetRegistryObjectCompleteName(&RegPath, NULL, enumerateValueKey->Object);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -