注册表Key访问重定向

#include <ntifs.h>

DRIVER_INITIALIZE    DriverEntry;
DRIVER_UNLOAD        DriverUnload;
EX_CALLBACK_FUNCTION RegistryCallback;

LARGE_INTEGER  g_CmRegstryCookie;
extern PUSHORT NtBuildNumber;

NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath )
{
    NTSTATUS    Status = STATUS_NOT_SUPPORTED;   

    //KdBreakPoint();

    if ( *NtBuildNumber >= 6000 )
    {
        DriverObject->DriverUnload = DriverUnload;
        Status = CmRegisterCallback( RegistryCallback, DriverObject, &g_CmRegstryCookie ); 
    }    

    return Status;
}

VOID     DriverUnload( PDRIVER_OBJECT  DriverObject )
{
    CmUnRegisterCallback( g_CmRegstryCookie  );
}

PVOID   KmAlloc( SIZE_T PoolSize )
{
    PVOID PoolBase = ExAllocatePoolWithTag( NonPagedPool, PoolSize, 'MmK_');
    if ( PoolBase )
    {
        RtlZeroMemory( PoolBase, PoolSize );
    }
    return PoolBase;
}

VOID    KmFree( PVOID PoolBase )
{
    ExFreePoolWithTag( PoolBase, 'MmK_');
}

NTSTATUS LfGetObjectName( IN CONST PVOID Object, OUT PUNICODE_STRING* ObjectName )
{
    NTSTATUS        Status = STATUS_INSUFFICIENT_RESOURCES;    
    PUNICODE_STRING TmpName;
    ULONG           ReturnLength;
    
    ObQueryNameString( Object, (POBJECT_NAME_INFORMATION)&ReturnLength, sizeof(ULONG), &ReturnLength );    
    *ObjectName = NULL;
    TmpName = (PUNICODE_STRING)KmAlloc( ReturnLength );    
    if ( TmpName )
    {
        Status = ObQueryNameString( Object, (POBJECT_NAME_INFORMATION)TmpName, ReturnLength, &ReturnLength );
        if ( NT_SUCCESS(Status) )
        {
            *ObjectName = TmpName;
        }
        else
        {
            KmFree( TmpName );
        }
    }

    return Status;
}

NTSTATUS RegistryCallback( PVOID CallbackContext, PVOID Argument1, PVOID Argument2 )                          
{
    NTSTATUS         Status      = STATUS_SUCCESS;
    REG_NOTIFY_CLASS NotifyClass = (REG_NOTIFY_CLASS)Argument1;
    
    if( ExGetPreviousMode() == KernelMode )
    {
        return  STATUS_SUCCESS;
    }

    switch ( NotifyClass )
    {
    case RegNtPreCreateKeyEx:
    case RegNtPreOpenKeyEx:
        {
            PREG_CREATE_KEY_INFORMATION KeyInfo = (PREG_CREATE_KEY_INFORMATION)Argument2;            
            UNICODE_STRING              CompKey1Name;
            UNICODE_STRING              CompKey2Name;
            UNICODE_STRING              FullKeyName;
            PUNICODE_STRING             RootKeyName;
            WCHAR*                      Buffer;
            USHORT                      BufLen;
            HANDLE                      KeyHandle;
            ULONG                       Disposition;
            OBJECT_ATTRIBUTES           ObjectAttrib;

            Status = LfGetObjectName( KeyInfo->RootObject, &RootKeyName );
            if ( NT_SUCCESS(Status) )
            {
                BufLen = KeyInfo->CompleteName->Length + sizeof(L"\\RediKey");
                if ( RootKeyName->Length > 10*sizeof(WCHAR) )//sizeof(L"\\REGISTRY\\") : 10*sizeof(WCHAR)
                {
                    BufLen += RootKeyName->Length + sizeof(WCHAR);
                }

                Buffer = KmAlloc( BufLen );
                if ( Buffer )
                {
                    RtlInitEmptyUnicodeString( &FullKeyName, Buffer, BufLen );
                    if ( RootKeyName->Length > 10 )
                    {
                        RtlCopyUnicodeString( &FullKeyName, RootKeyName );
                        RtlAppendUnicodeToString( &FullKeyName, L"\\" );
                    }

                    RtlAppendUnicodeStringToString( &FullKeyName, KeyInfo->CompleteName );
                    
                    RtlInitUnicodeString( &CompKey1Name, L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion" );
                    
                    RtlInitUnicodeString( &CompKey1Name, L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RUN" );
                    RtlInitUnicodeString( &CompKey2Name, L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RUN\\" );
                    
                    if ( _wcsnicmp( FullKeyName.Buffer, CompKey1Name.Buffer, CompKey1Name.Length/sizeof(WCHAR) ) == 0 || 
                         _wcsnicmp( FullKeyName.Buffer, CompKey2Name.Buffer, CompKey2Name.Length/sizeof(WCHAR) ) == 0  )
                    {
                        ULONG StrLen = sizeof(L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion");
                        
                        RtlMoveMemory( FullKeyName.Buffer + (StrLen + sizeof(L"RediKey"))/sizeof(WCHAR), 
                                        FullKeyName.Buffer + StrLen/sizeof(WCHAR), 
                                        FullKeyName.Length - StrLen );
                        
                        RtlMoveMemory( FullKeyName.Buffer + StrLen/sizeof(WCHAR), 
                                        L"RediKey\\",
                                        sizeof(L"RediKey") );
                        
                        FullKeyName.Length += sizeof(L"RediKey");
                        
                        InitializeObjectAttributes( &ObjectAttrib, &FullKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL );
                        
                        if( NotifyClass == RegNtPreCreateKeyEx )
                        {
                            Status = ZwCreateKey( 
                                        &KeyHandle,
                                        KeyInfo->DesiredAccess,
                                        &ObjectAttrib,
                                        0,
                                        KeyInfo->Class,
                                        KeyInfo->CreateOptions,
                                        &Disposition ); 
                        }
                        else
                        {
                            Status = ZwOpenKey( 
                                        &KeyHandle,
                                        KeyInfo->DesiredAccess,
                                        &ObjectAttrib);                                        
                        }
                        
                        if ( NT_SUCCESS(Status) )
                        {
                            PVOID KeyObject;
                            
                            Status = ObReferenceObjectByHandle( 
                                        KeyHandle, 
                                        KeyInfo->DesiredAccess, 
                                        KeyInfo->ObjectType, 
                                        KernelMode, 
                                        &KeyObject, 
                                        NULL );
                            
                            if( NT_SUCCESS(Status) )
                            {                
                                __try
                                {
                                    if( NotifyClass == RegNtPreCreateKeyEx )
                                    {                                    
                                        *KeyInfo->Disposition  = Disposition;
                                    }                                    
                                    
                                    *KeyInfo->ResultObject = KeyObject;
                                    KeyInfo->GrantedAccess = KeyInfo->DesiredAccess;
                                    
                                    Status = STATUS_CALLBACK_BYPASS;
                                }
                                __except( EXCEPTION_EXECUTE_HANDLER )
                                {
                                    ObDereferenceObject( KeyObject );
                                    Status =  GetExceptionCode();
                                }
                            }

                            ZwClose( KeyHandle );
                        }
                    }
                }

                KmFree( RootKeyName );
                KmFree( Buffer );
            }            
        }
        break;
    }

    return Status;
}

 

转载于:https://my.oschina.net/ejoyc/blog/179461

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值