ZwQueryDirectoryFile get file information

// tt.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include "pch.h"
#include <windows.h>
#include <stdio.h>

typedef LONG NTSTATUS;
typedef NTSTATUS *PNTSTATUS;
typedef DWORD ULONG_PTR;

#define STATUS_SUCCESS (NTSTATUS)0x00000000L
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define FILE_OPEN               0x00000001
#define OBJ_CASE_INSENSITIVE    0x00000040L
#define FILE_DIRECTORY_FILE     0x00000001

#define InitializeObjectAttributes( p, n, a, r, s ) {    \
    (p)->uLength = sizeof( OBJECT_ATTRIBUTES );          \
    (p)->hRootDirectory = r;                             \
    (p)->uAttributes = a;                                \
    (p)->pObjectName = n;                                \
    (p)->pSecurityDescriptor = s;                        \
    (p)->pSecurityQualityOfService = NULL;               \
}

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING;

typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
typedef USHORT RTL_STRING_LENGTH_TYPE;

typedef struct _STRING {
    USHORT Length;
    USHORT MaximumLength;
    PCHAR Buffer;
} STRING;

typedef STRING *PSTRING;
typedef STRING ANSI_STRING;
typedef PSTRING PANSI_STRING;

typedef struct _OBJECT_ATTRIBUTES {
    ULONG uLength;
    HANDLE hRootDirectory;
    PUNICODE_STRING pObjectName;
    ULONG uAttributes;
    PVOID pSecurityDescriptor;
    PVOID pSecurityQualityOfService;
} OBJECT_ATTRIBUTES;

#define InitializeObjectAttributes( p, n, a, r, s ) {    \
    (p)->uLength = sizeof( OBJECT_ATTRIBUTES );          \
    (p)->hRootDirectory = r;                             \
    (p)->uAttributes = a;                                \
    (p)->pObjectName = n;                                \
    (p)->pSecurityDescriptor = s;                        \
    (p)->pSecurityQualityOfService = NULL;               \
}

typedef OBJECT_ATTRIBUTES * POBJECT_ATTRIBUTES;

typedef struct _IO_STATUS_BLOCK {
    union {
        NTSTATUS Status;
        PVOID Pointer;
    };
    ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef VOID(NTAPI *PIO_APC_ROUTINE) (IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved);

typedef enum _FILE_INFORMATION_CLASS {
    FileDirectoryInformation = 1,
    FileFullDirectoryInformation,
    FileBothDirectoryInformation,
    FileBasicInformation,
    FileStandardInformation,
    FileInternalInformation,
    FileEaInformation,
    FileAccessInformation,
    FileNameInformation,
    FileRenameInformation,
    FileLinkInformation,
    FileNamesInformation,
    FileDispositionInformation,
    FilePositionInformation,
    FileFullEaInformation,
    FileModeInformation,
    FileAlignmentInformation,
    FileAllInformation,
    FileAllocationInformation,
    FileEndOfFileInformation,
    FileAlternateNameInformation,
    FileStreamInformation,
    FilePipeInformation,
    FilePipeLocalInformation,
    FilePipeRemoteInformation,
    FileMailslotQueryInformation,
    FileMailslotSetInformation,
    FileCompressionInformation,
    FileObjectIdInformation,
    FileCompletionInformation,
    FileMoveClusterInformation,
    FileQuotaInformation,
    FileReparsePointInformation,
    FileNetworkOpenInformation,
    FileAttributeTagInformation,
    FileTrackingInformation,
    FileIdBothDirectoryInformation,
    FileIdFullDirectoryInformation,
    FileValidDataLengthInformation,
    FileShortNameInformation,
    FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;

typedef enum _EVENT_TYPE { NotificationEvent, SynchronizationEvent } EVENT_TYPE;

typedef struct _FILE_BOTH_DIR_INFORMATION {
    ULONG NextEntryOffset;
    ULONG FileIndex;
    LARGE_INTEGER CreationTime;
    LARGE_INTEGER LastAccessTime;
    LARGE_INTEGER LastWriteTime;
    LARGE_INTEGER ChangeTime;
    LARGE_INTEGER EndOfFile;
    LARGE_INTEGER AllocationSize;
    ULONG FileAttributes;
    ULONG FileNameLength;
    ULONG EaSize;
    CCHAR ShortNameLength;
    WCHAR ShortName[12];
    WCHAR FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;

NTSTATUS(WINAPI * pRtlInitUnicodeString)(PUNICODE_STRING, PCWSTR);
NTSTATUS(WINAPI * pZwCreateFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG);
NTSTATUS(WINAPI * pZwCreateEvent)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, EVENT_TYPE, BOOLEAN);
NTSTATUS(WINAPI * pZwQuerydirectoryFile)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS, BOOLEAN, PUNICODE_STRING, BOOLEAN);
NTSTATUS(WINAPI * pZwWaitForSingleobject)(HANDLE, BOOLEAN, PLARGE_INTEGER);
NTSTATUS(WINAPI * pRtlUnicodeStringToAnsiString)(PANSI_STRING, PCUNICODE_STRING, BOOLEAN);
NTSTATUS(WINAPI * pZwClose)(HANDLE);

void IntializeNativeFunctions(VOID)
{
    HMODULE hModule = LoadLibraryW(L"Ntdll.dll");

    pRtlInitUnicodeString = (NTSTATUS(WINAPI *)(PUNICODE_STRING, PCWSTR)) GetProcAddress(hModule, "RtlInitUnicodeString");
    pZwCreateFile = (NTSTATUS(WINAPI *)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG)) GetProcAddress(hModule, "ZwCreateFile");
    pZwCreateEvent = (NTSTATUS(WINAPI *)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, EVENT_TYPE, BOOLEAN)) GetProcAddress(hModule, "ZwCreateEvent");
    pZwQuerydirectoryFile = (NTSTATUS(WINAPI *)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS, BOOLEAN, PUNICODE_STRING, BOOLEAN)) GetProcAddress(hModule, "ZwQueryDirectoryFile");
    pZwWaitForSingleobject = (NTSTATUS(WINAPI *)(HANDLE, BOOLEAN, PLARGE_INTEGER)) GetProcAddress(hModule, "ZwWaitForSingleObject");
    pRtlUnicodeStringToAnsiString = (NTSTATUS(WINAPI *)(PANSI_STRING, PCUNICODE_STRING, BOOLEAN)) GetProcAddress(hModule, "RtlUnicodeStringToAnsiString");
    pZwClose = (NTSTATUS(WINAPI *)(HANDLE)) GetProcAddress(hModule, "ZwClose");
}

NTSTATUS ListDirectory(WCHAR * pszDirectoryName)
{
    UNICODE_STRING RootDirectoryName;
    ANSI_STRING as;
    OBJECT_ATTRIBUTES RootDirectoryAttributes;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    HANDLE RootDirectoryHandle;
    IO_STATUS_BLOCK Iosb;
    HANDLE Event;
    PUCHAR Buffer[65536] = {0};
    WCHAR wszBuffer[50];

    PFILE_BOTH_DIR_INFORMATION DirInformation;

    if (pRtlInitUnicodeString == NULL) return -1;
    if (pRtlUnicodeStringToAnsiString == NULL) return -1;
    swprintf(wszBuffer, sizeof(wszBuffer), L"\\??\\%s\\", pszDirectoryName);
    ntStatus = ((pRtlInitUnicodeString)(&RootDirectoryName, wszBuffer));
    if (!NT_SUCCESS(ntStatus))
        return ntStatus;
    InitializeObjectAttributes(&RootDirectoryAttributes, &RootDirectoryName, OBJ_CASE_INSENSITIVE, 0, 0);
    if (pZwCreateFile == NULL) return -1;
    ntStatus = ((pZwCreateFile)(&RootDirectoryHandle,
        GENERIC_READ,
        &RootDirectoryAttributes,
        &Iosb,
        0,
        FILE_ATTRIBUTE_DIRECTORY,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        FILE_OPEN,
        FILE_DIRECTORY_FILE,
        0, 0));

    if (!NT_SUCCESS(ntStatus))
    {
        printf("Unable to open %s, error = 0x%x\n", &RootDirectoryName, ntStatus);
        return ntStatus;
    }
    if (pZwCreateEvent == NULL) return -1;
    ntStatus = ((pZwCreateEvent)(&Event, GENERIC_ALL, 0, NotificationEvent, FALSE));
    if (!NT_SUCCESS(ntStatus))
    {
        printf("Event creation failed with error 0x%x\n", ntStatus);
        return ntStatus;
    }
    if (pZwQuerydirectoryFile == NULL) return -1;
    if (((pZwQuerydirectoryFile)(RootDirectoryHandle,
        Event, 0, 0,
        &Iosb,
        Buffer,
        sizeof(Buffer),
        FileBothDirectoryInformation,
        FALSE,
        NULL,
        FALSE)) == STATUS_PENDING)
    {
        if (pZwWaitForSingleobject == NULL) return -1;
        ntStatus = ((pZwWaitForSingleobject)(Event, FALSE, 0));
    }
    if (!NT_SUCCESS(ntStatus))
    {
        printf("Unable to query directory contents, error 0x%x\n", ntStatus);
        return ntStatus;
    }
    DirInformation = (PFILE_BOTH_DIR_INFORMATION)Buffer;

    while (1)
    {
        UNICODE_STRING EntryName;
        EntryName.MaximumLength = EntryName.Length = (USHORT)DirInformation->FileNameLength;
        EntryName.Buffer = &DirInformation->FileName[0];
        ((pRtlUnicodeStringToAnsiString)(&as, &EntryName, TRUE));
        printf("%s\n", is .Buffer);
        if ( 0 == DirInformation-> NextEntryOffset)
             break ;
        else 
            DirInformation = (PFILE_BOTH_DIR_INFORMATION) (((PUCHAR) DirInformation) + DirInformation-> NextEntryOffset); 
    } 
    ((PZwClose) (RootDirectoryHandle)); 
    return ntStatus; 
} 

Int main (void) 
{ 
    WCHAR wszDirectory [] = {L " F: \\ \\ Desktop File " }; 
    IntializeNativeFunctions (); 
    ListDirectory (wszDirectory); 
    return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/anow/p/11102389.html