#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;
}