Here is example of source code, that closes file object handle by file name:
Code: Select all#include "stdafx.h"
UCHAR FileObjectTypeIndex = 0;
//--------------------------------------------------------------------------------------
UCHAR GetFileObjectTypeIndex(PUNICODE_STRING usSomeFileName)
{
UCHAR Ret = 0;
OBJECT_ATTRIBUTES ObjAttr;
HANDLE hFile;
IO_STATUS_BLOCK StatusBlock;
InitializeObjectAttributes(&ObjAttr, usSomeFileName, OBJ_CASE_INSENSITIVE , NULL, NULL);
// we need a handle of some file
NTSTATUS ns = ZwOpenFile(
&hFile,
FILE_READ_DATA | SYNCHRONIZE,
&ObjAttr, &StatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_SYNCHRONOUS_IO_NONALERT
);
if (NT_SUCCESS(ns))
{
// get list of all handles in system
PSYSTEM_HANDLE_INFORMATION Info = (PSYSTEM_HANDLE_INFORMATION)GetSysInf(SystemHandleInformation);
if (Info)
{
HANDLE CurrentProcessId = PsGetCurrentProcessId();
// find our handle in list
for (ULONG i = 0; i < Info->NumberOfHandles; i++)
{
if (Info->Handles[i].UniqueProcessId == (USHORT)CurrentProcessId &&
Info->Handles[i].HandleValue == (USHORT)hFile)
{
// return value of object type index (for file object)
Ret = Info->Handles[i].ObjectTypeIndex;
break;
}
}
M_FREE(Info);
}
ZwClose(hFile);
}
else
{
DbgMsg(__FILE__, __LINE__, "ZwOpenFile() fails; status: 0x%.8x\n", ns);
}
return Ret;
}
//--------------------------------------------------------------------------------------
BOOLEAN CloseFileHandlesByName(PUNICODE_STRING usFileName)
{
if (FileObjectTypeIndex == 0)
{
UNICODE_STRING usSomeFileName;
RtlInitUnicodeString(&usSomeFileName, L"\\SystemRoot\\system32\\ntdll.dll");
FileObjectTypeIndex = GetFileObjectTypeIndex(&usSomeFileName);
if (FileObjectTypeIndex == 0)
{
DbgMsg(__FILE__, __LINE__, __FUNCTION__"() ERROR: Invalid FileObjectTypeIndex\n");
return FALSE;
}
}
DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Closing all handles for '%wZ'\n", usFileName);
// get list of all handles in system
PSYSTEM_HANDLE_INFORMATION Info = (PSYSTEM_HANDLE_INFORMATION)GetSysInf(SystemHandleInformation);
if (Info)
{
for (ULONG i = 0; i < Info->NumberOfHandles; i++)
{
if (Info->Handles[i].ObjectTypeIndex == FileObjectTypeIndex)
{
PFILE_OBJECT FileObject = (PFILE_OBJECT)Info->Handles[i].Object;
// volume parameters block is not present in named pipes
// dirty trick, but working
if (FileObject->Vpb)
{
// get name of the object
POBJECT_NAME_INFORMATION NameInfo = GetObjectName(FileObject);
if (NameInfo)
{
if (RtlEqualUnicodeString(&NameInfo->Name, usFileName, TRUE))
{
DbgMsg(__FILE__, __LINE__, " ProcessId: %d, Handle: "IFMT"\n",
Info->Handles[i].UniqueProcessId, Info->Handles[i].HandleValue);
if (Info->Handles[i].UniqueProcessId == 4)
{
// don't close handles in system process
goto skip;
}
PEPROCESS Process;
// get process pointer
NTSTATUS ns = PsLookupProcessByProcessId((HANDLE)Info->Handles[i].UniqueProcessId, &Process);
if (NT_SUCCESS(ns))
{
KAPC_STATE ApcState;
// attach to a target process
KeStackAttachProcess(Process, &ApcState);
__try
{
// close handle of our file
ZwClose((HANDLE)Info->Handles[i].HandleValue);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DbgMsg(__FILE__, __LINE__, __FUNCTION__"() EXCEPTION\n");
}
KeUnstackDetachProcess(&ApcState);
ObDereferenceObject(Process);
}
else
{
DbgMsg(__FILE__, __LINE__, "PsLookupProcessByProcessId() fails; status: 0x%.8x\n", ns);
}
}
skip:
M_FREE(NameInfo);
}
}
}
}
M_FREE(Info);
return TRUE;
}
return FALSE;
}
//--------------------------------------------------------------------------------------
// EoF