【问题标题】:File System Filter Driver - Deny file creation文件系统过滤器驱动程序 - 拒绝创建文件
【发布时间】:2017-03-23 09:43:11
【问题描述】:

我创建了一个文件系统过滤器驱动程序。

我的驱动程序过滤 IRP_MJ_CREATE 并打印文件名。

NTSTATUS DispatchCreate(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)
{
    PFILE_OBJECT FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;

    DbgPrint("DispatchCreate() : %wZ\n", &FileObject->FileName;)

    return DispatchPassThrough(DeviceObject, Irp);
}

这很好用。

现在我想在创建新文件的每个请求上都拒绝访问。

(如果可能,“您没有权限。”)

所以我尝试了一些方法。

首先,我做了以下事情。

NTSTATUS DispatchCreate(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)
{
    PFILE_OBJECT FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);

    ULONG Option = Stack->Parameters.Create.Options;

    if ((Option >> 24) == FILE_CREATE)
    {
        DbgPrint("DispatchCreate() : File Create Denied, %wZ, %x \n", &FileObject->FileName, Option);

        return STATUS_ACCESS_VIOLATION; // or any error code
    }

    return DispatchPassThrough(DeviceObject, Irp);
}

这很好用,但有点奇怪。

例如,如果您没有管理员权限,那么当您尝试在“C:\”中创建某些内容时,您就有一点发言权。

这个时候,不知道FileObject可能会被正常删除。

所以我做了以下更改。

NTSTATUS DispatchCreate(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)
{
    PFILE_OBJECT FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);

    ULONG Option = Stack->Parameters.Create.Options;

    if ((Option >> 24) == FILE_CREATE)
    {
        DbgPrint("DispatchCreate() : File Create Denied, %wZ, %x \n", &FileObject->FileName, Option);

        Irp->IoStatus.Status = STATUS_ACCESS_VIOLATION;
        return Irp->IoStatus.Status;
    }

    return DispatchPassThrough(DeviceObject, Irp);
}

但是,会出现稍微不同的错误消息。

我希望它的行为与发生“拒绝访问”时完全相同,因为我没有正常权限。



还有一个问题。

与其他 Dispatch 例程不同,IRP_MJ_CREATEIRP_MJ_CLOSE 不需要 IoCompleteRequest()

我确认,即使我只有以下部分,手柄也正常返回。 (在用户模式下。)

return STATUS_SUCCESS;



感谢您的阅读。

请回答我的问题。

【问题讨论】:

    标签: windows filesystems driver windows-kernel filter-driver


    【解决方案1】:

    如果您需要在过滤器中拒绝某些请求 - 不需要将其传递给连接的设备 - 您需要自己设置错误状态并完成 IRP

    Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
    IofCompleteRequest(Irp);// !!!
    return STATUS_ACCESS_DENIED; // ! not Irp->IoStatus.Status - you can not access Irp after call IofCompleteRequest
    

    与其他 Dispatch 例程不同,IRP_MJ_CREATE 和 IRP_MJ_CLOSE 不会 需要 IoCompleteRequest()。

    当然这是绝对错误的。每个 Irp 都必须通过调用 IofCompleteRequest 来完成

    【讨论】:

    • 感谢您的回复。我解决了这个问题。但是,当我第一次创建一个简单的驱动程序进行练习时,CreateDispatch()CloseDispatch() 例程确认用户模式程序正常抓取句柄,即使我只是return STATUS_SUCCESS;。你能解释一下为什么吗?
    • @SlayerBae - 您从驱动程序返回控制权。创建/关闭没有输出参数(创建有状态块,但用户无法检查)。但是irp仍然没有被破坏。这就像内存分配 - 您可以分配然后不释放内存(并且不要更多地使用它)并且一切都会正常工作,除了内存泄漏。
    • 如果你没有完成另一个 irp,情况会更严重。说 read for buffered io - 数据不会被复制到用户缓冲区。如果异步 io - apc 或 iocp 数据包将不排队。当线程退出系统检查时 - 是否存在与线程关联的 irp - 如果仍然存在(如创建/关闭未完成)线程可以在退出时挂起(当 irp 完成时等待),因为结果进程也永远不会退出。系统未关闭/重新启动。 not complete irp - 非常严重的错误,不仅仅是内存泄漏。这可以在很长一段时间后才可见
    • 谢谢。一些我没用过的例子IoCompleteRequest()。我想知道为什么这些例子没有完成,但问题得到了回答。谢谢。
    • @abhiarora - 块执行 - 更快地查找 PsSetCreateProcessNotifyRoutine[Ex]
    猜你喜欢
    • 2012-08-11
    • 2011-08-10
    • 2021-08-19
    • 1970-01-01
    • 2015-03-21
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多