驱动型文件保护和进程保护

经过N多辗转和持续验证,终于搞定了在驱动程序中同时保护进程和文件(经持久测试后,避免了导致系统蓝屏的情况),重点
1)拒绝通过进程管理器关闭进程,同时又允许某些进程可以管理
2)通过比较文件名,截获被保护的文件操作

完整代码,可从https://download.csdn.net/download/pony12/12149153下载

进程保护回调函数:

NTSTATUS ProtectProcess(BOOLEAN Enable)
{
	OB_CALLBACK_REGISTRATION obReg;
	OB_OPERATION_REGISTRATION opReg;

	memset(&obReg, 0, sizeof(obReg));
	obReg.Version = ObGetFilterVersion();
	obReg.OperationRegistrationCount = 1;
	obReg.RegistrationContext = NULL;
	RtlInitUnicodeString(&obReg.Altitude, L"321000");
	memset(&opReg, 0, sizeof(opReg)); //初始化结构体变量

	//下面请注意这个结构体的成员字段的设置
	opReg.ObjectType = PsProcessType;
	opReg.Operations = OB_OPERATION_HANDLE_CREATE|OB_OPERATION_HANDLE_DUPLICATE; 
	opReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)&processPreCall; //在这里注册一个回调函数指针
	obReg.OperationRegistration = &opReg; //注意这一条语句

	return ObRegisterCallbacks(&obReg, &processCallBackHandle); //在这里注册回调函数
}

OB_PREOP_CALLBACK_STATUS 
	processPreCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pOperationInformation)
{
	if(pOperationInformation->KernelHandle == TRUE)
	{
		//如果是KernelHandle则直接返回不做操作
		return(OB_PREOP_SUCCESS);
	}

	if (pOperationInformation->ObjectType != *PsProcessType)
	{
		return(OB_PREOP_SUCCESS);
	}	

	HANDLE pid = PsGetProcessId((PEPROCESS)pOperationInformation->Object);
	char szProcName[512+1]={0};
	UNREFERENCED_PARAMETER(RegistrationContext);
	_snprintf(szProcName, sizeof(szProcName)-1, GetProcessImageNameByProcessID((ULONG)pid));

	parentsProtectedProcess = PsGetCurrentProcess();
	char szSvcProcName[512+1]={0};
	HANDLE svc_pid = PsGetProcessId(parentsProtectedProcess);
	_snprintf(szSvcProcName, sizeof(szSvcProcName)-1, GetProcessImageNameByProcessID((ULONG)svc_pid));

	//如果是auditflow_svc.exe进程的操作,则放行
	if( !_strnicmp(szSvcProcName,"auditflow_svc.", 14))
	{
		DbgPrint("PID : %ld CmdExe: %s\r\n", (ULONG64)svc_pid, szSvcProcName);
		return(OB_PREOP_SUCCESS);
	}

	//保护auditflow_svc.exe,auditflow_svc_child.exe,auditflow_child.exe,auditflowAgent.exe等进程
	//GetProcessImageNameByProcessID只能获得进程名字的前14位+\0,所以只能比较前几位
	if( !_strnicmp(szProcName,"auditflow", 9))
	{
		if (pOperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
		{
			if(pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess == PROCESS_TERMINATE)
			{
				//拒绝PROCESS_TERMINATE处理
				if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_TERMINATE) == PROCESS_TERMINATE)
				{
					//Terminate the process, such as by calling the user-mode TerminateProcess routine..
					pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
				}

				/*
				if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_VM_OPERATION) == PROCESS_VM_OPERATION)
				{
					//Modify the address space of the process, such as by calling the user-mode WriteProcessMemory and VirtualProtectEx routines.
					pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_OPERATION;
				}
				if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_VM_READ) == PROCESS_VM_READ)
				{
					//Read to the address space of the process, such as by calling the user-mode ReadProcessMemory routine.
					pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_READ;
				}
				if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_VM_WRITE) == PROCESS_VM_WRITE)
				{
					//Write to the address space of the process, such as by calling the user-mode WriteProcessMemory routine.
					pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_WRITE;
				}
				*/
			}
		}
	}

	return OB_PREOP_SUCCESS;
}

文件保护函数:

OB_PREOP_CALLBACK_STATUS FilePreCallBack(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
    UNICODE_STRING uniDosName;
	uniDosName.Length = 0;

	ACCESS_MASK oldCreateDesiredAccess = 0;
	ACCESS_MASK oldDuplicateDesiredAccess = 0;

	//参数检查
	if(NULL == OperationInformation)
		return OB_PREOP_SUCCESS;

    PFILE_OBJECT FileObject = (PFILE_OBJECT)OperationInformation->Object;
    HANDLE CurrentProcessId = PsGetCurrentProcessId();

	UNREFERENCED_PARAMETER(RegistrationContext);

	//有效性检查
	if(NULL == FileObject)
		return OB_PREOP_SUCCESS;
	
	//(1)屏蔽非IoFileObjectType类型的处理
    if( OperationInformation->ObjectType!=*IoFileObjectType)
    {
        return OB_PREOP_SUCCESS;
    }

    //(2)过滤无效指针
    if(    FileObject->FileName.Buffer==NULL              || 
        !MmIsAddressValid(FileObject->FileName.Buffer)    ||
        FileObject->DeviceObject==NULL                    ||
        !MmIsAddressValid(FileObject->DeviceObject)        )
    {
        return OB_PREOP_SUCCESS;
    }
	
	//(3)过滤无效路径, 否则使用RtlVolumeDeviceToDosName获取盘符会蓝屏
	/**/
	if( !_wcsicmp(FileObject->FileName.Buffer,L"\\Endpoint")	||
		!_wcsicmp(FileObject->FileName.Buffer,L"?")	||
		!_wcsicmp(FileObject->FileName.Buffer,L"\\.\\.")	||
		!_wcsicmp(FileObject->FileName.Buffer,L"\\"))
		return OB_PREOP_SUCCESS;
		
	//被保护的4个文件
	UNICODE_STRING UnicodeString1;
	RtlInitUnicodeString(&UnicodeString1, L"audit_auth.conf");
	UNICODE_STRING UnicodeString2;
	RtlInitUnicodeString(&UnicodeString2, L"ignsql.cfg");
	UNICODE_STRING UnicodeString3;
	RtlInitUnicodeString(&UnicodeString3, L"auditflow.ini");
	UNICODE_STRING UnicodeString4;
	RtlInitUnicodeString(&UnicodeString4, L"DBLocalInfo.ini");

	//获取操作文件char*名称
	char cbFileName[1024] = {0};
	UnicodeStringToChar(cbFileName, &FileObject->FileName);
	MyUpper(cbFileName);

	//(4)禁止删除下列文件, 经验证到这一步是有效的(非长时间,但区分了大小写)
	
	/* wcsstr容易造成蓝屏,应该使用RtlEqualUnicodeString
    if(wcsstr(_wcslwr(FileObject->FileName.Buffer),L"audit_auth.conf") || wcsstr(_wcslwr(FileObject->FileName.Buffer),L"ignsql.cfg") ||
	   wcsstr(_wcslwr(FileObject->FileName.Buffer),L"auditflow.ini")   || wcsstr(_wcslwr(FileObject->FileName.Buffer),L"DBLocalInfo.ini"))
	*/
	/* StrStrIW就是款字符的、StrStrIA是非宽字符的忽略大小写查找 不能用相等
	if(RtlEqualUnicodeString(&FileObject->FileName, &UnicodeString1,1) || RtlEqualUnicodeString(&FileObject->FileName, &UnicodeString2, 1) ||
	   RtlEqualUnicodeString(&FileObject->FileName, &UnicodeString3,1) || RtlEqualUnicodeString(&FileObject->FileName, &UnicodeString4, 1))
	*/
	if(strstr(cbFileName, "AUDIT_AUTH.CONF") || strstr(cbFileName, "IGNSQL.CFG") ||
	   strstr(cbFileName, "AUDITFLOW.INI") || strstr(cbFileName, "DBLOCALINFO.INI"))
	{
		oldCreateDesiredAccess = OperationInformation->Parameters->CreateHandleInformation.DesiredAccess;
		oldDuplicateDesiredAccess = OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess;
        if (FileObject->DeleteAccess==TRUE/*||FileObject->WriteAccess==TRUE*/)
        {
            if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
            {
                OperationInformation->Parameters->CreateHandleInformation.DesiredAccess=0;
            }
            if(OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE)
            {
                //OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess=0;
            }
			/*
			RtlVolumeDeviceToDosName(FileObject->DeviceObject, &uniDosName);
			DbgPrint("PID : %ld Drive: %wZ, Path: %wZ, fullPath: %wZ\r\n", (ULONG64)CurrentProcessId, &uniDosName, FileObject->FileName, &uniFilePath);
			//PID : 996 Drive: C:, Path: \Windows\System32\net1.exe, fullPath: C:\Windows\System32\net1.exe 
			DbgPrint("Operation=%d, DeleteAccess=%d, WriteAccess=%d, oldCreateDesiredAccess=%d, newCreateDesiredAcces=%d, oldDuplicateDesiredAccess=%d, newDuplicateDesiredAcces=%d\r\n", 
				OperationInformation->Operation, FileObject->DeleteAccess, FileObject->WriteAccess,
				oldCreateDesiredAccess, OperationInformation->Parameters->CreateHandleInformation.DesiredAccess,
				oldDuplicateDesiredAccess, OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess);
				*/
        }
    }

    return OB_PREOP_SUCCESS;
}

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pony12

助力1000篇OpenDDS文

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值