I'm trying to query all the handles in the current process. For that, first I'm trying to call NtQueryInformationProcess, which after 2 consecutive calls ends up throwing a STATUS_ACCESS_VIOLATION (0xC0000005) error code.
My c# code is as follows:
public class Main
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PROCESS_HANDLE_INFORMATION
{ // ProcessInfoClass 0x33
public IntPtr Handle;
public IntPtr HandleCount;
public IntPtr PointerCount;
public ulong GrantedAccess;
public ulong ObjectTypeIndex;
public ulong HandleAttributes;
public ulong Reserved;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PROCESS_HANDLE_SNAPSHOT_INFORMATION
{ // ProcessInfoClass 0x33
public ulong NumberOfHandles;
public ulong Reserved;
public IntPtr Handles;
}
[DllImport("kernel32.dll")]
public static extern IntPtr GetCurrentProcess();
[DllImport("ntdll.dll", SetLastError = true)]
public static extern int NtQueryInformationProcess(IntPtr processHandle, uint processInformationClass, ref IntPtr processInformation, int processInformationLength, ref int returnLength);
[DllImport("ntdll.dll", SetLastError = true)]
public static extern void RtlZeroMemory(IntPtr Destination, int length);
private const uint CNST_PROCESS_HANDLE_INFORMATION = 0x33;
public static void doThings()
{
unsafe
{
int handle_info_size = 0;
int nLength = 0;
IntPtr ptrHandleData = IntPtr.Zero;
try
{
int status = NtQueryInformationProcess(GetCurrentProcess(), CNST_PROCESS_HANDLE_INFORMATION, ref ptrHandleData, handle_info_size, ref nLength);
while (status != 0)
{
handle_info_size = nLength;
Marshal.FreeHGlobal(ptrHandleData);
ptrHandleData = Marshal.AllocHGlobal(nLength);
RtlZeroMemory(ptrHandleData, nLength);
status = NtQueryInformationProcess(GetCurrentProcess(), CNST_PROCESS_HANDLE_INFORMATION, ref ptrHandleData, handle_info_size, ref nLength);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Marshal.FreeHGlobal(ptrHandleData);
}
}
}
}
The first two times I call NtQueryInformationProcess it returns STATUS_INFO_LENGTH_MISMATCH (0xC0000004), which seems fine since first you need to figure out the required buffer length. After those two calls, I guess I have finally obtained the right buffer length but from there it only throws STATUS_ACCESS_VIOLATION errors and the handles information is never successfully retrieved.