Skip to content

Instantly share code, notes, and snippets.

@mahldcat
Created December 3, 2022 20:31
Show Gist options
  • Select an option

  • Save mahldcat/9a8c10f9a60f5ccf2588120cb41ea7cf to your computer and use it in GitHub Desktop.

Select an option

Save mahldcat/9a8c10f9a60f5ccf2588120cb41ea7cf to your computer and use it in GitHub Desktop.
#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* pNtCreateFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG);
NTSTATUS(WINAPI* pNtCreateEvent)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, EVENT_TYPE, BOOLEAN);
NTSTATUS(WINAPI* pNtQuerydirectoryFile)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS, BOOLEAN, PUNICODE_STRING, BOOLEAN);
NTSTATUS(WINAPI* pNtWaitForSingleobject)(HANDLE, BOOLEAN, PLARGE_INTEGER);
NTSTATUS(WINAPI* pRtlUnicodeStringToAnsiString)(PANSI_STRING, PCUNICODE_STRING, BOOLEAN);
NTSTATUS(WINAPI* pNtClose)(HANDLE);
void IntializeNativeFunctions(VOID)
{
HMODULE hModule = LoadLibrary(L"Ntdll.dll");
pRtlInitUnicodeString = (NTSTATUS(WINAPI*)(PUNICODE_STRING, PCWSTR)) GetProcAddress(hModule, "RtlInitUnicodeString");
pNtCreateFile = (NTSTATUS(WINAPI*)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG)) GetProcAddress(hModule, "NtCreateFile");
pNtCreateEvent = (NTSTATUS(WINAPI*)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, EVENT_TYPE, BOOLEAN)) GetProcAddress(hModule, "NtCreateEvent");
pNtQuerydirectoryFile = (NTSTATUS(WINAPI*)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS, BOOLEAN, PUNICODE_STRING, BOOLEAN)) GetProcAddress(hModule, "NtQueryDirectoryFile");
pNtWaitForSingleobject = (NTSTATUS(WINAPI*)(HANDLE, BOOLEAN, PLARGE_INTEGER)) GetProcAddress(hModule, "NtWaitForSingleObject");
pRtlUnicodeStringToAnsiString = (NTSTATUS(WINAPI*)(PANSI_STRING, PCUNICODE_STRING, BOOLEAN)) GetProcAddress(hModule, "RtlUnicodeStringToAnsiString");
pNtClose = (NTSTATUS(WINAPI*)(HANDLE)) GetProcAddress(hModule, "NtClose");
}
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];
WCHAR wszBuffer[50];
PFILE_BOTH_DIR_INFORMATION DirInformation;
if (pRtlInitUnicodeString == NULL) return -1;
if (pRtlUnicodeStringToAnsiString == NULL) return -1;
_snwprintf(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 (pNtCreateFile == NULL) return -1;
ntStatus = ((pNtCreateFile)(&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 (pNtCreateEvent == NULL) return -1;
ntStatus = ((pNtCreateEvent)(&Event, GENERIC_ALL, 0, NotificationEvent, FALSE));
if (!NT_SUCCESS(ntStatus))
{
printf("Event creation failed with error 0x%x\n", ntStatus);
return ntStatus;
}
if (pNtQuerydirectoryFile == NULL) return -1;
if (((pNtQuerydirectoryFile)(RootDirectoryHandle,
Event, 0, 0,
&Iosb,
Buffer,
sizeof(Buffer),
FileBothDirectoryInformation,
FALSE,
NULL,
FALSE)) == STATUS_PENDING)
{
if (pNtWaitForSingleobject == NULL) return -1;
ntStatus = ((pNtWaitForSingleobject)(Event, TRUE, 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));
if (DirInformation->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
printf("Directory name: ");
else printf("Filename: ");
printf("%s\n", as.Buffer);
if (0 == DirInformation->NextEntryOffset)
break;
else
DirInformation = (PFILE_BOTH_DIR_INFORMATION)(((PUCHAR)DirInformation) + DirInformation->NextEntryOffset);
}
((pNtClose)(RootDirectoryHandle));
return ntStatus;
}
int main()
{
WCHAR wszDirectory[] = { L"G:\\PleskVHosts" };
IntializeNativeFunctions();
ListDirectory(wszDirectory);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment