qq_30561005
yinggggggg
采纳率11.1%
2018-11-15 08:26 阅读 819

windows驱动 遍历nt路径下所有子文件及子文件夹的文件

160

写一个驱动,得到了nt路径,如\Device\HarddiskVolumeN(例如u盘),然后需要遍历其中的子文件和文件夹中的子文件。ZwOpenFile打开成功了,但是在msdn中没有找到遍历子文件的函数。

尝试用ZwQueryInformationFile,失败,status为STATUS_INVALID_PARAMETER(0xC0000000D)说是参数错误,但是看不到哪里错误了

图片说明

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

1条回答 默认 最新

  • oyljerry oyljerry 2018-11-15 08:37

    类似API的方式递归遍历,只不过API有点不一样

     #define ALLOCSIZE PAGE_SIZE
    
    #ifdef _REAL_DELETE_
    #define USE_DELETE_ON_CLOSE FILE_DELETE_ON_CLOSE
    #define FILE_ACCESS FILE_GENERIC_READ|DELETE
    #else
    #define USE_DELETE_ON_CLOSE FILE_DIRECTORY_FILE
    #define FILE_ACCESS FILE_GENERIC_READ
    #endif
    
    
    // int nLevel, PSTR prefix for debug only
    void ntTraverse(POBJECT_ATTRIBUTES poa, ULONG FileAttributes, int nLevel, PSTR prefix)
    {
        if (IoGetRemainingStackSize() < PAGE_SIZE)
        {
            DbgPrint("no stack!\n");
            return ;
        }
    
        if (!nLevel)
        {
            DbgPrint("!nLevel\n");
            return ;
        }
    
        NTSTATUS status;
        IO_STATUS_BLOCK iosb;
        UNICODE_STRING ObjectName;
        OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName };
    
        DbgPrint("%s[<%wZ>]\n", prefix, poa->ObjectName);
    
    #ifdef _REAL_DELETE_
        if (FileAttributes & FILE_ATTRIBUTE_READONLY)
        {
            if (0 <= NtOpenFile(&oa.RootDirectory, FILE_WRITE_ATTRIBUTES, poa, &iosb, FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT|FILE_OPEN_REPARSE_POINT))
            {
                static FILE_BASIC_INFORMATION fbi = { {}, {}, {}, {}, FILE_ATTRIBUTE_NORMAL };
                NtSetInformationFile(oa.RootDirectory, &iosb, &fbi, sizeof(fbi), FileBasicInformation);
                NtClose(oa.RootDirectory);
            }
        }
    #endif//_REAL_DELETE_
    
        if (0 <= (status = NtOpenFile(&oa.RootDirectory, FILE_ACCESS, poa, &iosb, FILE_SHARE_VALID_FLAGS, 
            FILE_SYNCHRONOUS_IO_NONALERT|FILE_OPEN_REPARSE_POINT|FILE_OPEN_FOR_BACKUP_INTENT|USE_DELETE_ON_CLOSE)))
        {
            if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if (PVOID buffer = ExAllocatePool(PagedPool, ALLOCSIZE))
                {
                    union {
                        PVOID pv;
                        PBYTE pb;
                        PFILE_DIRECTORY_INFORMATION DirInfo;
                    };
    
                    while (0 <= (status = NtQueryDirectoryFile(oa.RootDirectory, NULL, NULL, NULL, &iosb, 
                        pv = buffer, ALLOCSIZE, FileDirectoryInformation, 0, NULL, FALSE)))
                    {
    
                        ULONG NextEntryOffset = 0;
    
                        do 
                        {
                            pb += NextEntryOffset;
    
                            ObjectName.Buffer = DirInfo->FileName;
    
                            switch (ObjectName.Length = (USHORT)DirInfo->FileNameLength)
                            {
                            case 2*sizeof(WCHAR):
                                if (ObjectName.Buffer[1] != '.') break;
                            case sizeof(WCHAR):
                                if (ObjectName.Buffer[0] == '.') continue;
                            }
    
                            ObjectName.MaximumLength = ObjectName.Length;
    
    #ifndef _REAL_DELETE_
                            if (DirInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    #endif
                            {
                                ntTraverse(&oa, DirInfo->FileAttributes, nLevel - 1, prefix - 1);
                            }
    #ifndef _REAL_DELETE_
                            else
    #endif
                            {
                                DbgPrint("%s%8I64u <%wZ>\n", prefix, DirInfo->EndOfFile.QuadPart, &ObjectName);
                            }
    
                        } while (NextEntryOffset = DirInfo->NextEntryOffset);
    
                        if (ALLOCSIZE - iosb.Information > FIELD_OFFSET(FILE_DIRECTORY_INFORMATION, FileName[256]))
                        {
                            break;//NO_MORE_FILES
                        }
                    }
    
                    ExFreePool(buffer);
    
                    if (status == STATUS_NO_MORE_FILES)
                    {
                        status = STATUS_SUCCESS;
                    }
                }
            }
    
            NtClose(oa.RootDirectory);
        }
    
        if (0 > status)
        {
            DbgPrint("---- %x %wZ\n", status, poa->ObjectName);
        }
    }
    
    void ntTraverse()
    {
        char prefix[MAXUCHAR + 1];
        memset(prefix, '\t', MAXUCHAR);
        prefix[MAXUCHAR] = 0;
    
        STATIC_OBJECT_ATTRIBUTES(oa, "\\??\\c:\\users");
        //STATIC_OBJECT_ATTRIBUTES(oa, "\\systemroot");
        ntTraverse(&oa, FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_READONLY, MAXUCHAR, prefix + MAXUCHAR);
    }
    
    点赞 1 评论 复制链接分享

相关推荐