/// <summary> /// Reads the Thread Basic Information (TBI) struct of a process. /// </summary> /// <param name="process">The process to read.</param> /// <returns>Returns a 32 bit Thread Basic Information (TBI) struct equivalent.</returns> public static PInvokeStuff.THREAD_BASIC_INFORMATION GetTBI(Process process) { IntPtr hThread = PInvokeStuff.OpenThread(PInvokeStuff.ThreadAccess.QueryInformation, false, (uint)process.Threads.OfType <ProcessThread>().First().Id); if (hThread == null) // Some implementations on StackExchange compare against IntPtr.zero - but MSDN says it returns null, not null pointer { throw new Exceptions.PInvokeException(nameof(GetTBI), nameof(PInvokeStuff.OpenThread), Marshal.GetLastWin32Error()); } try { PInvokeStuff.THREAD_BASIC_INFORMATION tbi = new PInvokeStuff.THREAD_BASIC_INFORMATION(); int result = PInvokeStuff.NtQueryInformationThread(hThread, PInvokeStuff.ThreadInfoClass.ThreadBasicInformation, out tbi, (uint)Marshal.SizeOf(tbi)); // NtQueryInformationThread returns nonzero (NTSTATUS) if failed if (result != 0) { throw new Exceptions.PInvokeException(nameof(GetTBI), nameof(PInvokeStuff.NtQueryInformationThread), result); } return(tbi); } finally { PInvokeStuff.CloseHandle(hThread); } }
/// <summary> /// Reads the NT_TIB area of a process, into an incomplete 32 bit representation of the original struct. /// </summary> /// <param name="process">The process to read.</param> /// <returns>Returns an incomplete 32 bit representation of NT_TIB.</returns> public static PInvokeStuff.NT_TIB GetTIB(Process process) { // Read TBI - prerequise for TIB PInvokeStuff.THREAD_BASIC_INFORMATION tbi = GetTBI(process); // Read NT_TIB equivalent memory area of the process directly into our NT_TIB struct PInvokeStuff.NT_TIB tib = ReadToType <PInvokeStuff.NT_TIB>(process.Handle, tbi.TebBaseAddress); return(tib); }