Alexandru
Alexandru

Reputation: 12882

How to close a SYSTEM_HANDLE (or some open file handle in another process)

I am trying to create an application that closes open file handles of other processes. Aside from the fact that this causes instabilities in applications, I would like to proceed with this exercise. I have been successful in enumerating processes that have open handles or locks to particular files using this example (download link). Put simply, I am left with either a SYSTEM_HANDLE object or a duplicate of it (of type HANDLE):

SYSTEM_HANDLE handle = handleInfo->Handles[i];
HANDLE dupHandle = NULL;
if (!NT_SUCCESS(NtDuplicateObject(processHandle, (HANDLE)handle.Handle, GetCurrentProcess(), &dupHandle, 0, 0, 0)))
{
    continue;
}

I have tried closing the SYSTEM_HANDLE with no luck:

wcout << "Found " << fullPath << " in process " << process << "." << endl;
if (CloseHandle((HANDLE)handle.Handle))
{
    wcout << "Closed handle successfully." << endl;
}

The SYSTEM_HANDLE structure is defined as:

typedef struct _SYSTEM_HANDLE
{
    ULONG ProcessId;
    BYTE ObjectTypeNumber;
    BYTE Flags;
    USHORT Handle;
    PVOID Object;
    ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;

The application lies to me because it prints out "Closed handle successfully.", yet when I enumerate open handles of it again, this handle shows up. If, for example, I use an application like LockHunter to close the handle, if I enumerate it again, it does not show up. How can I close this handle?

Upvotes: 3

Views: 3668

Answers (1)

Alexandru
Alexandru

Reputation: 12882

I should have read my own link a little bit better, as wj32 clearly states:

(Step 3: Closing remote handles) To close handles opened by other processes, you simply call DuplicateHandle with DUPLICATE_CLOSE_SOURCE (1) specified in the options parameter (it's documented on the MSDN page for DuplicateHandle, so go read it). You can specify NULL for the target process handle and target handle parameters. For example:

DuplicateHandle(handleToTheRemoteProcess, theRemoteHandle, NULL, NULL, 0, FALSE, 0x1);

Although in my case, judging from the code, NtDuplicateObject should do the same trick if I pass in DUPLICATE_CLOSE_SOURCE.

Upvotes: 1

Related Questions