雨过天晴 发表于 2017-6-1 13:32:38

注册表回调整体框架

注册表回调整体框架
这个就不多说了,想详细了解的可以自行百度,网上有很多相关内容
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
        NTSTATUS ntStatus;
        ntStatus = CmRegisterCallback(MyRegistryCallback, NULL,&pCookie);
       
        return ntStatus;
}
//see demo:
//7eightl-minifilter\Demo\REG-hips






NTSTATUS HOOK_PreNtDeleteKey(PREG_DELETE_KEY_INFORMATION Data)
{
        NTSTATUS status = 0;
        PUNICODE_STRING keyName;
        UNICODE_STRING uTarget;




        return STATUS_SUCCESS;
}


NTSTATUS MyRegistryCallback( __in PVOID CallbackContext, __in_opt PVOID Argument1,            / / REG_NOTIFY_CLASS __in_opt PVOID Argument2            //KEY_INFORMATION ) {
            switch( (REG_NOTIFY_CLASS) Argument1)
{
         case RegNtPreDeleteKey :
return HOOK_PreNtDeleteKey((PREG_DELETE_KEY_INFORMATION) Argument2);
          case RegNtPreRenameKey:
return HOOK_PreNtRenameKey((PREG_RENAME_KEY_INFORMATION) Argument2);
          case RegNtPreCreateKeyEx:       // pre 操作
return HOOK_PreNtCreateKeyEx((PREG_CREATE_KEY_INFORMATION) Argument2);
          case RegNtPostCreateKeyEx :    // post 操作
return HOOK_PostNtCreateKeyEx((PRGG_POST_OPERATION_INFORMATION )}
   }      
}                                                                                                                                  }




main.c
#include "precomp.h"


#define                DEVICE_NAME                                        L"\\device\\HipsRegDrv"
#define                LINK_NAME                                        L"\\dosDevices\\HipsRegDrv"




// function to dispatch the IRPs
NTSTATUS DispatchOK(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
   Irp->IoStatus.Status = STATUS_SUCCESS;
   IoCompleteRequest(Irp,IO_NO_INCREMENT);
   return STATUS_SUCCESS;
}


VOID DriverUnload (
    IN PDRIVER_OBJECT        pDriverObject)
{
        UNICODE_STRING strLink;
        RtlInitUnicodeString(&strLink, LINK_NAME);
        stopRegMon();


        IoDeleteSymbolicLink(&strLink);
        IoDeleteDevice(pDriverObject->DeviceObject);


        DbgPrint(" Unloaded\n");
}




NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
{
    UNICODE_STRING         DeviceName;
    UNICODE_STRING         LinkName;
    NTSTATUS                 status;
    PDEVICE_OBJECT         pDriverDeviceObject;
        ULONG i;
   
    //DbgPrint("Driver loaded.");
    pDriverObject->DriverUnload = DriverUnload;   
   
    // init strings
    RtlInitUnicodeString(&DeviceName, DEVICE_NAME);
    RtlInitUnicodeString(&LinkName, LINK_NAME);
   
    // to communicate with usermode, we need a device
    status = IoCreateDevice(
         pDriverObject,      // ptr to caller object
         0,// extension device allocated byte number
         &DeviceName,         // device name
         FILE_DEVICE_UNKNOWN,
         0,                   // no special caracteristics
         FALSE,               // we can open many handles in same time
         &pDriverDeviceObject); // ptr to the created object
         
    if ( !NT_SUCCESS(status) )
       return STATUS_NO_SUCH_DEVICE;
   
        pDriverDeviceObject-> Flags |= DO_BUFFERED_IO;


    // we also need a symbolic link
    status = IoCreateSymbolicLink(&LinkName,&DeviceName);
    if( !NT_SUCCESS(status) )
    {
                IoDeleteDevice( pDriverDeviceObject );
      return STATUS_NO_SUCH_DEVICE;
    }


    for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
                pDriverObject->MajorFunction = DispatchOK;
   


    startRegMon(pDriverObject);
    //Do other things...   
   
    return STATUS_SUCCESS;
}


precomp.h
#ifndef _PRECOMP_H_
#define _PRECOMP_H_
#include <ntifs.h>
#include <ntddk.h>
#include <windef.h>
#include "regmon.h"
#endif


regmon.c
#include "precomp.h"


GENERIC_MAPPING g_KeyMapping = {KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS};
static WCHAR g_wszAltitude[] = L"370020";


PGENERIC_MAPPING IoGetKeyGenericMapping( )
{
        return &g_KeyMapping;
}


BOOL MyObQueryObjectName(HANDLE hObjHandle, PUNICODE_STRING ustrObjectName, BOOL bNeedAllocateName)
{
        PVOID                        pQueryBuffer                = NULL;
        DWORD                        dwReqSize                        = 0;
        NTSTATUS                ntStatus                        = 0;
        __try
        {
                dwReqSize = sizeof(OBJECT_NAME_INFORMATION) + (MAX_PATH + 32)*sizeof(WCHAR);
               
                pQueryBuffer = ExAllocatePoolWithTag(PagedPool, dwReqSize, 'RFLM');
               
                if(pQueryBuffer == NULL)
                        return FALSE;
               
                ntStatus = ZwQueryObject(hObjHandle,
                        ObjectNameInfo,
                        pQueryBuffer,
                        dwReqSize,
                        &dwReqSize);
               
                if((ntStatus == STATUS_INFO_LENGTH_MISMATCH) ||
                        (ntStatus == STATUS_BUFFER_OVERFLOW) ||
                        (ntStatus == STATUS_BUFFER_TOO_SMALL))
                {
                        ExFreePool(pQueryBuffer);
                        pQueryBuffer = NULL;
                       
                        pQueryBuffer = ExAllocatePoolWithTag(PagedPool, dwReqSize, 'RFLM');
                       
                        if(pQueryBuffer == NULL)
                        {
                                return FALSE;
                        }
                       
                        ntStatus = ZwQueryObject(hObjHandle,
                                ObjectNameInfo,
                                pQueryBuffer,
                                dwReqSize,
                                &dwReqSize);
                       
                }
               
                if(NT_SUCCESS(ntStatus))
                {
                        OBJECT_NAME_INFORMATION * pNameInfo = (OBJECT_NAME_INFORMATION *)pQueryBuffer;
                       
                        if(bNeedAllocateName)
                        {
                                ustrObjectName->Buffer = ExAllocatePoolWithTag(PagedPool, pNameInfo->Name.Length + sizeof(WCHAR), 'RFLM');
                               
                                if(ustrObjectName->Buffer)
                                {
                                        RtlZeroMemory(ustrObjectName->Buffer, pNameInfo->Name.Length + sizeof(WCHAR));
                                        ustrObjectName->Length = 0;
                                        ustrObjectName->MaximumLength = pNameInfo->Name.Length;
                                        RtlCopyUnicodeString(ustrObjectName, &pNameInfo->Name);
                                }
                                else
                                        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
                               
                        }
                        else
                                RtlCopyUnicodeString(ustrObjectName, &pNameInfo->Name);
                }
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
                ntStatus = GetExceptionCode();
        }
       
        if(pQueryBuffer)
        {
                ExFreePool(pQueryBuffer);
                pQueryBuffer = NULL;
        }
       
        return NT_SUCCESS(ntStatus);
}




LARGE_INTEGER g_RegCookie;


#if (NTDDI_VERSION >= NTDDI_VISTA)
NTSTATUS TlGetObjectNameOnVistaAndLater(PVOID Object, PUNICODE_STRING Name)
{
        PUNICODE_STRING                        pKeyName = NULL;
        NTSTATUS                                ntStatus = 0;


        if(Object == NULL || Name == NULL)
                return STATUS_INVALID_PARAMETER;


        ntStatus = CmCallbackGetKeyObjectID(&g_RegCookie,
                                                                          Object,
                                                                          NULL,
                                                                       &pKeyName);


        if(NT_SUCCESS(ntStatus) == FALSE)
        {
                return ntStatus;
        }


        Name->Buffer = ( PWCHAR )ExAllocatePoolWithTag(
                                                        PagedPool,
                                                        pKeyName->Length,
                                                        'RFLM'
                                                        );


        if(Name->Buffer == NULL)
        {
                return STATUS_INSUFFICIENT_RESOURCES;
        }


        RtlZeroMemory(Name->Buffer, pKeyName->Length);


        Name->Length = 0;
        Name->MaximumLength = pKeyName->Length;


        RtlCopyUnicodeString(Name, pKeyName);
        return STATUS_SUCCESS;
}
#endif


NTSTATUS TlGetObjectNameOnXP(PVOID Object, PUNICODE_STRING Name)
{
        UNICODE_STRING                                ustrKeyName                                = {0};
        HANDLE                                                ObjectHandle                        = NULL;
        NTSTATUS                                        ntStatus                                = 0;


        if(Object == NULL || Name == NULL)
                return STATUS_INVALID_PARAMETER;


        ntStatus = ObOpenObjectByPointer(Object,
                                                          OBJ_KERNEL_HANDLE ,
                                                          0,
                                                          0,
                                                          NULL,
                                                          KernelMode,
                                                          &ObjectHandle);


        if(NT_SUCCESS(ntStatus) == FALSE)
        {
                return ntStatus;
        }


        if(MyObQueryObjectName(ObjectHandle, &ustrKeyName, TRUE) == FALSE)
        {
                ZwClose(ObjectHandle);
                return STATUS_INSUFFICIENT_RESOURCES;
        }
       
        ZwClose(ObjectHandle);


        Name->Buffer = ( PWCHAR )ExAllocatePoolWithTag(
                                                        PagedPool,
                                                        ustrKeyName.Length,
                                                        'RFLM'
                                                        );


        if(Name->Buffer == NULL)
        {
                return STATUS_INSUFFICIENT_RESOURCES;
        }


        RtlZeroMemory(Name->Buffer, ustrKeyName.Length);


        Name->Length = 0;
        Name->MaximumLength = ustrKeyName.Length;


        RtlCopyUnicodeString(Name, &ustrKeyName);
        ExFreePool(ustrKeyName.Buffer);


        return STATUS_SUCCESS;
}


NTSTATUS TlGetObjectFullName(PVOID Object, PUNICODE_STRING Name)
{
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
        return TlGetObjectNameOnVistaAndLater(Object, Name);
#else
        return TlGetObjectNameOnXP(Object, Name);
#endif
}




NTSTATUS MyDeleteKey(PREG_DELETE_KEY_INFORMATION Data)
{
        NTSTATUS                        ntStatus                = 0;
        UNICODE_STRING                ustrKeyName                = {0};


        __try
        {


                if((ExGetPreviousMode() == KernelMode))
                {
                        return STATUS_SUCCESS;
                }


                if(NT_SUCCESS(TlGetObjectFullName(Data->Object, &ustrKeyName)) == FALSE)
                {
                        return STATUS_SUCCESS;
                }
                DbgPrint("DeleteKey Key:%wZ\n", &ustrKeyName);


                ExFreePool(ustrKeyName.Buffer);


        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
        }


        return STATUS_SUCCESS;
}


NTSTATUS MySetValueKey(PREG_SET_VALUE_KEY_INFORMATION Data)
{
        NTSTATUS                                ntStatus                                = 0;
        UNICODE_STRING                        ustrKeyName                                = {0};
        UNICODE_STRING                        ustrTarget                                = {0};
        WCHAR                                        wszKeyPath        = {0};


        __try
        {
               
                if((ExGetPreviousMode() == KernelMode))
                {
                        return STATUS_SUCCESS;
                }


                if(NT_SUCCESS(TlGetObjectFullName(Data->Object, &ustrKeyName)) == FALSE)
                {


                        return STATUS_SUCCESS;
                }


                ustrTarget.Buffer = wszKeyPath;
                ustrTarget.MaximumLength = MAX_PATH * sizeof(WCHAR);
               
                RtlCopyUnicodeString(&ustrTarget, &ustrKeyName);




                ExFreePool(ustrKeyName.Buffer);


                if (ustrTarget.Buffer != L'\\' )
                        RtlAppendUnicodeToString(&ustrTarget, L"\\");


                RtlAppendUnicodeStringToString(&ustrTarget, Data->ValueName);
                DbgPrint("SetValueKey Key:%wZ\n", &ustrTarget);


        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {


        }


        return STATUS_SUCCESS;
}


NTSTATUS MyDeleteValueKey(PREG_DELETE_VALUE_KEY_INFORMATION Data)
{
        NTSTATUS                                ntStatus                                = 0;
        UNICODE_STRING                        ustrKeyName                                = {0};
        UNICODE_STRING                        ustrTarget                                = {0};
        WCHAR                                        wszKeyPath        = {0};




        __try
        {


                if((ExGetPreviousMode() == KernelMode))
                {
                        return STATUS_SUCCESS;
                }


                if(NT_SUCCESS(TlGetObjectFullName(Data->Object, &ustrKeyName)) == FALSE)
                {
                        return STATUS_SUCCESS;
                }


                ustrTarget.Buffer = wszKeyPath;
                ustrTarget.MaximumLength = MAX_PATH * sizeof(WCHAR);
               
                RtlCopyUnicodeString(&ustrTarget, &ustrKeyName);


                ExFreePool(ustrKeyName.Buffer);


                if (ustrTarget.Buffer!=L'\\' )
                        RtlAppendUnicodeToString(&ustrTarget, L"\\");


                RtlAppendUnicodeStringToString(&ustrTarget, Data->ValueName);
                DbgPrint("DeleteValueKey Key:%wZ\n", &ustrTarget);


        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {


        }


        return STATUS_SUCCESS;
}


NTSTATUS MyRenameKey(PREG_RENAME_KEY_INFORMATION Data)
{
        NTSTATUS                                ntStatus        = 0;
        UNICODE_STRING                        ustrKeyName = {0};
       
        __try
        {
                if((ExGetPreviousMode() == KernelMode))
                {
                        return STATUS_SUCCESS;
                }


                if(NT_SUCCESS(TlGetObjectFullName(Data->Object, &ustrKeyName)) == FALSE)
                {
                        return STATUS_SUCCESS;
                }


                DbgPrint("RenameKey Key:%wZ\n", &ustrKeyName);


                ExFreePool(ustrKeyName.Buffer);




        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {


        }


        return STATUS_SUCCESS;
}


NTSTATUS MyCreateKey(PREG_PRE_CREATE_KEY_INFORMATION Data)
{
        NTSTATUS                        ntStatus                                = 0;
        UNICODE_STRING                ustrTarget                                = {0};
        WCHAR                                wszKeyName        = {0};


        __try
        {
                if((ExGetPreviousMode() == KernelMode))
                {
                        return STATUS_SUCCESS;
                }
               
                ustrTarget.Buffer = wszKeyName;
                ustrTarget.MaximumLength = MAX_PATH * sizeof(WCHAR);
               
                RtlCopyUnicodeString(&ustrTarget, Data->CompleteName);
                DbgPrint("CreateKey Key:%wZ\n", &ustrTarget);
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
        }


        return STATUS_SUCCESS;
}


NTSTATUS MyCreateKeyEx(PREG_CREATE_KEY_INFORMATION Data)
{
        NTSTATUS                        ntStatus        = 0;
        UNICODE_STRING                ustrKeyName        = {0};
        UNICODE_STRING                ustrTarget        = {0};


        __try
        {
                if((ExGetPreviousMode() == KernelMode))
                {


                        return STATUS_SUCCESS;
                }


                if(NT_SUCCESS(TlGetObjectFullName(Data->RootObject, &ustrKeyName)) == FALSE)
                {


                        return STATUS_SUCCESS;
                }


                ustrTarget.MaximumLength = MAX_PATH * sizeof(WCHAR);
               
                RtlCopyUnicodeString(&ustrTarget, &ustrKeyName);


                ExFreePool(ustrKeyName.Buffer);
               
                if(Data->CompleteName)
                {
                        RtlAppendUnicodeToString(&ustrTarget, L"\\");
                        RtlAppendUnicodeStringToString(&ustrTarget, Data->CompleteName);
                }


                DbgPrint("CreateKeyEx :%wZ\n", ustrTarget);


        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {


        }


        return STATUS_SUCCESS;
}




NTSTATUS MyRegCallback
(
        PVOID CallbackContext,
        PVOID Argument1,
        PVOID Argument2
)
{
        switch( (REG_NOTIFY_CLASS) Argument1)
        {
        case RegNtPreDeleteKey :
                return MyDeleteKey((PREG_DELETE_KEY_INFORMATION) Argument2);
        case RegNtPreSetValueKey:
                return MySetValueKey((PREG_SET_VALUE_KEY_INFORMATION) Argument2);
        case RegNtPreDeleteValueKey:
                return MyDeleteValueKey((PREG_DELETE_VALUE_KEY_INFORMATION) Argument2);
        case RegNtPreRenameKey:
                return MyRenameKey((PREG_RENAME_KEY_INFORMATION) Argument2);
        case RegNtPreCreateKey:
                return MyCreateKey((PREG_PRE_CREATE_KEY_INFORMATION) Argument2);       
        case RegNtPreCreateKeyEx:
                return MyCreateKeyEx((PREG_CREATE_KEY_INFORMATION) Argument2);


        }


        return STATUS_SUCCESS;
}


NTSTATUS startRegMon(PDRIVER_OBJECT driverObject)
{
#if (NTDDI_VERSION >= NTDDI_VISTA)
        UNICODE_STRING uAltitude;


        RtlInitUnicodeString(&uAltitude, g_wszAltitude);
        return CmRegisterCallbackEx(MyRegCallback,
                                                  &uAltitude,
                                                  driverObject,
                                                  NULL,
                                                  &g_RegCookie,
                                                  NULL);       
#else
        return CmRegisterCallback(MyRegCallback,
                                                          NULL,
                                                       &g_RegCookie);


#endif
                                                  
}


VOID stopRegMon( )
{
        CmUnRegisterCallback(g_RegCookie);
}






regmon.c
#ifndef __REGMON_H__
#define __REGMON_H__


typedef enum _OBJECT_INFO_CLASS {
    ObjectBasicInfo,
                ObjectNameInfo,
                ObjectTypeInfo,
                ObjectAllTypesInfo,
                ObjectProtectionInfo
} OBJECT_INFO_CLASS;




PGENERIC_MAPPING IoGetKeyGenericMapping( );


NTSTATUS
MyRegCallback
(
        PVOID CallbackContext,
        PVOID Argument1,
        PVOID Argument2
);




NTSTATUS startRegMon(PDRIVER_OBJECT driverObject);
VOID stopRegMon( );




#endif








可以参考TA的教程
页: [1]
查看完整版本: 注册表回调整体框架