diff --git a/hook_file.c b/hook_file.c index 02d37c3..7c83afb 100644 --- a/hook_file.c +++ b/hook_file.c @@ -185,7 +185,7 @@ HOOKDEF(NTSTATUS, WINAPI, NtReadFile, path_from_handle(FileHandle, fname, 32768); LOQ_ntstatus("filesystem", "pFbl", "FileHandle", FileHandle, - "FileName", fname, "Buffer", IoStatusBlock->Information, Buffer, "Length", IoStatusBlock->Information); + "HandleName", fname, "Buffer", IoStatusBlock->Information, Buffer, "Length", IoStatusBlock->Information); free(fname); @@ -210,7 +210,7 @@ HOOKDEF(NTSTATUS, WINAPI, NtWriteFile, path_from_handle(FileHandle, fname, 32768); LOQ_ntstatus("filesystem", "pFbl", "FileHandle", FileHandle, - "FileName", fname, "Buffer", IoStatusBlock->Information, Buffer, "Length", IoStatusBlock->Information); + "HandleName", fname, "Buffer", IoStatusBlock->Information, Buffer, "Length", IoStatusBlock->Information); free(fname); diff --git a/misc.c b/misc.c index e9b2fcf..6de2beb 100644 --- a/misc.c +++ b/misc.c @@ -256,78 +256,40 @@ void hide_module_from_peb(HMODULE module_handle) uint32_t path_from_handle(HANDLE handle, wchar_t *path, uint32_t path_buffer_len) { - IO_STATUS_BLOCK status; - FILE_FS_VOLUME_INFORMATION volume_information; - unsigned char *buf; - FILE_NAME_INFORMATION *name_information; - unsigned long serial_number; - - static NTSTATUS(WINAPI *pNtQueryVolumeInformationFile)( - _In_ HANDLE FileHandle, - _Out_ PIO_STATUS_BLOCK IoStatusBlock, - _Out_ PVOID FsInformation, - _In_ ULONG Length, - _In_ FS_INFORMATION_CLASS FsInformationClass - ); - - static NTSTATUS(WINAPI *pNtQueryInformationFile)( - _In_ HANDLE FileHandle, - _Out_ PIO_STATUS_BLOCK IoStatusBlock, - _Out_ PVOID FileInformation, - _In_ ULONG Length, - _In_ FILE_INFORMATION_CLASS FileInformationClass + POBJECT_NAME_INFORMATION resolvedName; + ULONG returnLength; + NTSTATUS status; + uint32_t length = 0; + + static NTSTATUS(WINAPI *pNtQueryObject)( + _In_opt_ HANDLE Handle, + _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, + _Out_opt_ PVOID ObjectInformation, + _In_ ULONG ObjectInformationLength, + _Out_opt_ PULONG ReturnLength ); - if (pNtQueryVolumeInformationFile == NULL) { - *(FARPROC *) &pNtQueryVolumeInformationFile = GetProcAddress( - GetModuleHandle("ntdll"), "NtQueryVolumeInformationFile"); - } - - if(pNtQueryInformationFile == NULL) { - *(FARPROC *) &pNtQueryInformationFile = GetProcAddress( - GetModuleHandle("ntdll"), "NtQueryInformationFile"); - } - - memset(&status, 0, sizeof(status)); - - // get the volume serial number of the directory handle - if(NT_SUCCESS(pNtQueryVolumeInformationFile(handle, &status, - &volume_information, sizeof(volume_information), - FileFsVolumeInformation)) == 0) { - return 0; + if (pNtQueryObject == NULL) { + *(FARPROC *) &pNtQueryObject = GetProcAddress( + GetModuleHandle("ntdll"), "NtQueryObject"); } - // enumerate all harddisks in order to find the - // corresponding serial number - wcscpy(path, L"?:\\"); - for (path[0] = L'A'; path[0] <= L'Z'; path[0]++) { - if (GetVolumeInformationW(path, NULL, 0, &serial_number, NULL, - NULL, NULL, 0) == 0 || - serial_number != volume_information.VolumeSerialNumber) { - continue; - } + resolvedName = (POBJECT_NAME_INFORMATION)calloc(1, OBJECT_NAME_INFORMATION_REQUIRED_SIZE); - buf = calloc(1, FILE_NAME_INFORMATION_REQUIRED_SIZE); - name_information = (FILE_NAME_INFORMATION *)buf; - - // obtain the relative path for this filename on the given harddisk - if (NT_SUCCESS(pNtQueryInformationFile(handle, &status, - name_information, FILE_NAME_INFORMATION_REQUIRED_SIZE, - FileNameInformation))) - { - uint32_t length = min(name_information->FileNameLength / sizeof(wchar_t), path_buffer_len - 3); - // NtQueryInformationFile omits the "C:" part in a - // filename, apparently - memcpy(path + 2, name_information->FileName, length * sizeof(wchar_t)); - free(buf); - return length + 2; - } else - free(buf); + status = pNtQueryObject(handle, ObjectNameInformation, + resolvedName, OBJECT_NAME_INFORMATION_REQUIRED_SIZE, &returnLength); - break; + if (NT_SUCCESS(status)) { + length = min(resolvedName->Name.Length / sizeof(wchar_t), path_buffer_len - 1); + // NtQueryInformationFile omits the "C:" part in a + // filename, apparently + memcpy(path, resolvedName->NameBuffer, length * sizeof(wchar_t)); } + if (path_buffer_len) + path[length] = L'\0'; - return 0; + free(resolvedName); + return length; } uint32_t path_from_object_attributes(const OBJECT_ATTRIBUTES *obj, @@ -524,6 +486,8 @@ wchar_t *ensure_absolute_unicode_path(wchar_t *out, const wchar_t *in) free(tmpout); if (nonexistent) free(nonexistent); + if (out[1] == L':' && out[2] == L'\\') + out[0] = toupper(out[0]); return out; globalroot_copy: diff --git a/ntapi.h b/ntapi.h index 4195391..763de81 100644 --- a/ntapi.h +++ b/ntapi.h @@ -468,6 +468,22 @@ typedef struct _KEY_NAME_INFORMATION { WCHAR KeyName[1]; } KEY_NAME_INFORMATION, *PKEY_NAME_INFORMATION; +typedef struct _OBJECT_NAME_INFORMATION { + UNICODE_STRING Name; + WCHAR NameBuffer[1]; +} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; + +#define OBJECT_NAME_INFORMATION_REQUIRED_SIZE \ + sizeof(OBJECT_NAME_INFORMATION) + sizeof(wchar_t) * 32768 + +typedef enum { + ObjectBasicInformation, + ObjectNameInformation, + ObjectTypeInformation, + ObjectAllInformation, + ObjectDataInformation +} OBJECT_INFORMATION_CLASS; + typedef enum { FileFsVolumeInformation = 1, FileFsLabelInformation = 2,