• 发一注册表监控驱动代码


    该代码利用微软提供的注册表回调函数CmRegisterCallback,无需任何SSDT hook
    不仅能够进行注册表监控,还可以拦截。
    驱动完整代码如下:
    #define NTDDI_WINXPSP2                      0x05010200
    #define OSVERSION_MASK      0xFFFF0000
    #define SPVERSION_MASK      0x0000FF00
    #define SUBVERSION_MASK     0x000000FF

    //
    // macros to extract various version fields from the NTDDI version
    //
    #define OSVER(Version)  ((Version) & OSVERSION_MASK)
    #define SPVER(Version)  (((Version) & SPVERSION_MASK) >> 8)
    #define SUBVER(Version) (((Version) & SUBVERSION_MASK) )
    //#define NTDDI_VERSION   NTDDI_WINXPSP2
    #include <ntifs.h>
    #include <wdm.h>
    #include <ntstrsafe.h>
    #define FILE_DEVICE_UNKNOWN 0x00000022
    #define IOCTL_UNKNOWN_BASE FILE_DEVICE_UNKNOWN
    #define IOCTL_CAPTURE_GET_REGEVENTS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_NEITHER,FILE_READ_DATA | FILE_WRITE_DATA)
    #define USERSPACE_CONNECTION_TIMEOUT 10
    #define REGISTRY_POOL_TAG 'pRE'
    typedef unsigned int UINT;
    typedef char * PCHAR;
    typedef PVOID POBJECT;
    /* Registry event */
    typedef struct  _REGISTRY_EVENT {
    REG_NOTIFY_CLASS eventType;
    TIME_FIELDS time;
    HANDLE processId;
    ULONG dataType;
    ULONG dataLengthB;
    ULONG registryPathLengthB;
    /* Contains path and optionally data */
    UCHAR registryData[];
    } REGISTRY_EVENT, * PREGISTRY_EVENT;
    /* Storage for registry event to be put into a linked list */
    typedef struct  _REGISTRY_EVENT_PACKET {
        LIST_ENTRY     Link;
    PREGISTRY_EVENT pRegistryEvent;
    } REGISTRY_EVENT_PACKET, * PREGISTRY_EVENT_PACKET;
    /* Context stuff */
    typedef struct _CAPTURE_REGISTRY_MANAGER
    {
        PDEVICE_OBJECT deviceObject;
    BOOLEAN bReady;
    LARGE_INTEGER  registryCallbackCookie;
    LIST_ENTRY lQueuedRegistryEvents;
    KTIMER connectionCheckerTimer;
    KDPC connectionCheckerFunction;
    KSPIN_LOCK lQueuedRegistryEventsSpinLock;
    ULONG lastContactTime;
    } CAPTURE_REGISTRY_MANAGER , *PCAPTURE_REGISTRY_MANAGER;
    /* Methods */
    NTSTATUS KDispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
    NTSTATUS KDispatchCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
    VOID UnloadDriver(PDRIVER_OBJECT DriverObject);
    NTSTATUS RegistryCallback(IN PVOID CallbackContext, IN PVOID  Argument1, IN PVOID  Argument2);
    //BOOLEAN GetRegistryObjectCompleteName(PREGISTRY_EVENT pRegistryEvent, PUNICODE_STRING pPartialObjectName, PVOID pRegistryObject);
    //VOID QueueRegistryEvent(PREGISTRY_EVENT pRegistryEvent);
    VOID UpdateLastContactTime();
    ULONG GetCurrentTime();
    NTSTATUS HandleIoctlGetRegEvents(IN PDEVICE_OBJECT DeviceObject, PIRP Irp,
           PIO_STACK_LOCATION pIoStackIrp, UINT *pdwDataWritten);
    VOID ConnectionChecker(
        IN struct _KDPC  *Dpc,
        IN PVOID  DeferredContext,
        IN PVOID  SystemArgument1,
        IN PVOID  SystemArgument2
        );
    /* Global values */
    PDEVICE_OBJECT gpDeviceObject;

    /* Main entry point into the driver, is called when the driver is loaded */
    NTSTATUS DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
    {
        NTSTATUS status;
        UNICODE_STRING uszDriverString;
        UNICODE_STRING uszDeviceString;
    LARGE_INTEGER registryEventsTimeout;
        PDEVICE_OBJECT pDeviceObject;
        PCAPTURE_REGISTRY_MANAGER pRegistryManager;
       
    // Point uszDriverString at the driver name
        RtlInitUnicodeString(&uszDriverString, L"[url=file://\\Device\\RegistryMonitor]\\Device\\RegistryMonitor[/url]");
        // Create and initialize device object
    status = IoCreateDevice(
      DriverObject,
            sizeof(CAPTURE_REGISTRY_MANAGER),
            &uszDriverString,
            FILE_DEVICE_UNKNOWN,
            0,
            FALSE,
            &pDeviceObject
      );
        if(!NT_SUCCESS(status))
    {
      DbgPrint("RegistryMonitor: ERROR IoCreateDevice ->  [url=file://\\Device\\RegistryMonitor]\\Device\\RegistryMonitor[/url] - %08x\n", status);
            return status;
    }
       
    /* Set global device object to newly created object */
    gpDeviceObject = pDeviceObject;
    /* Get the registr manager from the extension of the device */
    pRegistryManager = gpDeviceObject->DeviceExtension;
    pRegistryManager->bReady = FALSE;
       
    /* Point uszDeviceString at the device name */
        RtlInitUnicodeString(&uszDeviceString, L"[url=file://\\DosDevices\\RegistryMonitor]\\DosDevices\\RegistryMonitor[/url]");
    /* Create symbolic link to the user-visible name */
        status = IoCreateSymbolicLink(&uszDeviceString, &uszDriverString);
        if(!NT_SUCCESS(status))
    {
            DbgPrint("RegistryMonitor: ERROR IoCreateSymbolicLink ->  [url=file://\\DosDevices\\RegistryMonitor]\\DosDevices\\RegistryMonitor[/url] - %08x\n", status);
            IoDeleteDevice(pDeviceObject);
            return status;
        }
    KeInitializeSpinLock(&pRegistryManager->lQueuedRegistryEventsSpinLock);
    InitializeListHead(&pRegistryManager->lQueuedRegistryEvents);
        // Load structure to point to IRP handlers
        DriverObject->DriverUnload                         = UnloadDriver;
        DriverObject->MajorFunction[IRP_MJ_CREATE]         = KDispatchCreateClose;
        DriverObject->MajorFunction[IRP_MJ_CLOSE]          = KDispatchCreateClose;
        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KDispatchIoctl;
    status = CmRegisterCallback(RegistryCallback, pRegistryManager, &pRegistryManager->registryCallbackCookie);
    if(!NT_SUCCESS(status))
    {
      DbgPrint("RegistryMonitor: ERROR CmRegisterCallback - %08x\n", status);
      return status;
    }
    UpdateLastContactTime();
    /* Create a DPC routine so that it can be called periodically */
    KeInitializeDpc(&pRegistryManager->connectionCheckerFunction,
      (PKDEFERRED_ROUTINE) ConnectionChecker, pRegistryManager);
    KeInitializeTimer(&pRegistryManager->connectionCheckerTimer);
    registryEventsTimeout.QuadPart = 0;
    /* Set the ConnectionChecker routine to be called every so often */
    KeSetTimerEx(&pRegistryManager->connectionCheckerTimer,
      registryEventsTimeout,
      (USERSPACE_CONNECTION_TIMEOUT+(USERSPACE_CONNECTION_TIMEOUT/2))*1000,
      &pRegistryManager->connectionCheckerFunction);
    pRegistryManager->bReady = TRUE;
    DbgPrint("RegistryMonitor: Successfully Loaded\n");
        /* Return success */
        return STATUS_SUCCESS;
    }
    /* Checks to see if the registry monitor has received an IOCTL from a userspace
       program in a while. If it hasn't then all old queued registry events are
       cleared. This is called periodically when the driver is loaded */
    VOID ConnectionChecker(
        IN struct _KDPC  *Dpc,
        IN PVOID  DeferredContext,
        IN PVOID  SystemArgument1,
        IN PVOID  SystemArgument2
        )
    {
    PCAPTURE_REGISTRY_MANAGER pRegistryManager = (PCAPTURE_REGISTRY_MANAGER)DeferredContext;
    if( (GetCurrentTime()-pRegistryManager->lastContactTime) > (USERSPACE_CONNECTION_TIMEOUT+(USERSPACE_CONNECTION_TIMEOUT/2)))
    {
      DbgPrint("RegistryMonitor: WARNING Userspace IOCTL timeout, clearing old queued registry events\n");
      while(!IsListEmpty(&pRegistryManager->lQueuedRegistryEvents))
      {
       PLIST_ENTRY head = ExInterlockedRemoveHeadList(&pRegistryManager->lQueuedRegistryEvents, &pRegistryManager->lQueuedRegistryEventsSpinLock);
       PREGISTRY_EVENT_PACKET pRegistryEventPacket = CONTAINING_RECORD(head, REGISTRY_EVENT_PACKET, Link);
       ExFreePoolWithTag(pRegistryEventPacket->pRegistryEvent, REGISTRY_POOL_TAG);
       ExFreePoolWithTag(pRegistryEventPacket, REGISTRY_POOL_TAG);
      }
    }
    }

    NTSTATUS KDispatchCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
    {
        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information=0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_SUCCESS;
    }
    NTSTATUS HandleIoctlGetRegEvents(IN PDEVICE_OBJECT DeviceObject, PIRP Irp,
           PIO_STACK_LOCATION pIoStackIrp, UINT *pdwDataWritten)
    {
        NTSTATUS status = STATUS_UNSUCCESSFUL;
        PCHAR pOutputBuffer = Irp->UserBuffer;
        UINT dwOutputBufferSize = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;
    PCAPTURE_REGISTRY_MANAGER pRegistryManager;
    /* Get the registry manager from the device extension */
        pRegistryManager = gpDeviceObject->DeviceExtension;
    *pdwDataWritten = 0;
       
    /* Check we are allowed to write into the buffer passed from the user space program */
        if(pOutputBuffer)
        {
            try {
       ProbeForWrite(pOutputBuffer,
        pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength,
        __alignof (REGISTRY_EVENT));
       if(pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(REGISTRY_EVENT))
       {
        PLIST_ENTRY pRegistryListHead;
        PREGISTRY_EVENT_PACKET pRegistryPacket;
        UINT bufferSpace = dwOutputBufferSize;
        UINT bufferSpaceUsed = 0;
       
        /* Fill the buffer passed from userspace with registry events */
        while(!IsListEmpty(&pRegistryManager->lQueuedRegistryEvents) &&
         (bufferSpaceUsed < bufferSpace) &&
         ((bufferSpace-bufferSpaceUsed) >= sizeof(REGISTRY_EVENT)))
        {
         UINT registryEventSize = 0;
         pRegistryListHead = ExInterlockedRemoveHeadList(&pRegistryManager->lQueuedRegistryEvents, &pRegistryManager->lQueuedRegistryEventsSpinLock);
         pRegistryPacket = CONTAINING_RECORD(pRegistryListHead, REGISTRY_EVENT_PACKET, Link);
         
         registryEventSize = sizeof(REGISTRY_EVENT)+pRegistryPacket->pRegistryEvent->registryPathLengthB+pRegistryPacket->pRegistryEvent->dataLengthB;
         if((bufferSpace-bufferSpaceUsed) >= registryEventSize)
         {
          //DbgPrint("Sending-%i: %ls\n",bufferSpaceUsed, pRegistryPacket->pRegistryEvent->registryPath);
          RtlCopyMemory(pOutputBuffer+bufferSpaceUsed, pRegistryPacket->pRegistryEvent, registryEventSize);
          bufferSpaceUsed += registryEventSize;
          ExFreePoolWithTag(pRegistryPacket->pRegistryEvent, REGISTRY_POOL_TAG);
          ExFreePoolWithTag(pRegistryPacket, REGISTRY_POOL_TAG);
         } else {
          ExInterlockedInsertHeadList(&pRegistryManager->lQueuedRegistryEvents, &pRegistryPacket->Link, &pRegistryManager->lQueuedRegistryEventsSpinLock);
          break;
         }
        }
       
        /* Return the amount of space that is occupied with registry events */
        *pdwDataWritten = bufferSpaceUsed;
        status = STATUS_SUCCESS;
       } else {
        *pdwDataWritten = sizeof(REGISTRY_EVENT);
        status = STATUS_BUFFER_TOO_SMALL;
       }
            } except( EXCEPTION_EXECUTE_HANDLER ) {
       status = GetExceptionCode();   
       DbgPrint("RegistryMonitor: EXCEPTION IOCTL_CAPTURE_GET_REGEVENTS - %i\n", status);   
            }
        }
        return status;
    }
    NTSTATUS KDispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
    {
        NTSTATUS status = STATUS_UNSUCCESSFUL;
        PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
    UINT dwDataWritten = 0;
        switch(irpStack->Parameters.DeviceIoControl.IoControlCode)
        {
      case IOCTL_CAPTURE_GET_REGEVENTS:
       UpdateLastContactTime();
       status = HandleIoctlGetRegEvents(DeviceObject, Irp, irpStack, &dwDataWritten);
       break;
            default:
                break;
        }
        Irp->IoStatus.Status = status;
       
        // Set # of bytes to copy back to user-mode...
        if(NT_SUCCESS(status))
            Irp->IoStatus.Information = dwDataWritten;
        else
            Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
    }
    VOID UpdateLastContactTime()
    {
    PCAPTURE_REGISTRY_MANAGER pRegistryManager;
    /* Get the process manager from the device extension */
        pRegistryManager = gpDeviceObject->DeviceExtension;
    pRegistryManager->lastContactTime = GetCurrentTime();
    }
    ULONG GetCurrentTime()
    {
    LARGE_INTEGER currentSystemTime;
    LARGE_INTEGER currentLocalTime;
    ULONG time;
    KeQuerySystemTime(&currentSystemTime);
    ExSystemTimeToLocalTime(&currentSystemTime,&currentLocalTime);
    RtlTimeToSecondsSince1970(&currentLocalTime, &time);
    return time;
    }
    BOOLEAN GetRegistryObjectCompleteName(PUNICODE_STRING pRegistryPath, PUNICODE_STRING pPartialRegistryPath, PVOID pRegistryObject)
    {
    PCAPTURE_REGISTRY_MANAGER pRegistryManager;
    BOOLEAN foundCompleteName = FALSE;
    BOOLEAN partial = FALSE;
    /* Get the process manager from the device extension */
        pRegistryManager = gpDeviceObject->DeviceExtension;
    /* Check to see if everything is valid */
    /* We sometimes see a partial registry object name which is actually complete
        however if fails one of these checks for some reason. Not sure whether to report
        this registry event */
    if((!MmIsAddressValid(pRegistryObject)) ||
      (pRegistryObject == NULL))
    {
      return FALSE;
    }
    /* Check to see if the partial name is really the complete name */
    if(pPartialRegistryPath != NULL)
    {
      if( (((pPartialRegistryPath->Buffer[0] == '\\') || (pPartialRegistryPath->Buffer[0] == '%')) ||
       ((pPartialRegistryPath->Buffer[0] == 'T') && (pPartialRegistryPath->Buffer[1] == 'R') && (pPartialRegistryPath->Buffer[2] == 'Y') && (pPartialRegistryPath->Buffer[3] == '\\'))) )
      {
       RtlUnicodeStringCopy(pRegistryPath, pPartialRegistryPath);
       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(pRegistryObject, (POBJECT_NAME_INFORMATION)pObjectName, 0, &returnedLength );
      if(status == STATUS_INFO_LENGTH_MISMATCH)
      {
       pObjectName = ExAllocatePoolWithTag(NonPagedPool, returnedLength, REGISTRY_POOL_TAG);
       status = ObQueryNameString(pRegistryObject, (POBJECT_NAME_INFORMATION)pObjectName, returnedLength, &returnedLength );
       if(NT_SUCCESS(status))
       {
        RtlUnicodeStringCopy(pRegistryPath, pObjectName);
        foundCompleteName = TRUE;
       }
       ExFreePoolWithTag(pObjectName, REGISTRY_POOL_TAG);
      }
    }
    //ASSERT(foundCompleteName == TRUE);
    return foundCompleteName;
    }
    BOOLEAN QueueRegistryEvent(PREGISTRY_EVENT pRegistryEvent)
    {
    PCAPTURE_REGISTRY_MANAGER pRegistryManager;
        /* Get the registry manager from the device extension */
        pRegistryManager = gpDeviceObject->DeviceExtension;
    /* Check the last contact time of the user space program before queuing */
    if( (GetCurrentTime()-pRegistryManager->lastContactTime) <= USERSPACE_CONNECTION_TIMEOUT)
    {
      PREGISTRY_EVENT_PACKET pRegistryEventPacket = ExAllocatePoolWithTag(NonPagedPool, sizeof(REGISTRY_EVENT_PACKET), REGISTRY_POOL_TAG);
      pRegistryEventPacket->pRegistryEvent = pRegistryEvent;
      
      /* Queue registry event */
      ExInterlockedInsertTailList(&pRegistryManager->lQueuedRegistryEvents, &pRegistryEventPacket->Link, &pRegistryManager->lQueuedRegistryEventsSpinLock);
      return TRUE;
    }
    return FALSE;
    }
    NTSTATUS RegistryCallback(IN PVOID CallbackContext,
            IN PVOID  Argument1,
            IN PVOID  Argument2)
    {
    //REGISTRY_EVENT registryEvent;
    BOOLEAN registryEventIsValid = FALSE;
    BOOLEAN exception = FALSE;
    LARGE_INTEGER CurrentSystemTime;
    LARGE_INTEGER CurrentLocalTime;
    TIME_FIELDS TimeFields;
    int type;
    UNICODE_STRING registryPath;
    UCHAR* registryData = NULL;
    ULONG registryDataLength = 0;
    ULONG registryDataType = 0;
    /* Allocate a large 64kb string ... maximum path name allowed in windows */
    registryPath.Length = 0;
    registryPath.MaximumLength = NTSTRSAFE_UNICODE_STRING_MAX_CCH * sizeof(WCHAR);
    registryPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, registryPath.MaximumLength, REGISTRY_POOL_TAG);
    if(registryPath.Buffer == NULL)
    {
      return STATUS_SUCCESS;
    }
    /* Put the time this event occured into the registry event */
    KeQuerySystemTime(&CurrentSystemTime);
    ExSystemTimeToLocalTime(&CurrentSystemTime,&CurrentLocalTime);

    //registryEvent.processId = PsGetCurrentProcessId();
    //registryEvent.eventType = (REG_NOTIFY_CLASS)Argument1;
    type = (REG_NOTIFY_CLASS)Argument1;
    try
    {
      /* Large switch statement for all registry events ... fairly easy to understand */
      switch(type)
      {
      case RegNtPostCreateKey:
      {
       PREG_POST_CREATE_KEY_INFORMATION createKey = (PREG_POST_CREATE_KEY_INFORMATION)Argument2;
       if(NT_SUCCESS(createKey->Status))
       {
        PVOID* registryObject = createKey->Object;
        registryEventIsValid = GetRegistryObjectCompleteName(&registryPath, createKey->CompleteName, *registryObject);
       }
       break;
      }
      case RegNtPostOpenKey:
      {
       PREG_POST_OPEN_KEY_INFORMATION openKey = (PREG_POST_OPEN_KEY_INFORMATION)Argument2;
       if(NT_SUCCESS(openKey->Status))
       {
        PVOID* registryObject = openKey->Object;
        registryEventIsValid = GetRegistryObjectCompleteName(&registryPath, openKey->CompleteName, *registryObject);
       }
       break;
      }
      case RegNtPreDeleteKey:
      {
       PREG_DELETE_KEY_INFORMATION deleteKey = (PREG_DELETE_KEY_INFORMATION)Argument2;
       registryEventIsValid = GetRegistryObjectCompleteName(&registryPath, NULL, deleteKey->Object);
       break;
      }
      case RegNtDeleteValueKey:
      {
       PREG_DELETE_VALUE_KEY_INFORMATION deleteValueKey = (PREG_DELETE_VALUE_KEY_INFORMATION)Argument2;
       registryEventIsValid = GetRegistryObjectCompleteName(&registryPath, NULL, deleteValueKey->Object);
       if((registryEventIsValid) && (deleteValueKey->ValueName->Length > 0))
       {
        RtlUnicodeStringCatString(&registryPath,L"\\");
        RtlUnicodeStringCat(&registryPath, deleteValueKey->ValueName);
       }
       break;
      }
      case RegNtPreSetValueKey:
      {
       PREG_SET_VALUE_KEY_INFORMATION setValueKey = (PREG_SET_VALUE_KEY_INFORMATION)Argument2;
       registryEventIsValid = GetRegistryObjectCompleteName(&registryPath, NULL, setValueKey->Object);
       if((registryEventIsValid) && (setValueKey->ValueName->Length > 0))
       {
        registryDataType = setValueKey->Type;
        registryDataLength = setValueKey->DataSize;
        registryData = ExAllocatePoolWithTag(NonPagedPool, registryDataLength, REGISTRY_POOL_TAG);
        if(registryData != NULL)
        {
         RtlCopyBytes(registryData,setValueKey->Data,setValueKey->DataSize);
        } else {
         DbgPrint("RegistryMonitor: ERROR can't allocate memory for setvalue data\n");
        }
        RtlUnicodeStringCatString(&registryPath,L"\\");
        RtlUnicodeStringCat(&registryPath, setValueKey->ValueName);
       }
       break;
      }
      case RegNtEnumerateKey:
      {
       PREG_ENUMERATE_KEY_INFORMATION enumerateKey = (PREG_ENUMERATE_KEY_INFORMATION)Argument2;
       registryDataType = enumerateKey->KeyInformationClass;
       registryEventIsValid = GetRegistryObjectCompleteName(&registryPath, NULL, enumerateKey->Object);
       break;
      }
      case RegNtEnumerateValueKey:
      {
       PREG_ENUMERATE_VALUE_KEY_INFORMATION enumerateValueKey = (PREG_ENUMERATE_VALUE_KEY_INFORMATION)Argument2;
       registryDataType = enumerateValueKey->KeyValueInformationClass;
       registryEventIsValid = GetRegistryObjectCompleteName(&registryPath, NULL, enumerateValueKey->Object);
       break;
      }
      case RegNtQueryKey:
      {
       PREG_QUERY_KEY_INFORMATION queryKey = (PREG_QUERY_KEY_INFORMATION)Argument2;
       registryDataType = queryKey->KeyInformationClass;
       registryEventIsValid = GetRegistryObjectCompleteName(&registryPath, NULL, queryKey->Object);
       break;
      }
      case RegNtQueryValueKey:
      {
       PREG_QUERY_VALUE_KEY_INFORMATION queryValueKey = (PREG_QUERY_VALUE_KEY_INFORMATION)Argument2;
       registryEventIsValid = GetRegistryObjectCompleteName(&registryPath, NULL, queryValueKey->Object);
       if((registryEventIsValid) && (queryValueKey->ValueName->Length > 0))
       {
        registryDataType = queryValueKey->KeyValueInformationClass;
        RtlUnicodeStringCatString(&registryPath,L"\\");
        RtlUnicodeStringCat(&registryPath, queryValueKey->ValueName);
       }
       break;
      }
      case RegNtKeyHandleClose:
      {
       PREG_KEY_HANDLE_CLOSE_INFORMATION closeKey = (PREG_KEY_HANDLE_CLOSE_INFORMATION)Argument2;
       registryEventIsValid = GetRegistryObjectCompleteName(&registryPath, NULL, closeKey->Object);
       break;
      }
      default:
       break;
      }
    } except( EXCEPTION_EXECUTE_HANDLER ) {
      /* Do nothing if an exception occured ... event won't be queued */
      registryEventIsValid = FALSE;
      exception = TRUE;
    }
    if(registryEventIsValid)
    {
      PREGISTRY_EVENT pRegistryEvent;
      UINT eventSize = sizeof(REGISTRY_EVENT)+registryPath.Length+(sizeof(WCHAR))+registryDataLength;
      pRegistryEvent = ExAllocatePoolWithTag(NonPagedPool, eventSize, REGISTRY_POOL_TAG);
      
      if(pRegistryEvent != NULL)
      {
       pRegistryEvent->registryPathLengthB = registryPath.Length+sizeof(WCHAR);
       pRegistryEvent->dataType = registryDataType;
       pRegistryEvent->dataLengthB = registryDataLength;
       //RtlStringCbCopyUnicodeString(pRegistryEvent->registryPath, pRegistryEvent->registryPathLength, &registryPath);
       RtlCopyBytes(pRegistryEvent->registryData, registryPath.Buffer, registryPath.Length);
       pRegistryEvent->registryData[registryPath.Length] = '\0';
       pRegistryEvent->registryData[registryPath.Length+1] = '\0';
       RtlCopyBytes(pRegistryEvent->registryData+pRegistryEvent->registryPathLengthB, registryData, registryDataLength);
       if(registryData != NULL)
       {
        ExFreePoolWithTag(registryData, 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(registryPath.Buffer != NULL)
    {
      ExFreePoolWithTag(registryPath.Buffer, REGISTRY_POOL_TAG);
    }
    /* Always return a success ... we aren't doing any filtering, just monitoring */
    return STATUS_SUCCESS;
    }
    void UnloadDriver(IN PDRIVER_OBJECT DriverObject)
    {
        UNICODE_STRING  uszDeviceString;
    NTSTATUS        ntStatus;
    PCAPTURE_REGISTRY_MANAGER pRegistryManager;
        /* Get the registry manager from the device extension */
        pRegistryManager = gpDeviceObject->DeviceExtension;

    if(pRegistryManager->bReady == TRUE)
    {
      KeCancelTimer(&pRegistryManager->connectionCheckerTimer);
      CmUnRegisterCallback(pRegistryManager->registryCallbackCookie);
      pRegistryManager->bReady = FALSE;
    }
    while(!IsListEmpty(&pRegistryManager->lQueuedRegistryEvents))
    {
      PLIST_ENTRY head = ExInterlockedRemoveHeadList(&pRegistryManager->lQueuedRegistryEvents, &pRegistryManager->lQueuedRegistryEventsSpinLock);
      PREGISTRY_EVENT_PACKET pRegistryEventPacket = CONTAINING_RECORD(head, REGISTRY_EVENT_PACKET, Link);
      ExFreePoolWithTag(pRegistryEventPacket->pRegistryEvent, REGISTRY_POOL_TAG);
      ExFreePoolWithTag(pRegistryEventPacket, REGISTRY_POOL_TAG);
    }
    RtlInitUnicodeString(&uszDeviceString, L"[url=file://\\DosDevices\\RegistryMonitor]\\DosDevices\\RegistryMonitor[/url]");
        IoDeleteSymbolicLink(&uszDeviceString);
        if(DriverObject->DeviceObject != NULL)
    {
      IoDeleteDevice(DriverObject->DeviceObject);
    }
    }
  • 相关阅读:
    学习笔记——SQL SERVER2014内存数据库
    学习笔记——WCF
    线程
    文件内容操作类-RandomAccessFile
    文件操作类-file-创建文件夹
    同步方法解决同步问题
    同步代码块
    停止线程
    使用泛型来优化坐标类
    数据操作流-DataOutputStream
  • 原文地址:https://www.cnblogs.com/Safe3/p/1439730.html
Copyright © 2020-2023  润新知