I'm working in a test project where i want close a opened handle by a user mode application since that the file name in use match with file name (obtained by this opened handle).
I will enumerate here each method of my example and say what he do.
0 - ntTraverse() - list all files of a specified folder and of your subfolders.
1 - FileHandleToUNICODE_STRING() - transform a file handle to a file name without driver letter, like C:
2 - KStr_Equals() - check if two UNICODE_STRING are equals.
3 - KStr_IndexOf() - search a substring (UNICODE_STRING) in other string (also UNICODE_STRING).
4 - CloseHandlesIfMatchFileName() - try close a opened handle if match with current file name (listed by ntTraverse() method), before opened handle is
converted to filename (like said in item 1).
5 - PrintProcessesUsingFile() - show what process is using the actual listed file, and pid found is passed to CloseHandlesIfMatchFileName() when called.
PS: us parameter comes of PrintProcessesUsingFilePOA() called in ntTraverse()
Now my trouble: like title of question already says, ZwQueryInformationFile function returns STATUS_OBJECT_TYPE_MISMATCH every time when i want get the file name associated to opened handle but KeStachAttachProcess function is working fine to me.
Screenshot below shows a dll injected by Process Hacker software on notepad.exe (in this case was scanned Process Hacker root folder), obviously this generates a opened handle but like you can see ZwQueryInformationFile not was able to obtain the file name associated with this opened handle (then the error STATUS_OBJECT_TYPE_MISMATCH).
I really need know the file name of opened handle to compare and close exactly the handle matched to current file listed and in use by usermode process.
I'm leaving the complete example with source code (that can be compiled on VS 2017 + WDK with success) attached.
Here is the main logic of project:
I will enumerate here each method of my example and say what he do.
0 - ntTraverse() - list all files of a specified folder and of your subfolders.
1 - FileHandleToUNICODE_STRING() - transform a file handle to a file name without driver letter, like C:
2 - KStr_Equals() - check if two UNICODE_STRING are equals.
3 - KStr_IndexOf() - search a substring (UNICODE_STRING) in other string (also UNICODE_STRING).
4 - CloseHandlesIfMatchFileName() - try close a opened handle if match with current file name (listed by ntTraverse() method), before opened handle is
converted to filename (like said in item 1).
5 - PrintProcessesUsingFile() - show what process is using the actual listed file, and pid found is passed to CloseHandlesIfMatchFileName() when called.
PS: us parameter comes of PrintProcessesUsingFilePOA() called in ntTraverse()
Now my trouble: like title of question already says, ZwQueryInformationFile function returns STATUS_OBJECT_TYPE_MISMATCH every time when i want get the file name associated to opened handle but KeStachAttachProcess function is working fine to me.
Screenshot below shows a dll injected by Process Hacker software on notepad.exe (in this case was scanned Process Hacker root folder), obviously this generates a opened handle but like you can see ZwQueryInformationFile not was able to obtain the file name associated with this opened handle (then the error STATUS_OBJECT_TYPE_MISMATCH).
I really need know the file name of opened handle to compare and close exactly the handle matched to current file listed and in use by usermode process.
I'm leaving the complete example with source code (that can be compiled on VS 2017 + WDK with success) attached.
Here is the main logic of project:
Code: Select all
And here is the method with ZwQueryInformationFile failing.if ((Handles->UniqueProcessId == (HANDLE)id)) {
status = PsLookupProcessByProcessId(id, &process);
if (NT_SUCCESS(status))
{
RtlZeroMemory(FName.Buffer, FName.MaximumLength);
KeStackAttachProcess(process, &ks);
FileHandleToUNICODE_STRING(Handles->HandleValue, &FName);
if (KStr_IndexOf(&FName, &us, &tmpPos))
{
DbgPrint("---. FName: %wZ => Pos: %d\n", &FName, tmpPos);
/* ohfi.Inherit = 0;
ohfi.ProtectFromClose = 0;
ObSetHandleAttributes(Handles->HandleValue, &ohfi, KernelMode);
status = ZwClose(Handles->HandleValue);
DbgPrint("ZwClose() status: 0x%X", status); */
}
KeUnstackDetachProcess(&ks);
ObDereferenceObject(process);
}
}
Code: Select all
NTSTATUS FileHandleToUNICODE_STRING(IN HANDLE FileHandle, OUT PUNICODE_STRING FileName) {
PIO_STATUS_BLOCK pioStatusBlock;
PFILE_NAME_INFORMATION fniFileInfo;
NTSTATUS status;
pioStatusBlock = (PIO_STATUS_BLOCK)ExAllocatePoolWithTag(NonPagedPool, sizeof(IO_STATUS_BLOCK), 'TAG');
if (pioStatusBlock == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
DbgPrint(":Failed to allocate memory for pioStatusBlock");
return status;
}
fniFileInfo = (PFILE_NAME_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, sizeof(FILE_NAME_INFORMATION) + (MAX_PATH - 1), 'TAG');
if (fniFileInfo == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
ExFreePoolWithTag(pioStatusBlock, 'TAG');
DbgPrint(":Failed to allocate memory for fniFileInfo");
return status;
}
status = ZwQueryInformationFile(FileHandle, pioStatusBlock, fniFileInfo, (ULONG)sizeof(FILE_NAME_INFORMATION) + (MAX_PATH - 1), FileNameInformation);
if (status != STATUS_SUCCESS)
{
ExFreePoolWithTag(pioStatusBlock, 'TAG');
ExFreePoolWithTag(fniFileInfo, 'TAG');
DbgPrint("ZwQueryInformationFile() --.STATUS %x \n", status);
return status;
}
FileName->MaximumLength = fniFileInfo->FileNameLength;
FileName->Length = fniFileInfo->FileNameLength;
RtlCopyMemory(FileName->Buffer, &fniFileInfo->FileName, fniFileInfo->FileNameLength);
ExFreePoolWithTag(pioStatusBlock, 'TAG');
ExFreePoolWithTag(fniFileInfo, 'TAG');
status = STATUS_SUCCESS;
return status;
}
Attachments
Driver.c and ntapi.h
(17.22 KiB) Downloaded 2 times
(17.22 KiB) Downloaded 2 times
0xC0000024.png (282.72 KiB) Viewed 201 times