#include #include typedef NTSTATUS (__stdcall *NT_OPEN_FILE)(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions); NT_OPEN_FILE NtOpenFileStruct; // typedef VOID (__stdcall *RTL_INIT_ANSI_STRING)(_Out_ PANSI_STRING DestinationString, _In_opt_ PCSZ SourceString); // RTL_INIT_ANSI_STRING RtlInitAnsiStringStruct; // typedef VOID (__stdcall *RTL_INIT_STRING)(_Out_ PSTRING DestinationString, _In_opt_ PCSZ SourceString); // RTL_INIT_STRING RtlInitStringStruct; typedef NTSTATUS (__stdcall *RTL_ANSI_STRING_TO_UNICODE_STRING)(_Inout_ PUNICODE_STRING DestinationString, _In_ PCANSI_STRING SourceString, _In_ BOOLEAN AllocateDestinationString); RTL_ANSI_STRING_TO_UNICODE_STRING RtlAnsiStringToUnicodeStringStruct; // typedef BOOLEAN (__stdcall *RTL_DOS_PATH_NAME_TO_RELATIVE_NT_PATH_NAME_U)(_In_ PCWSTR DosFileName, _Out_ PUNICODE_STRING NtFileName, _Out_opt_ PWSTR* FilePath, _Out_opt_ PRTL_RELATIVE_NAME RelativeName); // RTL_DOS_PATH_NAME_TO_RELATIVE_NT_PATH_NAME_U RtlDosPathNameToRelativeNtPathName_UStruct; typedef BOOLEAN (__stdcall *RTL_DOS_PATH_NAME_TO_NT_PATH_NAME_U)(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR * NtFileNamePart, _Out_opt_ PVOID DirectoryInfo); RTL_DOS_PATH_NAME_TO_NT_PATH_NAME_U RtlDosPathNameToNtPathName_UStruct; typedef VOID (__stdcall *RTL_INIT_UNICODE_STRING)(_Inout_ PUNICODE_STRING DestinationString, _In_opt_ PCWSTR SourceString); RTL_INIT_UNICODE_STRING RtlInitUnicodeStringStruct; typedef VOID (__stdcall *RTL_FREE_UNICODE_STRING)(_Inout_ PUNICODE_STRING UnicodeString); RTL_FREE_UNICODE_STRING RtlFreeUnicodeStringStruct; static void local_init_ntdll(void); static void local_init_ntdll(void) { /* load the ntdll.dll */ HMODULE hModule = LoadLibrary("ntdll.dll"); NtOpenFileStruct = (NT_OPEN_FILE)GetProcAddress(hModule, "NtOpenFile"); if(NtOpenFileStruct == NULL) { error_printf("Error: could not find the function NtOpenFile in library ntdll.dll."); exit(-1); } error_printf("NtOpenFile is located at 0x%p in ntdll.dll.\n", NtOpenFileStruct); //RtlInitAnsiStringStruct = (RTL_INIT_ANSI_STRING)GetProcAddress(hModule, "RtlInitAnsiString"); //if(NtOpenFileStruct == NULL) { // error_printf("Error: could not find the function RtlInitAnsiString in library ntdll.dll."); // exit(-1); //} //RtlInitStringStruct = (RTL_INIT_ANSI_STRING)GetProcAddress(hModule, "RtlInitString"); //if(NtOpenFileStruct == NULL) { // error_printf("Error: could not find the function RtlInitString in library ntdll.dll."); // exit(-1); //} RtlAnsiStringToUnicodeStringStruct = (RTL_ANSI_STRING_TO_UNICODE_STRING)GetProcAddress(hModule, "RtlAnsiStringToUnicodeString"); if(RtlAnsiStringToUnicodeStringStruct == NULL) { error_printf("Error: could not find the function RtlAnsiStringToUnicodeString in library ntdll.dll."); exit(-1); } // RtlDosPathNameToRelativeNtPathName_UStruct = (RTL_DOS_PATH_NAME_TO_RELATIVE_NT_PATH_NAME_U)GetProcAddress(hModule, "RtlDosPathNameToRelativeNtPathName_U"); // if(RtlDosPathNameToRelativeNtPathName_UStruct == NULL) { // error_printf("Error: could not find the function RtlDosPathNameToRelativeNtPathName in library ntdll.dll."); // exit(-1); // } RtlDosPathNameToNtPathName_UStruct = (RTL_DOS_PATH_NAME_TO_NT_PATH_NAME_U)GetProcAddress(hModule, "RtlDosPathNameToNtPathName_U"); if(RtlDosPathNameToNtPathName_UStruct == NULL) { error_printf("Error: could not find the function RtlDosPathNameToNtPathName in library ntdll.dll."); exit(-1); } RtlInitUnicodeStringStruct = (RTL_INIT_UNICODE_STRING)GetProcAddress(hModule, "RtlInitUnicodeString"); if(RtlInitUnicodeStringStruct == NULL) { error_printf("Error: could not find the function RtlInitUnicodeString in library ntdll.dll."); exit(-1); } RtlFreeUnicodeStringStruct = (RTL_FREE_UNICODE_STRING)GetProcAddress(hModule, "RtlFreeUnicodeString"); if(RtlFreeUnicodeStringStruct == NULL) { error_printf("Error: could not find the function RtlFreeUnicodeString in library ntdll.dll."); exit(-1); } } static HANDLE local_open_internal(FsContext *fs_ctx, const char* relative) { LocalData *data = fs_ctx->private; error_printf("Try to open %s\n", relative); if (relative[0] == '.' && relative[1] == '\0') { return data->mount_handle; } /* create the string in the right format */ //STRING filename; //ANSI_STRING filename_ANSI; UNICODE_STRING filename_UNICODE; //RtlInitStringStruct(&filename, ctx->fs_root); wchar_t filename_WIDECHAR[4096]; MultiByteToWideChar(CP_ACP, 0, relative, -1, filename_WIDECHAR, sizeof(filename_WIDECHAR)); RtlInitUnicodeStringStruct(&filename_UNICODE, filename_WIDECHAR); /* initialize OBJECT_ATTRIBUTES */ OBJECT_ATTRIBUTES obja; InitializeObjectAttributes(&obja, &filename_UNICODE, OBJ_CASE_INSENSITIVE, data->mount_handle, NULL); /* call NtOpenFile */ HANDLE file = NULL; ULONG shareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; //0; ULONG openOptions = 0; //FILE_NON_DIRECTORY_FILE; //FILE_DIRECTORY_FILE; IO_STATUS_BLOCK statusBlock; NTSTATUS stat = NtOpenFileStruct(&file, GENERIC_READ | FILE_READ_ATTRIBUTES, &obja, &statusBlock, shareAccess, openOptions); if(NT_SUCCESS(stat)) { error_printf("File successfully opened.\n"); } else { error_printf("File could not be opened: %lx.\n", stat); } RtlFreeUnicodeStringStruct(&filename_UNICODE); return file; } static int local_init(FsContext *ctx) { #ifdef FS_IOC_GETVERSION struct statfs stbuf; #endif LocalData *data = g_malloc(sizeof(*data)); local_init_ntdll(); //Main info sources: http://resources.infosecinstitute.com/calling-ntdll-functions-directly/ & https://googleprojectzero.blogspot.de/2016/02/the-definitive-guide-on-win32-to-nt.html error_printf("Try to open %s\n", ctx->fs_root); /* create the string in the right format */ //STRING filename; //ANSI_STRING filename_ANSI; UNICODE_STRING filename_UNICODE; //RtlInitStringStruct(&filename, ctx->fs_root); wchar_t filename_WIDECHAR[4096]; MultiByteToWideChar(CP_ACP, 0, ctx->fs_root, -1, filename_WIDECHAR, sizeof(filename_WIDECHAR)); RtlDosPathNameToNtPathName_UStruct(filename_WIDECHAR, &filename_UNICODE, NULL, NULL); /* initialize OBJECT_ATTRIBUTES */ OBJECT_ATTRIBUTES obja; InitializeObjectAttributes(&obja, &filename_UNICODE, OBJ_CASE_INSENSITIVE, NULL, NULL); /* call NtOpenFile */ HANDLE file = NULL; ULONG shareAccess = 0; ULONG openOptions = FILE_DIRECTORY_FILE; IO_STATUS_BLOCK statusBlock; NTSTATUS stat = NtOpenFileStruct(&file, GENERIC_READ | FILE_READ_ATTRIBUTES, &obja, &statusBlock, shareAccess, openOptions); if(NT_SUCCESS(stat)) { error_printf("File successfully opened.\n"); } else { error_printf("File could not be opened: %lx.\n", stat); goto err; } RtlFreeUnicodeStringStruct(&filename_UNICODE); // local_open_internal(file, "blah"); // local_open_internal(file, "blub.txt"); data->mount_handle = file; ctx->xops = 0; ctx->export_flags |= V9FS_PATHNAME_FSCONTEXT; ctx->private = data; return 0; err: g_free(data); return -1; }