Ejemplo n.º 1
0
VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject)
{
	UNICODE_STRING usSymbolicName;
	RtlInitUnicodeString(&usSymbolicName, L"\\??\\_RegistryMonitor");

	// 删除符号链接和设备对象
	if (NULL != pDriverObject->DeviceObject)
	{
		IoDeleteSymbolicLink(&usSymbolicName);
		IoDeleteDevice(pDriverObject->DeviceObject);
		KdPrint(("Unload driver success.."));
	}

	// 释放链表所有内存
	while (TRUE)
	{
		// 从链表中取出一个节点
		PEVENT_DATA_NODE pNode = (PEVENT_DATA_NODE)ExInterlockedRemoveHeadList(&g_ListHead, &g_Lock);
		if (NULL != pNode)
		{
			if (NULL != pNode->pstRegistryEvent)
			{
				ExFreePoolWithTag(pNode->pstRegistryEvent, MEM_TAG);
			}
			ExFreePoolWithTag(pNode, MEM_TAG);
		}
		else
		{
			break;
		}
	};

	CmUnRegisterCallback(g_Cookie);
	KdPrint(("%wZ Unload.\r\n", pDriverObject->DriverName));
}
Ejemplo n.º 2
0
NTSTATUS  
RegFuncUnregister(void)
{	
	NTSTATUS Status = STATUS_SUCCESS;

	Status = CmUnRegisterCallback( g_MalwFind.lnRegCookie );

	return Status;
}
Ejemplo n.º 3
0
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Description :
//		Driver unload callback. Removes hooks, callbacks, and communication stuff.
//	Parameters :
//	Process :
//		Removes hooks, callbacks, device driver symbolic link / device, and cleans the monitored
//		processes linked list.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID Unload(PDRIVER_OBJECT pDriverObject)
{
	unhook_ssdt_entries();
	
	CmUnRegisterCallback(cookie);
	PsRemoveLoadImageNotifyRoutine(imageCallback);
	
	IoDeleteSymbolicLink(&usDosDeviceName);
	IoDeleteDevice(pDriverObject->DeviceObject);
	
	cleanMonitoredProcessList();	
	cleanHiddenProcessList();
}
Ejemplo n.º 4
0
void SSDTUnload( PDRIVER_OBJECT pDriverObject )
{
	UNICODE_STRING	usDosDeviceName;
	if (Prot)
	    CmUnRegisterCallback(Cookie);
	if (EventKernelSet)
	{
		ObDereferenceObject(EventKernelSet);
		EventKernelSet=NULL;
	}
	if (EventKernelWait)
	{
		ObDereferenceObject(EventKernelWait);
		EventKernelWait=NULL;
	}
	RtlInitUnicodeString( &usDosDeviceName, DEVICE_NAME );
	IoDeleteSymbolicLink( &usDosDeviceName );
	IoDeleteDevice( pDriverObject->DeviceObject );
	FreeLog();
	
	DbgPrint( "SSDT: Unload Success!" );
}
Ejemplo n.º 5
0
BOOLEAN
SetCallContextSample(
    )
/*++

Routine Description:

    This sample shows how a registry callback can associate a context
    with a registry operation during the pre-notification phase so that it
    is available in the post-notification phase. 

Return Value:

    TRUE if the sample completed successfully.

--*/
{
    PCALLBACK_CONTEXT CallbackCtx = NULL;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES KeyAttributes;
    UNICODE_STRING Name;
    HANDLE Key = NULL;
    DWORD ValueData = 0;
    BOOLEAN Success = FALSE;
    

    InfoPrint("");
    InfoPrint("=== Set Operation Context Sample ====");

    //
    // Create the callback context
    //

    CallbackCtx = CreateCallbackContext(CALLBACK_MODE_SET_CALL_CONTEXT,
                                         CALLBACK_ALTITUDE);

    if (CallbackCtx == NULL) {
        goto Exit;
    }
    
    //
    // Register callback with the context
    //

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtx->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtx,
                                  &CallbackCtx->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Success = TRUE;

    //
    // Create a key and set a value.
    //

    RtlInitUnicodeString(&Name, KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwCreateKey(&Key,
                         KEY_ALL_ACCESS,
                         &KeyAttributes,
                         0,
                         NULL,
                         0,
                         NULL);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ZwCreateKey failed. Status 0x%x", Status);
        Success = FALSE;
    }

    RtlInitUnicodeString(&Name, VALUE_NAME);
    Status = ZwSetValueKey(g_RootKey,
                           &Name,
                           0,
                           REG_DWORD,
                           &ValueData,
                           sizeof(ValueData));
    
    if(!NT_SUCCESS(Status)) {
        ErrorPrint("ZwSetValue failed. Status 0x%x", Status);
        Success = FALSE;
    }

    //
    // Unregister the callback
    //

    Status = CmUnRegisterCallback(CallbackCtx->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
        Success = FALSE;
    }


    //
    // Check that the callback records 2 in OperationContextCount.
    // The count should be incremented once in the post-notification for the
    // create key and once for the set value.
    //

    if (CallbackCtx->NotificationWithContextCount != 2) {
        ErrorPrint("Callback OperationWithContextCount expected 2, got %d",
                   CallbackCtx->NotificationWithContextCount);
        Success = FALSE;
    }

  Exit:
    
    if (Success == TRUE) {
        InfoPrint("Set Call Context sample succeeded.");
    } else {
        ErrorPrint("Set Call Context sample FAILED.");
    }

    //
    // Clean up
    //
    
    if (Key != NULL) {
        ZwDeleteKey(Key);
        ZwClose(Key);
    }

    RtlInitUnicodeString(&Name, VALUE_NAME);
    ZwDeleteValueKey(g_RootKey, &Name);

    if (CallbackCtx != NULL) {
        ExFreePoolWithTag(CallbackCtx, REGFLTR_CONTEXT_POOL_TAG);
    }

    return Success;

}
Ejemplo n.º 6
0
BOOLEAN 
SetObjectContextSample(
    )
/*++

Routine Description:

    This sample shows how a registry callback can associate a context on
    a registry object using CmSetCallbackObjectContext. 

    This context is available in the ObjectContext field of the 
    REG_Xxx_KEY_INFORMATION data structures. The registry object is a handle
    to a key and not the registry key itself. When the handle is closed
    or the callback is unregistered, the callback will receive a 
    RegNtCallbackObjectContextCleanup notification to give a chance to 
    clean up the context.

Return Value:

    TRUE if the sample completed successfully.

--*/
{

    PCALLBACK_CONTEXT CallbackCtx = NULL;
    NTSTATUS Status;
    UNICODE_STRING Name;
    OBJECT_ATTRIBUTES KeyAttributes;
    HANDLE RootKeyWithContext = NULL;
    DWORD ValueData = 0;
    BOOLEAN Success = FALSE;


    InfoPrint("");
    InfoPrint("=== Set Object Context Sample ====");

    //
    // Create the callback context
    //

    CallbackCtx = CreateCallbackContext(CALLBACK_MODE_SET_OBJECT_CONTEXT,
                                         CALLBACK_ALTITUDE);

    if (CallbackCtx == NULL) {
        goto Exit;
    }

    //
    // Register the callback
    //

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtx->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtx,
                                  &CallbackCtx->Cookie, 
                                  NULL);
    
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Success = TRUE;
    
    //
    // Open the root key again. The callback will associate an object
    // context with the RootKeyWithContext handle.
    //

    RtlInitUnicodeString(&Name, ROOT_KEY_ABS_PATH);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);
    
    Status = ZwOpenKey(&RootKeyWithContext,
                       KEY_ALL_ACCESS,
                       &KeyAttributes);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ZwOpenKey on root key failed. Status 0x%x", Status);
        Success = FALSE;
    }

    //
    // Set value using both the g_RootKey handle and the RootKeyWithContext
    // handle.
    //

    RtlInitUnicodeString(&Name, VALUE_NAME);
    Status = ZwSetValueKey(g_RootKey,
                           &Name,
                           0,
                           REG_DWORD,
                           &ValueData,
                           sizeof(ValueData));
    
    if(!NT_SUCCESS(Status)) {
        ErrorPrint("ZwSetValue failed. Status 0x%x", Status);
        Success = FALSE;
    }

    if (RootKeyWithContext != NULL) {
        Status = ZwSetValueKey(RootKeyWithContext,
                               &Name,
                               0,
                               REG_DWORD,
                               &ValueData,
                               sizeof(ValueData));
        
        if(!NT_SUCCESS(Status)) {
            ErrorPrint("ZwSetValue failed. Status 0x%x", Status);
            Success = FALSE;
        }
    }

    //
    // Unregister the callback
    //

    Status = CmUnRegisterCallback(CallbackCtx->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
    }

    //
    // Check that the RegNtCallbackObjectContextCleanup notification was
    // received when we unregistered the callback.
    //

    if (CallbackCtx->ContextCleanupCount != 1) {
        ErrorPrint("Callback was not invoked for a context cleanup notification.");
        Success = FALSE;
    } 

    //
    // Check that there were two notifications that had the object context set.
    // These are the pre and post set value using the RootKeyWithContext handle.
    //
    
    if (CallbackCtx->NotificationWithContextCount != 2) {
        ErrorPrint("Callback OperationWithContext count expected 2, instead it was %d",
                   CallbackCtx->NotificationWithContextCount);
        Success = FALSE;
    } 

    //
    // Check that there were two notifications that did not have the object 
    // context set. These are the pre and post set value using the 
    // g_RootKey handle.
    //
    
    if (CallbackCtx->NotificationWithNoContextCount != 2) {
        ErrorPrint("Callback OperationWithNoContext count expected 2, instead it was %d",
                   CallbackCtx->NotificationWithNoContextCount);
        Success = FALSE;
    } 

  Exit:
    
    if (Success == TRUE) {
        InfoPrint("Set Object Context Sample Succeeded.");
    } else {
        ErrorPrint("Set Object Context Sample FAILED.");
    }

    //
    // Clean up
    //
    
    RtlInitUnicodeString(&Name, VALUE_NAME);
    ZwDeleteValueKey(g_RootKey, &Name);
    
    if (RootKeyWithContext != NULL) {
        ZwClose(RootKeyWithContext);
    }

    if (CallbackCtx != NULL) {
        ExFreePoolWithTag(CallbackCtx, REGFLTR_CONTEXT_POOL_TAG);
    }

    return Success;
}
Ejemplo n.º 7
0
NTSTATUS RemoveCallbackNotify(PVOID InBuffer)
{	
	NTSTATUS Status = STATUS_SUCCESS;
	PREMOVE_CALLBACK Temp = (PREMOVE_CALLBACK)InBuffer;

	ULONG_PTR CallbackAddress  = Temp->CallbackAddress;
	CALLBACK_TYPE CallBackType = Temp->NotifyType;

	if (!CallbackAddress ||
		!MmIsAddressValid((PVOID)CallbackAddress))
	{
		return STATUS_UNSUCCESSFUL;
	}

	DbgPrint("CallBackType: %d\r\n",CallBackType);
	switch(CallBackType)
	{
	case NotifyLoadImage:
		{
			DbgPrint("Remove NotifyLoadImage\r\n");
			Status = PsRemoveLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)CallbackAddress);
			break;
		}
	case NotifyCmCallBack:
		{
			LARGE_INTEGER Cookie;
			ULONG_PTR Note = Temp->Note;
			Cookie.QuadPart = 0;

			DbgPrint("Remove NotifyCmCallBack\r\n");

			if (WinVersion == WINDOWS_XP)
			{
				Cookie = XpGetRegisterCallbackCookie(Note);
			}

			if (WinVersion==WINDOWS_7)
			{
				Cookie.QuadPart = Note;
			}

			if (Cookie.LowPart == 0 && Cookie.HighPart == 0)
			{
				return STATUS_UNSUCCESSFUL;
			}

			Status = CmUnRegisterCallback(Cookie);

			break;
		}
	case NotifyKeBugCheckReason:
		{
			PREMOVE_CALLBACK Temp = (PREMOVE_CALLBACK)InBuffer;

			ULONG_PTR Note = Temp->Note;


			if (Note!=NULL&&MmIsAddressValid((PVOID)Note))
			{
				KeDeregisterBugCheckReasonCallback((PKBUGCHECK_REASON_CALLBACK_RECORD)Note);
			}

			break;
		}
	case NotifyShutdown:
		{
			LARGE_INTEGER Cookie;

			PREMOVE_CALLBACK Temp = (PREMOVE_CALLBACK)InBuffer;

			ULONG_PTR Note = Temp->Note;


			if (Note!=NULL&&MmIsAddressValid((PVOID)Note))
			{
				IoUnregisterShutdownNotification((PDEVICE_OBJECT)Note);
			}

			break;
		}
	case NotifyCreateThread:
		{
			NTSTATUS Status = STATUS_SUCCESS;
			PREMOVE_CALLBACK Temp = (PREMOVE_CALLBACK)InBuffer;

			ULONG_PTR CallbackAddress = Temp->CallbackAddress;

			if (!CallbackAddress ||
				!MmIsAddressValid((PVOID)CallbackAddress)||!PsRemoveCreateThreadNotifyRoutine)
			{
				return STATUS_UNSUCCESSFUL;
			}

			Status = PsRemoveCreateThreadNotifyRoutine((PCREATE_THREAD_NOTIFY_ROUTINE)CallbackAddress);

			break;
		}
	default:
		{
			Status = STATUS_UNSUCCESSFUL;
		}
	}

	return Status;
}
Ejemplo n.º 8
0
NTSTATUS
UnRegisterCallback(
    _In_ PDEVICE_OBJECT DeviceObject,
    _In_ PIRP Irp
    ) 
/*++

Routine Description:

    Unregisters a callback with the specified cookie and clean up the
    callback context.

Arguments:

    DeviceObject - The device object receiving the request.

    Irp - The request packet.

Return Value:

    Status from CmUnRegisterCallback

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;
    PIO_STACK_LOCATION IrpStack;
    ULONG InputBufferLength;
    PUNREGISTER_CALLBACK_INPUT UnRegisterCallbackInput;
    PCALLBACK_CONTEXT CallbackCtx;

    UNREFERENCED_PARAMETER(DeviceObject);

    //
    // Get the input buffer and check its size
    //
    
    IrpStack = IoGetCurrentIrpStackLocation(Irp);

    InputBufferLength  = IrpStack->Parameters.DeviceIoControl.InputBufferLength;

    if (InputBufferLength < sizeof(UNREGISTER_CALLBACK_INPUT)) {
        Status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

    UnRegisterCallbackInput = (PUNREGISTER_CALLBACK_INPUT) Irp->AssociatedIrp.SystemBuffer;
    
    //
    // Unregister the callback with the cookie
    //

    Status = CmUnRegisterCallback(UnRegisterCallbackInput->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    //
    // Free the callback context buffer
    //
    CallbackCtx = FindAndRemoveCallbackContext(UnRegisterCallbackInput->Cookie);
    if (CallbackCtx != NULL) {
        DeleteCallbackContext(CallbackCtx);
    }

  Exit:

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("UnRegisterCallback failed. Status 0x%x", Status);
    } else {
        InfoPrint("UnRegisterCallback succeeded");
    }
    InfoPrint("");

    return Status;

}
Ejemplo n.º 9
0
NTSTATUS SSDTDeviceIoCtl( PDEVICE_OBJECT pDeviceObject, PIRP Irp )
{
//	ULONG pbuf;
	PLOG_BUF    old;
	NTSTATUS s;
	PIO_STACK_LOCATION IrpStack;
	PVOID InputBuffer;
	PVOID OutputBuffer;
	ULONG InputBufferLength;
	ULONG OutputBufferLength;
	ULONG IoControlCode;
		
	s = Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	
	IrpStack = IoGetCurrentIrpStackLocation( Irp );
	
	InputBuffer = IrpStack->Parameters.DeviceIoControl.Type3InputBuffer;
	InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
	OutputBuffer = Irp->UserBuffer;
	OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
	IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
	
	///////////////////////////////////////////////
	//这里处理分发例程
	switch( IoControlCode )
	{
	case IOCTL_REG_PROTECTION://开启注册表保护
		CmRegisterCallback(RegistryCallback,
			NULL,
			&Cookie
		);
		Prot=TRUE;
		break;
	case IOCTL_STOP_PROTECTION://停止注册表保护
        CmUnRegisterCallback(Cookie);
		Prot=FALSE;
		break;
	case IOCTL_SAVE_EVENT://把事件传到驱动
		{
			EVENT_INFORMATION EvntInfo;
			__try
			{   
				ProbeForRead( InputBuffer, sizeof(EvntInfo), sizeof( ULONG ) );
				memcpy(&EvntInfo,InputBuffer,8);
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{
				;
			}
			if (!NT_SUCCESS(ObReferenceObjectByHandle(EvntInfo.hKernelSetEvent,0,*ExEventObjectType,UserMode,&EventKernelSet,NULL)))
			{
				EventKernelSet=NULL;
			}
			if (!NT_SUCCESS(ObReferenceObjectByHandle(EvntInfo.hKernelWaitEvent,0,*ExEventObjectType,UserMode,&EventKernelWait,NULL)))
			{
				EventKernelWait=NULL;
			}
			DbgPrint("[Kernel_Driver] EventKernelSet = 0x%X, EventKernelWait=0x%X.\n",EventKernelSet,EventKernelWait);
			s = STATUS_SUCCESS;
			break;
		}
	case IOCTL_REGISTRY_INFO://获得注册表信息
		{
			DbgPrint("[Kernel_Driver] IOCTL_GET_CREATE_PROC_INFO.\n");
			__try
			{
				REGISTRY_INFORMATION RegInfo={0};
				memcpy(RegInfo.ProcessName,aProcessName,256);
				memcpy(RegInfo.KeyPath,astr.Buffer,256);
				DbgPrint("%s %s.\n",RegInfo.ProcessName,RegInfo.KeyPath);
				ProbeForWrite( OutputBuffer, sizeof(RegInfo), sizeof( ULONG ) );
				RtlCopyMemory(OutputBuffer,&RegInfo,sizeof(RegInfo)); // it's strange.
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{
				DbgPrint("[Kernel_Driver] IOCTL_GET_CREATE_PROC_INFO raised exception.\n");
				;
			}
			break;
		}
	case IOCTL_ALLOW_MODIFY://允许修改
		{
			__try
			{   
				ProbeForRead( InputBuffer, sizeof(CreateAllowed), sizeof( ULONG ) );
				memcpy(&CreateAllowed,InputBuffer,sizeof(CreateAllowed));
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{
				;
			}
			break;
		}
	//*************************************************
	case IOCTL_GETSSDT:	//得到SSDT
		__try
		{
			ProbeForWrite( OutputBuffer, sizeof( MYSSDT ), sizeof( ULONG ) );
			RtlCopyMemory( OutputBuffer, KeServiceDescriptorTable, sizeof( MYSSDT ) );
		}
		__except( EXCEPTION_EXECUTE_HANDLER )
		{
			s = GetExceptionCode();
			break;
		}
		DbgPrint( "SSDT: GetSSDT Completeled!" );
		break;
	case IOCTL_KILL:
		{
			__try
			{
				ProbeForRead( InputBuffer, sizeof( ULONG ), sizeof( ULONG ) );
				memcpy(&processID,InputBuffer,sizeof(processID));
				s=PsLookupProcessByProcessId(processID,&eProcess);
				if(NT_SUCCESS(s))
				{
					ObDereferenceObject(eProcess);
				}
				s=TerminateProcess(eProcess);
				if(NT_SUCCESS(s))
				{
					DbgPrint("TerminateProcess Ok!\n");
				}
			}
			__except( EXCEPTION_EXECUTE_HANDLER )
			{
				s = GetExceptionCode();
				break;
			}
			//	status = STATUS_SUCCESS;
			break;
		}
	case IOCTL_ENUMTCP://枚举TCP连接
		{
			PVOID	pOut=NULL;
			ULONG	OutLen=0; 
			
			if(OutputBufferLength<sizeof(CONNINFO102))
			{
				KdPrint(("输出缓冲区长度无效\n"));
				s=STATUS_BUFFER_OVERFLOW;
				break;
			}
			
			pOut=EnumPortInformation(&OutLen,TCPPORT);
			if(!pOut)
			{
				KdPrint(("获取TCP端口信息失败!\n"));
				s=STATUS_UNSUCCESSFUL;
				break;
			}
			
			if(OutputBufferLength<OutLen)
			{
				KdPrint(("输出缓冲区太小,应为%ld\n",OutLen));
				ExFreePool(pOut);
				s=STATUS_BUFFER_OVERFLOW;
				break;
			} 
			
			RtlCopyMemory(OutputBuffer,pOut,OutLen);
			
			ExFreePool(pOut);
			Irp->IoStatus.Information = OutLen;
			break;
		}
	case IOCTL_ENUMUDP://枚举UDP连接
		{
			PVOID	pOut=NULL;
			ULONG	OutLen=0;  
			
			if(OutputBufferLength<sizeof(UDPCONNINFO))
			{
				KdPrint(("输出缓冲区长度无效\n"));
				s=STATUS_BUFFER_OVERFLOW;
				break;
			}
			
			pOut=EnumPortInformation(&OutLen,UDPPORT);
			if(!pOut)
			{
				KdPrint(("获取UDP端口信息失败!\n"));
				s=STATUS_UNSUCCESSFUL;
				break;
			}
			
			if(OutputBufferLength<OutLen)
			{
				KdPrint(("输出缓冲区太小,应为%ld\n",OutLen));
				ExFreePool(pOut);
				s=STATUS_BUFFER_OVERFLOW;
				break;
			}
			
			RtlCopyMemory(OutputBuffer,pOut,OutLen);
			
			ExFreePool(pOut);
			Irp->IoStatus.Information = OutLen;
            break;
		}
	case IOCTL_QSIADDR:
        EnumProcess();
		__try {                 
			
            ProbeForWrite( OutputBuffer,
				OutputBufferLength,
				sizeof( UCHAR ));
			
        } __except( EXCEPTION_EXECUTE_HANDLER ) {
			
            Irp->IoStatus.Information = STATUS_INVALID_PARAMETER;
            return FALSE;
        }            

		if(MAX_MESSAGE > OutputBufferLength)
		{
			return FALSE;
		}
		else 
			if(Log->Length != 0	||  Log->Next   != NULL)
			{
				//pReturnLog = Log;
				MUTEX_P(LogMutex);
				//	NewLog();
				old=OldestLog();
				if(old!=Log)
				{
					MUTEX_V(LogMutex);
					DbgPrint("Old log\n");
				}
				memcpy(OutputBuffer,old->Message,old->Length);
					Irp->IoStatus.Information = old->Length;
				if(old!=Log)
				{
					ExFreePool(old);
				}
				else
				{
					DbgPrint("Current log\n");
					Log->Length=0;
					MUTEX_V(LogMutex);
				}
			}
			else
			{   
				//	MUTEX_V(LogMutex);
					Irp->IoStatus.Information = 0;
			}
			
			

		DbgPrint("SSDT: Set QuerySystemInformation Address Completed!");
                break;
	case IOCTL_SETSSDT: //设置 SSDT
		__try
		{
			ProbeForRead( InputBuffer, sizeof( MYSSDT ), sizeof( ULONG ) );
			//去掉内存保护
			__asm
			{
				cli		;//关中断
				mov eax, cr0
				and eax, ~0x10000
				mov cr0, eax
			}
			RtlCopyMemory( KeServiceDescriptorTable, InputBuffer, sizeof( MYSSDT ) );
			//开中断,把内存保护加上
			 __asm
			 {
				mov eax, cr0
				or eax, 0x10000
				mov cr0, eax
				sti		;//开中断
			 }
		}
		__except( EXCEPTION_EXECUTE_HANDLER )
		{
			s = GetExceptionCode();
			break;
		}
		DbgPrint( "SSDT: SetSSDT Completeled!" );
		break;
	//*************************************************
	case IOCTL_GETHOOK:	//查询SSDT指定地址
		__try
		{
			ProbeForRead( InputBuffer, sizeof( ULONG ), sizeof( ULONG ) );
			ProbeForWrite( OutputBuffer, sizeof( ULONG ), sizeof( ULONG ) );
		}
		__except( EXCEPTION_EXECUTE_HANDLER )
		{
			s = GetExceptionCode();
			break;
		}
		//测试传入的参数是否正确
		if( KeServiceDescriptorTable->ulNumberOfServices <= *(PULONG)InputBuffer )
		{
			s = STATUS_INVALID_PARAMETER;
			break;
		}
		//将结果传到用户输出位置
		*((PULONG)OutputBuffer) = *( (PULONG)(KeServiceDescriptorTable->pvSSDTBase) + *(PULONG)InputBuffer );
		DbgPrint( "SSDT: GetHookedAddress Completeled!" );
		break;
	//*************************************************
	case IOCTL_SETHOOK:	//设置SSDT指定地址
		__try
		{
			ProbeForRead( InputBuffer, sizeof( ULONG ), sizeof( ULONG ) );
			ProbeForRead( OutputBuffer, sizeof( ULONG ), sizeof( ULONG ) );
		}
		__except( EXCEPTION_EXECUTE_HANDLER )
		{
			s = GetExceptionCode();
			break;
		}
		//测试传入的参数是否正确
		if( KeServiceDescriptorTable->ulNumberOfServices <= *(PULONG)InputBuffer )
		{
			s = STATUS_INVALID_PARAMETER;
			break;
		}
		//在此将输出缓冲区当作输入缓冲区来用,输入指定SSDT HOOK的地址值
		//去掉内存保护
		__asm
		{
			cli		;//关中断
			mov eax, cr0
			and eax, ~0x10000
			mov cr0, eax
		}
		 *( (PULONG)(KeServiceDescriptorTable->pvSSDTBase) + *(PULONG)InputBuffer ) = *((PULONG)OutputBuffer);
		 //开中断,把内存保护加上
		 __asm
		 {
			mov eax, cr0
			or eax, 0x10000
			mov cr0, eax
			sti		;//开中断
		 }
		 DbgPrint( "SSDT: SetHookedAddress Completeled!" );
		break;
	//*************************************************
	default:
		s = STATUS_INVALID_DEVICE_REQUEST;
		DbgPrint( "SSDT: Invalid Parameter Completeled!" );
		break;
	}
	///////////////////////////////////////////////
	
	IoCompleteRequest( Irp, IO_NO_INCREMENT );
	
	return s;
}
Ejemplo n.º 10
0
BOOLEAN 
MultipleAltitudeBlockDuringPreSample(
    )
/*++

Routine Description:

    This sample features a stack of three callbacks at different altitudes and
    demonstrates what happens when middle callback blocks an operation
    in the pre-notification phase. 

Return Value:

    TRUE if the sample completed successfully.

--*/
{

    PCALLBACK_CONTEXT CallbackCtxHigh = NULL;
    PCALLBACK_CONTEXT CallbackCtxMid = NULL;
    PCALLBACK_CONTEXT CallbackCtxLow = NULL;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES KeyAttributes;
    UNICODE_STRING Name;
    HANDLE Key = NULL;
    BOOLEAN Success = FALSE;

    InfoPrint("");
    InfoPrint("=== Multiple Altitude Block During Pre Sample ====");

    //
    // Create callback contexts for the 3 callbacks.
    // The high and low callbacks will only monitor how many notifications
    // they receive.
    //
    
    CallbackCtxHigh = CreateCallbackContext(CALLBACK_MODE_MULTIPLE_ALTITUDE_MONITOR,
                                            CALLBACK_HIGH_ALTITUDE);
    CallbackCtxMid = CreateCallbackContext(CALLBACK_MODE_MULTIPLE_ALTITUDE_BLOCK_DURING_PRE,
                                           CALLBACK_ALTITUDE);
    CallbackCtxLow = CreateCallbackContext(CALLBACK_MODE_MULTIPLE_ALTITUDE_MONITOR,
                                           CALLBACK_LOW_ALTITUDE);

    if ((CallbackCtxHigh == NULL) ||
        (CallbackCtxMid == NULL) ||
        (CallbackCtxLow == NULL)) {
        goto Exit;
    }

    //
    // Register the callbacks
    //

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtxHigh->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtxHigh,
                                  &CallbackCtxHigh->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtxMid->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtxMid,
                                  &CallbackCtxMid->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtxLow->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtxLow,
                                  &CallbackCtxLow->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Success = TRUE;

    //
    // Do a create key operation which will be blocked by the middle
    // callback and fail with STATUS_ACCESS_DENIED
    //
    
    RtlInitUnicodeString(&Name, KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwCreateKey(&Key,
                         KEY_ALL_ACCESS,
                         &KeyAttributes,
                         0,
                         NULL,
                         0,
                         NULL);

    if (Status != STATUS_ACCESS_DENIED) {
        ErrorPrint("ZwCreateKey returned unexpected status 0x%x", Status);
        Success = FALSE;
    }

    
    //
    // Unregister the callbacks
    //

    Status = CmUnRegisterCallback(CallbackCtxHigh->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
    }

    Status = CmUnRegisterCallback(CallbackCtxMid->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
    }

    Status = CmUnRegisterCallback(CallbackCtxLow->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
    }


    //
    // Verify that the highest alitude callback receives a pre and a post 
    // notification. It receives a post notification because it returned 
    // STATUS_SUCCESS in the pre-notification so it is guaranteed to get a 
    // post notification.
    //
    
    if ((CallbackCtxHigh->PreNotificationCount != 1) ||
        (CallbackCtxHigh->PostNotificationCount != 1)) {
        ErrorPrint("High Callback should have seen 1 pre and 1 post notifications.");
        ErrorPrint("High Callback actually saw %d pre and %d post notifications.",
                   CallbackCtxHigh->PreNotificationCount,
                   CallbackCtxHigh->PostNotificationCount);
        Success = FALSE;
    }

    //
    // Verify the middle callback receives only a pre notification.
    // It does not get a post notification because it return a non-success
    // value in the pre-notification phase.
    //
    
    if ((CallbackCtxMid->PreNotificationCount != 1) ||
        (CallbackCtxMid->PostNotificationCount != 0)) {
        ErrorPrint("Mid Callback should have seen 1 pre and 0 post notifications.");
        ErrorPrint("Mid Callback actually saw %d pre and %d post notifications.",
                   CallbackCtxMid->PreNotificationCount,
                   CallbackCtxMid->PostNotificationCount);
        Success = FALSE;
    }

    //
    // Verify the lowest callback receives no notifications.
    // Once the middle callback blocks, no callbacks at lower altitudes are
    // notified.
    //
    
    if ((CallbackCtxLow->PreNotificationCount != 0) ||
        (CallbackCtxLow->PostNotificationCount != 0)) {
        ErrorPrint("Low Callback should have seen 0 pre and 0 post notifications.");
        ErrorPrint("Low Callback actually saw %d pre and %d post notifications.",
                   CallbackCtxLow->PreNotificationCount,
                   CallbackCtxLow->PostNotificationCount);
        Success = FALSE;
    }

  Exit:

    if (Success) {
        InfoPrint("Multiple Altitude Block During Pre Sample succeeded.");
    } else {
        ErrorPrint("Multiple Altitude Block During Pre Sample FAILED.");
    }

    //
    // Clean up
    //

    if (Key != NULL) {
        ZwDeleteKey(Key);
        ZwClose(Key);
    }

    if (CallbackCtxHigh != NULL) {
        ExFreePoolWithTag(CallbackCtxHigh, REGFLTR_CONTEXT_POOL_TAG);
    }

    if (CallbackCtxMid != NULL) {
        ExFreePoolWithTag(CallbackCtxMid, REGFLTR_CONTEXT_POOL_TAG);
    }

    if (CallbackCtxLow != NULL) {
        ExFreePoolWithTag(CallbackCtxLow, REGFLTR_CONTEXT_POOL_TAG);
    }

    return Success;
}
Ejemplo n.º 11
0
BOOLEAN 
MultipleAltitudeInternalInvocationSample(
    )
/*++

Routine Description:

    This sample features a stack of 3 callbacks at different altitudes and
    demonstrates what happens when the middle callback invokes a registry
    operation. 

Return Value:

    TRUE if the sample completed successfully.

--*/
{
    PCALLBACK_CONTEXT CallbackCtxHigh = NULL;
    PCALLBACK_CONTEXT CallbackCtxMid = NULL;
    PCALLBACK_CONTEXT CallbackCtxLow = NULL;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES KeyAttributes;
    UNICODE_STRING Name;
    HANDLE Key = NULL;
    BOOLEAN Success = FALSE;
    

    InfoPrint("");
    InfoPrint("=== Multiple Altitude Internal Invocation Sample ====");

    //
    // Create callback contexts for the 3 callbacks.
    // The high and low callbacks will only monitor how many notifications
    // they receive.
    //
    
    CallbackCtxHigh = CreateCallbackContext(CALLBACK_MODE_MULTIPLE_ALTITUDE_MONITOR,
                                            CALLBACK_HIGH_ALTITUDE);
    CallbackCtxMid = CreateCallbackContext(CALLBACK_MODE_MULTIPLE_ALTITUDE_INTERNAL_INVOCATION,
                                           CALLBACK_ALTITUDE);
    CallbackCtxLow = CreateCallbackContext(CALLBACK_MODE_MULTIPLE_ALTITUDE_MONITOR,
                                           CALLBACK_LOW_ALTITUDE);

    if ((CallbackCtxHigh == NULL) ||
        (CallbackCtxMid == NULL) ||
        (CallbackCtxLow == NULL)) {
        goto Exit;
    }

    //
    // Register the callbacks
    //

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtxHigh->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtxHigh,
                                  &CallbackCtxHigh->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtxMid->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtxMid,
                                  &CallbackCtxMid->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtxLow->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtxLow,
                                  &CallbackCtxLow->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Success = TRUE;

    //
    // Create a key. When the middle callback receives the pre-notification
    // and the post-notification for this create it will perform an open key 
    // and a close key operation.
    //
    
    RtlInitUnicodeString(&Name, KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwCreateKey(&Key,
                         KEY_ALL_ACCESS,
                         &KeyAttributes,
                         0,
                         NULL,
                         0,
                         NULL);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ZwCreateKey returned unexpected status 0x%x", Status);
        Success = FALSE;
    }

    //
    // Unregister the callbacks
    //

    Status = CmUnRegisterCallback(CallbackCtxHigh->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
        Success = FALSE;
    }

    Status = CmUnRegisterCallback(CallbackCtxMid->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
        Success = FALSE;
    }

    Status = CmUnRegisterCallback(CallbackCtxLow->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
        Success = FALSE;
    }


    //
    // Verify the highest altitude callback receives one pre and one post
    // notification. This callback does not get notifications for the 
    // registry operations called by the middle callback.
    //
    
    if ((CallbackCtxHigh->PreNotificationCount != 1) ||
        (CallbackCtxHigh->PostNotificationCount != 1)) {
        ErrorPrint("High Callback should have seen 1 pre and 1 post notifications.");
        ErrorPrint("High Callback actually saw %d pre and %d post notifications.",
                   CallbackCtxHigh->PreNotificationCount,
                   CallbackCtxHigh->PostNotificationCount);
        Success = FALSE;
    }

    //
    // Verify the middle callback receives one pre and one post notification.
    // This callback does not get notifications for the registry operations 
    // that it calls.
    //
    
    if ((CallbackCtxMid->PreNotificationCount != 1) ||
        (CallbackCtxMid->PostNotificationCount != 1)) {
        ErrorPrint("Mid Callback should have seen 1 pre and 1 post notifications.");
        ErrorPrint("Mid Callback actually saw %d pre and %d post notifications.",
                   CallbackCtxMid->PreNotificationCount,
                   CallbackCtxMid->PostNotificationCount);
        Success = FALSE;
    }

    //
    // Verify the lowest callback receives 5 pre-notifications and 5
    // post-notifications. This callback receives 1 pre and 1 post from the 
    // original create key operation. It also receives 2 pre and 2 post for
    // the open key and close key operations called by the middle callback 
    // during the pre phase of the create key and then 2 pre and 2 post again
    // for the calls in the post phase of the create key.
    //
    
    if ((CallbackCtxLow->PreNotificationCount != 5) ||
        (CallbackCtxLow->PostNotificationCount != 5)) {
        ErrorPrint("Low Callback should have seen 5 pre and 5 post notifications.");
        ErrorPrint("Low Callback actually saw %d pre and %d post notifications.",
                   CallbackCtxLow->PreNotificationCount,
                   CallbackCtxLow->PostNotificationCount);
        Success = FALSE;
    }

  Exit:
    
    if (Success) {
        InfoPrint("Multiple Altitude Internal Invocation Sample succeeded.");
    } else {
        ErrorPrint("Multiple Altitude Internal Invocation Sample FAILED.");
    }

    //
    // Clean up
    //

    if (Key != NULL) {
        ZwDeleteKey(Key);
        ZwClose(Key);
    }

    if (CallbackCtxHigh != NULL) {
        ExFreePoolWithTag(CallbackCtxHigh, REGFLTR_CONTEXT_POOL_TAG);
    }

    if (CallbackCtxMid != NULL) {
        ExFreePoolWithTag(CallbackCtxMid, REGFLTR_CONTEXT_POOL_TAG);
    }

    if (CallbackCtxLow != NULL) {
        ExFreePoolWithTag(CallbackCtxLow, REGFLTR_CONTEXT_POOL_TAG);
    }

    return Success;
}
Ejemplo n.º 12
0
BOOLEAN
PreNotificationBypassSample(
    )
/*++

Routine Description:

    This sample shows how to bypass a registry operation so that the CM does
    not process the operation. Unlike block, an operation that is bypassed
    is still considered successful so the callback must provide the caller
    with what the CM would have provided.

    A key and a value are created. However both operations are bypassed by the
    callback so that the key and value actually created have different names
    than would is expected.
    
Return Value:

    TRUE if the sample completed successfully.

--*/
{
    PCALLBACK_CONTEXT CallbackCtx = NULL;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES KeyAttributes;
    UNICODE_STRING Name;
    HANDLE Key = NULL;
    DWORD ValueData = 0; 
    BOOLEAN Success = FALSE;

    InfoPrint("");
    InfoPrint("=== Pre-Notification Bypass Sample ====");

    //
    // Create the callback context
    //

    CallbackCtx = CreateCallbackContext(CALLBACK_MODE_PRE_NOTIFICATION_BYPASS,
                                        CALLBACK_ALTITUDE);
    if (CallbackCtx == NULL) {
        goto Exit;
    }

    //
    // Register the callback
    //

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtx->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtx,
                                  &CallbackCtx->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Success = TRUE;
    
    //
    // Create a key and set a value. Both should succeed
    //

    RtlInitUnicodeString(&Name, KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwCreateKey(&Key,
                         KEY_ALL_ACCESS,
                         &KeyAttributes,
                         0,
                         NULL,
                         0,
                         NULL);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ZwCreateKey failed. Status 0x%x", Status);
        Success = FALSE;
    }

    RtlInitUnicodeString(&Name, VALUE_NAME);
    Status = ZwSetValueKey(g_RootKey,
                           &Name,
                           0,
                           REG_DWORD,
                           &ValueData,
                           sizeof(ValueData));
    
    if(!NT_SUCCESS(Status)) {
        ErrorPrint("ZwSetValue failed. Status 0x%x", Status);
        Success = FALSE;
    }

    //
    // Unregister the callback
    //

    Status = CmUnRegisterCallback(CallbackCtx->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
        Success = FALSE;
    }

    
    //
    // Check that a key with the expected name KEY_NAME cannot be found 
    // but a key with the "modified" name can be found. 
    //

    if (Key != NULL) {
        ZwClose(Key);
    }

    RtlInitUnicodeString(&Name, KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);
    
    Status = ZwOpenKey(&Key,
                       KEY_ALL_ACCESS,
                       &KeyAttributes);

    if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
        ErrorPrint("ZwOpenKey on key returned unexpected status: 0x%x", Status);
        if (Key != NULL) {
            ZwDeleteKey(Key);
            ZwClose(Key);
            Key = NULL;
        }
        Success = FALSE;
    }

    RtlInitUnicodeString(&Name, MODIFIED_KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwOpenKey(&Key,
                       KEY_ALL_ACCESS,
                       &KeyAttributes);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ZwOpenKey on modified key path failed. Status: 0x%x", Status);
        Success = FALSE;
    }
        

    //
    // Do the same check by trying to delete a value with VALUE_NAME and
    // with the "modified" name. 
    //

    RtlInitUnicodeString(&Name, VALUE_NAME);
    Status = ZwDeleteValueKey(g_RootKey, &Name);

    if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
        ErrorPrint("ZwDeleteValueKey on original value returned unexpected status: 0x%x", 
                   Status);
        Success = FALSE;
    }

    RtlInitUnicodeString(&Name, MODIFIED_VALUE_NAME);
    Status = ZwDeleteValueKey(g_RootKey, &Name);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ZwDeleteValueKey on modified value failed. Status: 0x%x", 
                   Status);
        Success = FALSE;
    }

  Exit:

    //
    // Clean up
    //

    if (Key != NULL) {
        ZwDeleteKey(Key);
        ZwClose(Key);
    }

    if (CallbackCtx != NULL) {
        ExFreePoolWithTag(CallbackCtx, REGFLTR_CONTEXT_POOL_TAG);
    }

    if (Success) {
        InfoPrint("Pre-Notification Bypass Sample succeeded.");
    } else {
        ErrorPrint("Pre-Notification Bypass Sample FAILED.");
    }

    return Success;
}
Ejemplo n.º 13
0
BOOLEAN
PreNotificationBlockSample(
    )
/*++

Routine Description:

    This sample shows how to block a registry operation in the
    pre-notification phase. 

    Two keys are created. The create operations should succeed, but one
    is intercepted by the callback and failed with STATUS_ACCESS_DENIED.
    The same is done for two values.

Return Value:

    TRUE if the sample completed successfully.

--*/
{
    PCALLBACK_CONTEXT CallbackCtx = NULL;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES KeyAttributes;
    UNICODE_STRING Name;
    HANDLE Key = NULL;
    HANDLE NotModifiedKey = NULL;
    DWORD ValueData = 0; 
    BOOLEAN Success = FALSE;

    InfoPrint("");
    InfoPrint("=== Pre-Notification Block Sample ====");
    
    //
    // Create the callback context
    //

    CallbackCtx = CreateCallbackContext(CALLBACK_MODE_PRE_NOTIFICATION_BLOCK,
                                        CALLBACK_ALTITUDE);
    if (CallbackCtx == NULL) {
        goto Exit;
    }
    
    //
    // Register callback
    //

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtx->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtx,
                                  &CallbackCtx->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Success = TRUE;
    
    //
    // Create two keys.
    // Creating the "not modified" key will succeed.
    // Creating the other key will fail with STATUS_ACCESS_DENIED
    //

    RtlInitUnicodeString(&Name, NOT_MODIFIED_KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwCreateKey(&NotModifiedKey,
                         KEY_ALL_ACCESS,
                         &KeyAttributes,
                         0,
                         NULL,
                         0,
                         NULL);

    if (Status != STATUS_SUCCESS) {
        ErrorPrint("ZwCreateKey returned unexpected status 0x%x", Status);
        Success = FALSE;
    }

    RtlInitUnicodeString(&Name, KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwCreateKey(&Key,
                         KEY_ALL_ACCESS,
                         &KeyAttributes,
                         0,
                         NULL,
                         0,
                         NULL);

    if (Status != STATUS_ACCESS_DENIED) {
        ErrorPrint("ZwCreateKey returned unexpected status 0x%x", Status);
        Success = FALSE;
    }


    //
    // Set two values. 
    // Setting the "not modified" value will succeed.
    // Setting the other value will fail with STATUS_ACCESS_DENIED.
    //

    RtlInitUnicodeString(&Name, NOT_MODIFIED_VALUE_NAME);
    Status = ZwSetValueKey(g_RootKey,
                           &Name,
                           0,
                           REG_DWORD,
                           &ValueData,
                           sizeof(ValueData));
    
    if(Status != STATUS_SUCCESS) {
        ErrorPrint("ZwSetValue return unexpected status 0x%x", Status);
        Success = FALSE;
    }

    RtlInitUnicodeString(&Name, VALUE_NAME);
    Status = ZwSetValueKey(g_RootKey,
                           &Name,
                           0,
                           REG_DWORD,
                           &ValueData,
                           sizeof(ValueData));
    
    if(Status != STATUS_ACCESS_DENIED) {
        ErrorPrint("ZwSetValue return unexpected status 0x%x", Status);
        Success = FALSE;
    }
    
    //
    // Unregister the callback
    //

    Status = CmUnRegisterCallback(CallbackCtx->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
        Success = FALSE;
    }

  Exit:

    //
    // Clean up
    //

    if (Key != NULL) {
        ZwDeleteKey(Key);
        ZwClose(Key);
    }

    if (NotModifiedKey != NULL) {
        ZwDeleteKey(NotModifiedKey);
        ZwClose(NotModifiedKey);
    }

    RtlInitUnicodeString(&Name, VALUE_NAME);
    ZwDeleteValueKey(g_RootKey, &Name);
    RtlInitUnicodeString(&Name, NOT_MODIFIED_VALUE_NAME);
    ZwDeleteValueKey(g_RootKey, &Name);

    if (CallbackCtx != NULL) {
        ExFreePoolWithTag(CallbackCtx, REGFLTR_CONTEXT_POOL_TAG);
    }

    if (Success) {
        InfoPrint("Pre-Notification Block Sample succeeded.");
    } else {
        ErrorPrint("Pre-Notification Block Sample FAILED.");
    }

    return Success;
    
}
Ejemplo n.º 14
0
extern "C" NTSTATUS DriverEntry (
    IN PDRIVER_OBJECT pDriObj,
    IN PUNICODE_STRING pRegPath
    )
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    PDEVICE_EXTENSION pDevExt;


    pDriObj->DriverUnload = DriverUnloadRoutine;
    pDriObj->MajorFunction[IRP_MJ_CREATE] = OnCreate;
    pDriObj->MajorFunction[IRP_MJ_CLOSE] = OnCreate;
    pDriObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIoControl;

    g_MonitoringOn = FALSE;
    InUse = 0;

    UNICODE_STRING DeviceName;
    UNICODE_STRING SymLinkName;
    RtlInitUnicodeString(&DeviceName, DEVICENAME);
    RtlInitUnicodeString(&SymLinkName, SYMLINKNAME);

    do{
        status = IoCreateDevice(pDriObj, sizeof(DEVICE_EXTENSION),
            &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE,
            &g_DeviceObject);

        if (!NT_SUCCESS(status)) {
            KdPrint(("[RegMon] 设备无法创建(0x%08x)\n", status));
            break;
        }
        g_DeviceObject->Flags |= DO_BUFFERED_IO;
        pDevExt = (PDEVICE_EXTENSION)g_DeviceObject->DeviceExtension;
        pDevExt->pDevObj = g_DeviceObject;
        
        
        status = IoCreateSymbolicLink(&SymLinkName, &DeviceName);
        if (!NT_SUCCESS(status)) {
            KdPrint(("[RegMon] 符号链接无法创建(0x%08x)\n", status));
            IoDeleteDevice(g_DeviceObject);
            break;
        }
        pDevExt->ustrDevSymLinkName = SymLinkName;


        status = CmRegisterCallback(RegistryCallback, pDevExt, &pDevExt->RegCallbackCookies);
        if (!NT_SUCCESS(status)) {
            KdPrint(("[RegMon] 注册表回调函数无法注册(0x%08x)\n", status));
            IoDeleteSymbolicLink(&SymLinkName);
            IoDeleteDevice(g_DeviceObject);
            break;
        }


        if (!pDevExt->Queue.Init() ||
            !pDevExt->WhiteList.Init(NULL, 0) ||
            !pDevExt->BlockList.Init(NULL, 0))
        {
            KdPrint(("[RegMon] 列表初始化失败\n"));
            CmUnRegisterCallback(pDevExt->RegCallbackCookies);
            pDevExt->BlockList.FreeList();
            pDevExt->WhiteList.FreeList();
            pDevExt->Queue.FreeQueue();
            IoDeleteSymbolicLink(&SymLinkName);
            IoDeleteDevice(g_DeviceObject);
            break;
        }
        
        status = STATUS_SUCCESS;
    } while(0);
    
    KdPrint(("[RegMon] 注册表监控驱动加载完毕(0x%08x)\n", status));
    return status;
}