// 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", as.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; }