C# – Get all handles of a given process in 64 bits

I am trying to convert some code snippet in C++ to C# which should run on 64 bit operating system. I would like to share it to you so that if you need you can use it immediately without losing time to implement yourself. Today I would like to introduce a code snippet which return all handles of a given process and can run on 64 bits operating system. The core API of this code snippet is NtQuerySystemInformation which retrieves the specified system information. Using this code snippet I can get list of handles like following

Console.WriteLine(GetHandles(Process.GetProcessesByName("YahooMessenger")[0]).Count);

I will use NtQuerySystemInformation in loop to query handle information. NtQuerySystemInformation does not give the correct buffer size back so I guess by using a while-loop to check if it returns status of STATUS_INFO_LENGTH_MISMATCH. If not, then I have a correct buffer size and allocate my pointer with received length.

 while ((nStatus = NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ipHandlePointer, nHandleInfoSize, ref nLength)) == STATUS_INFO_LENGTH_MISMATCH)
{
	nHandleInfoSize = nLength;
	Marshal.FreeHGlobal(ipHandlePointer);
	ipHandlePointer = Marshal.AllocHGlobal(nLength);
}

The received pointer will point to memory section which has structure as following

Reading data from the pointer, I can get count of handles which are running on computer

long lHandleCount = 0;
if (Is64Bits())
{
	lHandleCount = Marshal.ReadInt64(ipHandlePointer);
	ipHandle = new IntPtr(ipHandlePointer.ToInt64() + 8);
}
else
{
	lHandleCount = Marshal.ReadInt32(ipHandlePointer);
	ipHandle = new IntPtr(ipHandlePointer.ToInt32() + 4);
}

Looping through this handles pool using the pointer and count of handles we can figure out which handle is created by given process

SYSTEM_HANDLE_INFORMATION shHandle;
List<SYSTEM_HANDLE_INFORMATION> lstHandles = new List<SYSTEM_HANDLE_INFORMATION>();

for (long lIndex = 0; lIndex < lHandleCount; lIndex++)
{
	shHandle = new SYSTEM_HANDLE_INFORMATION();
	if (Is64Bits())
	{
		shHandle = (SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
		ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle) + 8);
	}
	else
	{
		ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle));
		shHandle = (SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
	}
	if (shHandle.ProcessID != process.Id) continue;
	lstHandles.Add(shHandle);
}
return lstHandles;

You can see that the size of SYSTEM_HANDLE_INFORMATION in 64 bits OS is 8 bytes larger than 32 bits OS. Therefore I must add more 8 bytes when jumping to another handle struct. I do not know why this struct is larger in 64 bits OS. Maybe there is an undocumented field of this struct in 64 bits OS or the GrantedAccess filed has size of Int64 in 64 bits OS (not as Int32 in 32 bits OS).
The complete source code you can download here “Get all handles of given process“.

8 thoughts on “C# – Get all handles of a given process in 64 bits”

  1. @Zohaib: Sorry I don’t understand what you mean with “File” and “Process” handles. The code above will query all handles of a given process no matter which handle it is.

  2. I know this post is pretty old, but I’ve just found it and it is very useful.
    However, I don’t understand your usage of CopyMemory function – this looks like a no-op one, because the destination array is not being used anywhere in your code from the point of the copy onward.

    Thanks!

  3. @MichaelID: The CopyMemory-function ist just for Debug purpose so that I can see the real value of the pointer. It’s not necessary for the functional code

  4. Thanks! How can I tell to which process the handle is? I guess its in the Object_Pointer, but what do I do with it?

Leave a Reply

Your email address will not be published. Required fields are marked *