SYS驱动程序我 HOOK 了 ZwCreateFile 函数,如何拒绝文件的创建?我 HOOK 了 ZwCreateFile 函数,已经通过 ObjectAttributes->ObjectName->Buffer 检查出我要保护的目录。我不想让其他程序在这里目录里创建文件,该如何设置返回值。
我的设置是:
if ( ObjectAttributes->ObjectName->Buffer && wcsstr( ObjectAttributes->ObjectName->Buffer, L"111.txt" ) )
{
// 拒绝操作
FileHandle = NULL;
IoStatusBlock->Information = 0;
IoStatusBlock->Status = STATUS_UNSUCCESSFUL;
return STATUS_UNSUCCESSFUL;
}就这样都不行,文件还是可以被创建出来,请教,该如何设置返回值,能让系统提示,无法创建文件。谢谢!

解决方案 »

  1.   

    需要完成该irp,别再向下传递
      

  2.   


    /**
     * New process function
     * Hook API ZwCreateFile
     */
    NTSTATUS NewZwCreateFile
    (
    OUT PHANDLE FileHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PLARGE_INTEGER AllocationSize OPTIONAL,
    IN ULONG FileAttributes,
    IN ULONG ShareAccess,
    IN ULONG CreateDisposition,
    IN ULONG CreateOptions,
    IN PVOID EaBuffer OPTIONAL,
    IN ULONG EaLength
    )
    {
    KdPrint(("NewZwCreateFile:: start\n")); if ( ExGetPreviousMode() != KernelMode )
    {
    // ..
    KdPrint(("NewZwCreateFile:: not Kernel mode.\n"));
    } if ( ObjectAttributes->ObjectName->Buffer && wcsstr( ObjectAttributes->ObjectName->Buffer, L"111.txt" ) )
    {
    // ¾Ü¾ø²Ù×÷
    FileHandle = NULL;
    IoStatusBlock->Information = 0;
    IoStatusBlock->Status = STATUS_UNSUCCESSFUL;
    return STATUS_UNSUCCESSFUL;
    } CHAR szFileName[ MAX_PATH ]; if ( FILE_WRITE_DATA == ( FILE_WRITE_DATA & DesiredAccess ) ||
    FILE_APPEND_DATA == ( FILE_APPEND_DATA & DesiredAccess ) )
    {
    RtlZeroMemory( szFileName, sizeof(szFileName) );
    if ( ApiHookFsGetFilenameByHandle( FileHandle, szFileName, sizeof(szFileName) ) )
    {
    if ( APIHOOKFS_ACTION_DENIED == ApiHookFsCheckAction( szFileName ) )
    {
    // ¾Ü¾ø²Ù×÷
    return STATUS_ACCESS_DENIED;
    }
    }
    } return g_pfnOrgZwCreateFile
    (
    FileHandle,
    DesiredAccess,
    ObjectAttributes,
    IoStatusBlock,
    AllocationSize,
    FileAttributes,
    ShareAccess,
    CreateDisposition,
    CreateOptions,
    EaBuffer,
    EaLength
    );
    }
      

  3.   

        if ( ObjectAttributes->ObjectName->Buffer && wcsstr( ObjectAttributes->ObjectName->Buffer, L"111.txt" ) )
        {
            return STATUS_INVALID_PARAMETER;
        }
      

  4.   

    多谢楼上的 zhoujianhei 的回答,return STATUS_INVALID_PARAMETER;但是不行。文件依然可以被创建。
      

  5.   

    首先,你要确认你的ZwCreateFile函数确实被执行了。
      

  6.   

    1.查是否在DISPATCH_LEVEL
    2.根本的解决方法是不要hook ZwCreateFile函数.
    因为ZwCreateFile的实现很复杂。
    正确的方法是使用文件过滤驱动或者hook FSD.
      

  7.   

    那是我随便说的,实际原因和DISPATCH_LEVEL没有关系。
    真实的原因是你少了一个判断
    你只判断了ObjectAttributes->ObjectName
    没有判断ObjectAttributes->RootDirectory
    但是实际上不能直接判断ObjectAttributes->RootDriectory
    中间缺少一个过程
    我觉得这样解释太麻烦,又看到你前面加了一个KernelMode的判断,所以就说了ZwCreateFile不能在DISPATCH_LEVEL下执行.实际上不是这样!!!!!
      

  8.   

    楼上的朋友你好,非常感谢你的回答。
    可能是我没有描述清楚。
    那个代码就是测试代码,所以不需要判断 ObjectAttributes->RootDirectory 我想要的效果是,当用户创建任何包含 111.txt 这样的文件名的时候就提示,拒绝访问,无法创建文件。
    不知道该如何实现呢?我看到一些资料里面提到 IoCompleteRequest( Irp, IO_NO_INCREMENT );
    可是我这里没有 Irp,我哪里能获取到当前的 Irp 指针呢?谢谢!
      

  9.   

    先提一下,wcsstr函数是不安全的,驱动程序中的字符串是不要求\0结尾的。
    比较文件名时要注意OBJ_CASE_INSENSITIVE。
    FileHandle = NULL要改成*FileHandle = NULL。
    STATUS最好用STATUS_ACCESS_DENIED。
      

  10.   

    非常感谢 cnzdgs 
    感谢你一直给我回帖解决问题,这个问题希望能得到你的帮助,我实在搞不定了,返回什么值,文件都是可以被创建。
      

  11.   

    你是用什么方法测试?调试的时候执行到return了吗?
      

  12.   

    我是用 WinDbg + VMWare 调试的,绝对执行到那个位置了,这个我能保证。
      

  13.   

    用IFS filter不行吗?非得hook system services?
      

  14.   


    我很奇怪ApiHookFsGetFilenameByHandle使用的FileHandle这个时候是无效的吧?你怎么弄出它的文件名?
      

  15.   

    我刚学习驱动程序编程,也是到处找的资料弄的,不知道有没有问题,函数代码如下:
    /**
     * 根据文件句柄获取文件 DOS 全路径
     */
    BOOL ApiHookFsGetFilenameByHandle( IN HANDLE hFileHandle, OUT PCHAR pszFilename, IN USHORT uSize )
    {
    if ( NULL == hFileHandle )
    {
    return FALSE;
    } BOOL bRet = FALSE;
    NTSTATUS ntStatus; PWCHAR pBuffer;
    PFILE_OBJECT pstFileObject;
    POBJECT_NAME_INFORMATION pstObjectNameInfo; ntStatus = ObReferenceObjectByHandle( hFileHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (void **)&pstFileObject, NULL );
    if ( NT_SUCCESS( ntStatus ) )
    {
    ntStatus = IoQueryFileDosDeviceName( pstFileObject, &pstObjectNameInfo );
    if ( NT_SUCCESS( ntStatus ) )
    {
    ntStatus = drvfunc_w2a( pstObjectNameInfo->Name.Buffer, pszFilename, uSize );
    if ( NT_SUCCESS( ntStatus ) )
    {
    bRet = TRUE;
    }
    }
    } return bRet;
    }
      

  16.   

    1. wcsstr 是大小写敏感的。 这一段有点问题。    if ( ObjectAttributes->ObjectName->Buffer && wcsstr( ObjectAttributes->ObjectName->Buffer, L"111.txt" ) )
        {
            //    ¾Ü¾ø²Ù×÷
            FileHandle            = NULL;
            IoStatusBlock->Information    = 0;
            IoStatusBlock->Status        = STATUS_UNSUCCESSFUL;
            return STATUS_UNSUCCESSFUL;
        }
    2. ApiHookFsGetFilenameByHandle 本身没什么问题,我说的是调用它的时候FileHandle参数是无效,导致判断逻辑没有进行。
    于是就调用了g_pfnOrgZwCreateFile,文件就创建了。
    你为什么不直接ObjectName判断呢?
      

  17.   

    没有的,我单步调试走到里面了,我看到函数直接 return 的。
    返回是返回了,可是文件还是被创建了。
      

  18.   

    你最好确定一下ZwCreateFile没被系统多次调用
    Irp->IoStatus.Status = STATUS_ACCESS_DENIED; 
    Irp->IoStatus.Information = 0; 
    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    return STATUS_ACCESS_DENIED;
      

  19.   

    驱动程HOOK会不会被杀毒软件kill掉啊?