Skip to content

Commit

Permalink
Change arg names for the resolved handle names to "HandleName". Compl…
Browse files Browse the repository at this point in the history
…etely rewrite path_from_handle since we already handle rewriting of \device\harddiskX\* names. This new method is more efficient and can be used for more object types that the NtQueryInformationFile implementation could not handle.
  • Loading branch information
brad-sp committed Nov 10, 2014
1 parent 57bc521 commit fa160df
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 66 deletions.
4 changes: 2 additions & 2 deletions hook_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);

Expand Down
92 changes: 28 additions & 64 deletions misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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:
Expand Down
16 changes: 16 additions & 0 deletions ntapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit fa160df

Please sign in to comment.