Call to NtQueryInformationProcess returns STATUS_ACCESS_VIOLATION error

681 Views Asked by At

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.

0

There are 0 best solutions below