HIPS(Sfilter)

85 篇文章 6 订阅
83 篇文章 10 订阅

文件过滤那么就是相关分发函数的处理

FilterCreate(创建)

FilterRead(一般不拦截,加解密处理)

FilterWrite(修改,加解密处理)

FilterSetInfo(删,重命名,IRP_MJ_SET_INFORMATION)

Filterclose(一般不拦截,写关闭拦截)

FIlterClean(写关闭)

代码片段

  DriverObject->MajorFunction[IRP_MJ_CREATE] = sfCreate;
    //DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = SfCreate;
    //DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = SfCreate;

 	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = sfDeviceIoControl;//主要弹窗操作
 	DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = sfSetInformation;//监控文件操作
 	DriverObject->MajorFunction[IRP_MJ_WRITE] = sfWrite;
	DriverObject->MajorFunction[IRP_MJ_READ] = sfRead;

    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = SfFsControl;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = sfCleanup;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = sfClose;
NTSTATUS 
sfCreate(PDEVICE_OBJECT lpDevice, PIRP lpIrp)
{
    PLIST_ENTRY						CurrentList				= NULL;
    USER_RESULT						R3UserResult			= User_Pass;
    NAME_LOOKUP_FLAGS				LookupFlags				= 0;
    PNAME_CONTROL					lpNameControl			= NULL;
	NTSTATUS						ntStatus					= STATUS_SUCCESS;
    ULONG							ulInfo					= 0;
    BOOLEAN							bSkipped				= FALSE;
    ULONG							ulDisposition			= 0;
    KEVENT							waitEvent				= {0};
	IO_STACK_LOCATION				*lpIrpStack				= IoGetCurrentIrpStackLocation(lpIrp);
	PFILE_OBJECT					lpFileObject			= lpIrpStack->FileObject;
	PTWOWAY							pTwoWay					= NULL;
	WCHAR							wszLongName[MAX_PATH]	= {0};
	WCHAR							wszFileName[MAX_PATH]	= {0};
	WCHAR							wszDeviceName[MAX_PATH] = {0};
	UNICODE_STRING					ustrDeviceName			= {0};
	UNICODE_STRING					ustrRule				= {0};
	BOOLEAN							bPopWindow				= TRUE;

    if (IS_MY_CONTROL_DEVICE_OBJECT(lpDevice))
    {

        lpIrp->IoStatus.Status = ntStatus;
        lpIrp->IoStatus.Information = ulInfo;

        IoCompleteRequest(lpIrp, IO_NO_INCREMENT);

        return ntStatus;
    }
    else if (!IS_MY_DEVICE_OBJECT(lpDevice))
    {
        lpIrp->IoStatus.Status = ntStatus = STATUS_INVALID_PARAMETER;
        lpIrp->IoStatus.Information = ulInfo;

        IoCompleteRequest(lpIrp, IO_NO_INCREMENT);

        return ntStatus;
    }
    else//过滤设备
    {
        PSFILTER_DEVICE_EXTENSION lpDevExt = (PSFILTER_DEVICE_EXTENSION)(lpDevice->DeviceExtension);
        PIO_SECURITY_CONTEXT securityContext = lpIrpStack->Parameters.Create.SecurityContext;

        if (
            lpIrp->RequestorMode == KernelMode || 
			IsDir(lpIrpStack) == TRUE ||
            PsGetCurrentProcessId() == g_hSystemProcID ||
            FlagOn(lpIrpStack->Flags, SL_OPEN_TARGET_DIRECTORY) ||
            (lpIrp->Flags & IRP_PAGING_IO) ||//IRP_NOCHACHE并且非IRP_XXX_PAGING_IO,也就是用户设置FILE_NO_INTERMEDIATE_BUFFERING,不需要进入缓存,流程APP->io->fsd->disk,
            (lpIrp->Flags & IRP_SYNCHRONOUS_PAGING_IO))//2.IRP_CACHE并且非IRP_XXX_PAGING_IP,就是FSD->>CC->mm,3IRP_PAGING_IO情况2中mm-》FSSD——》DISK只进入内存,并没有进入文件系统,反正是有内核内存管理器发的irp
        {
            bSkipped = TRUE;
            goto _EXIT;
        }


        ulDisposition = (lpIrpStack->Parameters.Create.Options >> 24) & 0xFF;//高八位

        if (ulDisposition == FILE_CREATE || ulDisposition == FILE_OVERWRITE || ulDisposition == FILE_OVERWRITE_IF)
        {
			//修改打开?
        }
        else
        {
			bPopWindow = FALSE;
        }

        // 在create时获取文件路径

		if (FlagOn(lpIrpStack->Flags, SL_OPEN_TARGET_DIRECTORY)) 
        {
            SetFlag(LookupFlags, NLFL_OPEN_TARGET_DIR);
        }

        if (lpDevExt->NLExtHeader.DosName.Length != 0) 
        {
            SetFlag(LookupFlags, NLFL_USE_DOS_DEVICE_NAME);
        }
      
        if (FlagOn(lpIrpStack->Parameters.Create.Options, FILE_OPEN_BY_FILE_ID)) 
        {
            SetFlag(LookupFlags, NLFL_OPEN_BY_ID);
        }

		SetFlag(LookupFlags, NLFL_IN_CREATE);
      
        ntStatus = GetFileNameFromObject(&lpNameControl, LookupFlags, lpIrpStack->FileObject, lpDevice);//拿到文件名

        if (lpNameControl == NULL ||
			!NT_SUCCESS(ntStatus))
        {
            // 允许
            bSkipped = TRUE;
            goto _EXIT;
        }

        if (IsShortNamePath(lpNameControl->Name.Buffer))
        {
			//实际上应该处理短格式文件名
			ConverShortToLongName(wszLongName, lpNameControl->Name.Buffer, sizeof(WCHAR)*MAX_PATH);
			RtlCopyMemory(lpNameControl->Name.Buffer, wszLongName, sizeof(WCHAR)*MAX_PATH);
        }

		ustrDeviceName.Buffer = wszDeviceName;
		ustrDeviceName.Length = 0;
		ustrDeviceName.MaximumLength = sizeof(WCHAR)*MAX_PATH;

		RtlCopyUnicodeString(&ustrDeviceName, &lpNameControl->Name);
		//RtlCopyMemory(wszDeviceName, lpNameControl->Name.Buffer, MAX_PATH*sizeof(WCHAR));、
		//UstrDeviceName:\device\harddiskvolume3\doc\1.txt
		//wszFileName:C:\doc\1.txt要从上面类型转下面符号链接的格式

		if (!GetNTLinkName(ustrDeviceName.Buffer, wszFileName))
		{
            bSkipped = TRUE;
            goto _EXIT;
		}

		RtlInitUnicodeString(&ustrDeviceName, wszFileName);
		RtlCopyUnicodeString(&lpNameControl->Name, &ustrDeviceName);



		RtlInitUnicodeString(&ustrRule, L"C:\\WINDOWS\\SYSTEM32\\*\\*.SYS");//定义规则匹配,忽略大小写,必须全是大写

		if (!IsPatternMatch(&ustrRule, &lpNameControl->Name, TRUE))
		{
            //bSkipped = TRUE;
            //goto _EXIT;
			bPopWindow = FALSE;
		}
		else
		{
			DbgPrint("File:%wZ\n", &lpNameControl->Name);
			DbgPrint("Noted: rule matched\n");
		}

		if (bPopWindow)
		{
			R3UserResult = hipsGetResultFromUser(L"创建", lpNameControl->Name.Buffer, NULL, User_DefaultNon);
		}

        if (R3UserResult == User_Block)
        {
            //禁止
            lpIrp->IoStatus.Information = 0;
            lpIrp->IoStatus.Status = STATUS_ACCESS_DENIED;
            IoCompleteRequest(lpIrp, IO_NO_INCREMENT);
            ntStatus = STATUS_ACCESS_DENIED;
            bSkipped = FALSE;

            goto _EXIT;
        }
//使用IOCOPY方式下发,需要最终的结果,成功失败
        IoCopyCurrentIrpStackLocationToNext(lpIrp);

        KeInitializeEvent(&waitEvent,
                          NotificationEvent,
                          FALSE);

        IoSetCompletionRoutine(lpIrp,
                               FilterCreateCompletion,
                               &waitEvent,
                               TRUE,
                               TRUE,
                               TRUE);

        ntStatus = IoCallDriver(((PSFILTER_DEVICE_EXTENSION)lpDevice->DeviceExtension)->NLExtHeader.AttachedToDeviceObject,
                              lpIrp);

        if (ntStatus == STATUS_PENDING)
        {
            ntStatus = KeWaitForSingleObject(&waitEvent,
                                           Executive,
                                           KernelMode,
                                           FALSE,
                                           NULL);
        }

        ntStatus = lpIrp->IoStatus.Status;

        if (NT_SUCCESS(ntStatus))
        {

			//如果HASH表中没有的话,此处将获得的文件名放入HASH表中,
			{
				PHASHDATA lpData= ExAllocatePoolWithTag(NonPagedPool, sizeof(HASHDATA), 'HSAH');
				if (lpData)
				{
					RtlZeroMemory(lpData, sizeof(HASHDATA));
					lpData->lpNameControl = lpNameControl;//文件名必须在创建时候并且返回irp成功,得到的才是可靠的,读写都是不可靠,因为以后操作不依赖文件名的,依赖lpFileObject
					lpNameControl = NULL;
					LockWrite(&g_HashTableLock);
					Insert((DWORD)lpFileObject, lpData, g_pHashTable);//文件内核对象作为Key,文件名作为value
					UnLockWrite(&g_HashTableLock);
				}
			}
        }

        IoCompleteRequest(lpIrp, IO_NO_INCREMENT);
    }

_EXIT:
    if (bSkipped)
    {
        IoSkipCurrentIrpStackLocation( lpIrp );
        ntStatus = IoCallDriver(((PSFILTER_DEVICE_EXTENSION)lpDevice->DeviceExtension)->NLExtHeader.AttachedToDeviceObject, lpIrp);
    }

    if (lpNameControl != NULL)
    {
        NLFreeNameControl(lpNameControl, &gSfNameBufferLookasideList);

    }

    return ntStatus;
}

写入

 

NTSTATUS
sfWrite(PDEVICE_OBJECT lpDevice, PIRP lpIrp)
{
    PLIST_ENTRY				CurrentList			= NULL;
    USER_RESULT				R3UserResult		= User_Pass;
    PNAME_CONTROL			lpNameControl		= NULL;
    BOOLEAN					bSkipped			= FALSE;
	NTSTATUS				Status				= STATUS_SUCCESS;
    ULONG					ulInfomation		= 0;
	IO_STACK_LOCATION		*lpIrpStack			= IoGetCurrentIrpStackLocation(lpIrp);
	PFILE_OBJECT			lpFileObject		= lpIrpStack->FileObject;
	PTWOWAY					pTwoWay				= NULL;
	UNICODE_STRING			ustrRule			= {0};

    if (IS_MY_CONTROL_DEVICE_OBJECT(lpDevice))
    {
        lpIrp->IoStatus.Status = Status;
        lpIrp->IoStatus.Information = ulInfomation;

        IoCompleteRequest(lpIrp, IO_NO_INCREMENT);

        return Status;
    }
    else if (!IS_MY_DEVICE_OBJECT(lpDevice))
    {
        lpIrp->IoStatus.Status = Status = STATUS_INVALID_PARAMETER;
        lpIrp->IoStatus.Information = 0;

        IoCompleteRequest(lpIrp, IO_NO_INCREMENT);

        return Status;
    }
    else
    {
        PSFILTER_DEVICE_EXTENSION lpDevExt = (PSFILTER_DEVICE_EXTENSION)(lpDevice->DeviceExtension);

        if (
            KeGetCurrentIrql() > APC_LEVEL ||
            PsGetCurrentProcessId() == g_hSystemProcID ||
            (lpIrp->Flags & IRP_PAGING_IO) ||//虚拟内存缓存机制发下来的
            (lpIrp->Flags & IRP_SYNCHRONOUS_PAGING_IO))
        {
            bSkipped = TRUE;
            goto _Exit;
        }

		//此处需要通过FileObject获得文件名

		pTwoWay = Find((DWORD)lpFileObject, g_pHashTable);//lpFileObject:lpIrpStack->FileObject;在irp栈上
		if (pTwoWay == NULL)
		{
            bSkipped = TRUE;
            goto _Exit;
		}
		lpNameControl = pTwoWay->data.lpNameControl;

		RtlInitUnicodeString(&ustrRule, L"C:\\WINDOWS\\SYSTEM32\\*\\*.SYS");
		
		if (!IsPatternMatch(&ustrRule, &lpNameControl->Name, TRUE))
		{
            bSkipped = TRUE;
            goto _Exit;
		}

		R3UserResult = hipsGetResultFromUser(L"写入", lpNameControl->Name.Buffer, NULL, User_DefaultNon);

        if (R3UserResult == User_Block)
        {
            //禁止
            lpIrp->IoStatus.Information = 0;
            lpIrp->IoStatus.Status = STATUS_ACCESS_DENIED;
            IoCompleteRequest(lpIrp, IO_NO_INCREMENT);
            Status = STATUS_ACCESS_DENIED;
            bSkipped = FALSE;

            goto _Exit;
        }

        //允许
        bSkipped = TRUE;
        goto _Exit;
    }

_Exit:
    if (bSkipped)
    {
        IoSkipCurrentIrpStackLocation( lpIrp );
        Status = IoCallDriver(((PSFILTER_DEVICE_EXTENSION)lpDevice->DeviceExtension)->NLExtHeader.AttachedToDeviceObject, lpIrp);
    }

    return Status;
}

重命名和删除

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值