internal static string GetParentProcessIdFromHandle(IntPtr handle) { if (handle == IntPtr.Zero) { return("N/A"); } ProcessBasicInformation pbi = new ProcessBasicInformation(); int returnLength = 0; uint status = Convert.ToUInt32(NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), ref returnLength)); if (status != 0) { return("NTStatus" + " " + status); } string returnValue = string.Empty; foreach (Process proc in Process.GetProcesses()) { if (proc.Id == pbi.InheritedFromUniqueProcessId.ToInt32()) { returnValue = proc.Id + " (" + proc.ProcessName + ")"; } proc.Dispose(); } return(returnValue == string.Empty ? "NOT RUNNING" : returnValue); }
static extern int NtQueryInformationProcess( IntPtr hProcess, int processInformationClass /* 0 */, ref ProcessBasicInformation processBasicInformation, uint processInformationLength, out uint returnLength );
private static extern uint NtQueryInformationProcess( [In] IntPtr ProcessHandle, [In] int ProcessInformationClass, [Out] out ProcessBasicInformation ProcessInformation, [In] int ProcessInformationLength, [Out][Optional] out int ReturnLength );
internal static IEnumerable <ProcessInfo> GetProcesses(uint[] processIds) { const int imageBufferSize = 2048; var imageBuffer = new StringBuilder(imageBufferSize); // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < processIds.Length; i++) { var processId = processIds[i]; // Obtain a process handle with only ProcessQueryLimitedInformation and ProcessVMRead access. // anything greater and the calling process must be elevated. using var processHandle = OpenProcessHandle(ProcessAccessFlags.QueryLimitedInformation | ProcessAccessFlags.VMRead, (int)processId); if (processHandle.IsInvalid) { continue; } // Keep this here as the reference pointer needs to be unique. var capacity = imageBufferSize; // Try to get the processes fully qualified executable name if (QueryFullProcessImageName(processHandle, NamePathFormat.Default, imageBuffer, ref capacity)) { var imageName = imageBuffer.ToString(); if (string.IsNullOrWhiteSpace(imageName)) { continue; } // NtQueryInformationProcess writes the requested information into this. var basicInfo = new ProcessBasicInformation(); // Retrieves a pointer to a PEB structure that can be used to determine whether the specified process is being debugged, // and a unique value used by the system to identify the specified process. var status = NtQueryInformationProcess(processHandle, 0, ref basicInfo, Marshal.SizeOf <ProcessBasicInformation>(), out _); if (status != 0) { continue; } if (!GetProcessTimes(processHandle, out var creationTime, out _, out _, out _)) { // We rely on accurate creation time to determine process relationships continue; } var commandLine = string.Empty; var workingDirectory = string.Empty; if (basicInfo.PebBaseAddress != IntPtr.Zero) { var peb = ReadProcessMemory <PEB>(processHandle, basicInfo.PebBaseAddress); if (peb is not null) { var processParameters = ReadProcessMemory <RtlUserProcessParameters>(processHandle, peb.Value.ProcessParameters); if (processParameters is not null) { commandLine = FormatCommandLine(ReadUnicodeString(processHandle, processParameters.Value.CommandLine), imageName); workingDirectory = ReadUnicodeString(processHandle, processParameters.Value.CurrentDirectory); } } } yield return(new ProcessInfo((int)processId, basicInfo.InheritedFromUniqueProcessId.ToInt32(), imageName, commandLine, workingDirectory, creationTime)); } } }
public MemoryPointer GetPebAddress() { ProcessBasicInformation pbi = new ProcessBasicInformation(); Ntdll.NtQueryInformationProcess(NativeHandle, ProcessInformationClass.ProcessBasicInformation, ref pbi, Marshal.SizeOf(pbi), out int _); return(new InternalMemoryPointer(pbi.PebBaseAddress)); }
public static int GetParentPid() { ProcessBasicInformation pbi = new ProcessBasicInformation(); int status = NtQueryInformationProcess(Process.GetCurrentProcess().Handle, 0, ref pbi, Marshal.SizeOf(pbi), out _); if (status != 0) { throw new Win32Exception(status); } return(pbi.InheritedFromUniqueProcessId.ToInt32()); }
// Reads native process info from a 64/32-bit process in the case where the target architecture // of this process is the same as that of the target process. private bool LoadProcessInfoNative(SafeProcessHandle handle, ProcessAccessFlags flags) { ProcessBasicInformation basicInfo = new ProcessBasicInformation(); int size; int status = NativeMethods.NtQueryInformationProcess( handle, ProcessInfoClass.BasicInformation, ref basicInfo, MarshalUtility.UnmanagedStructSize <ProcessBasicInformation>(), out size); _parentProcessId = basicInfo.ParentProcessId.ToInt32(); // If we can't load the ProcessBasicInfo, then we can't really do anything. if (status != NtStatus.Success || basicInfo.PebBaseAddress == IntPtr.Zero) { return(false); } if (flags.HasFlag(ProcessAccessFlags.VmRead)) { // Follows a pointer from the PROCESS_BASIC_INFORMATION structure in the target process's // address space to read the PEB. Peb peb = MarshalUtility.ReadUnmanagedStructFromProcess <Peb>( handle, basicInfo.PebBaseAddress); _isBeingDebugged = peb.IsBeingDebugged; if (peb.ProcessParameters != IntPtr.Zero) { // Follows a pointer from the PEB structure in the target process's address space to read // the RTL_USER_PROCESS_PARAMS. RtlUserProcessParameters processParameters = new RtlUserProcessParameters(); processParameters = MarshalUtility.ReadUnmanagedStructFromProcess <RtlUserProcessParameters>( handle, peb.ProcessParameters); _commandLine = MarshalUtility.ReadStringUniFromProcess( handle, processParameters.CommandLine.Buffer, processParameters.CommandLine.Length / 2); } } return(true); }
/// <summary> /// Gets the parent process of a specified process. /// </summary> /// <param name="handle">The process handle.</param> /// <returns>An instance of the Process class.</returns> public static Process GetParentProcess(IntPtr handle) { var pbi = new ProcessBasicInformation(); int returnLength; var status = _NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength); if (status != 0) { throw new Win32Exception(status); } try { return(Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32())); } catch (ArgumentException) { // not found return(null); } }
/// <summary> /// etrieves information about the specified process. /// </summary> /// <param name="processHandle">A handle to the process to query.</param> /// <returns>A <see cref="ProcessBasicInformation"/> structure containg process information.</returns> public static ProcessBasicInformation NtQueryInformationProcess(SafeMemoryHandle processHandle) { // Check if the handle is valid HandleManipulator.ValidateAsArgument(processHandle, "processHandle"); // Create a structure to store process info var info = new ProcessBasicInformation(); // Get the process info var ret = NativeMethods.NtQueryInformationProcess(processHandle, ProcessInformationClass.ProcessBasicInformation, ref info, info.Size, IntPtr.Zero); // If the function succeeded // if (ret == 0) return(info); // Else, couldn't get the process info, throws an exception throw new ApplicationException(string.Format("Couldn't get the information from the process, error code '{0}'.", ret)); }
public static Process GetParentProcess(IntPtr handle) { var pbi = new ProcessBasicInformation(); int returnLength; var status = NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength); if (status != 0) { throw new Win32Exception(status); } try { return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32()); } catch (ArgumentException) { // not found return null; } }
// Based on https://stackoverflow.com/a/3346055 public static Process GetParent(Process process) { var result = new ProcessBasicInformation(); var handle = process.Handle; var status = NtQueryInformationProcess(handle, 0, ref result, Marshal.SizeOf(result), out var returnLength); if (status != 0) { throw new Win32Exception(status); } try { var parentProcessId = result.InheritedFromUniqueProcessId.ToInt32(); return(parentProcessId > 0 ? Process.GetProcessById(parentProcessId) : null); } catch (ArgumentException) { return(null); // Process not found } }
/// <summary> /// Retrieves information about the specified process. /// </summary> /// <param name="processHandle">A handle to the process to query.</param> /// <returns>A <see cref="ProcessBasicInformation"/> structure containing process information.</returns> public static unsafe ProcessBasicInformation NtQueryInformationProcess(SafeMemoryHandle processHandle) { // Check if the handle is valid HandleManipulator.ValidateAsArgument(processHandle, "processHandle"); // Create a structure to store process info var info = new ProcessBasicInformation(); // Get the process info void *infoPtr = &info; // info is already fixed var ret = NativeMethods.NtQueryInformationProcess(processHandle, ProcessInformationClass.ProcessBasicInformation, infoPtr, new IntPtr(MarshalType <ProcessBasicInformation> .Size), out var returnLength); // If the function succeeded if (ret == 0) { return(info); } // Else, couldn't get the process info, throws an exception throw new ApplicationException($"The process information cannot be queried; error code '{ret}'."); }
/// <summary> /// Gets the parent process of the specified process /// </summary> /// <param name="process">The process of which to get the parent process</param> public static Process?GetParentProcess(this Process process) { if (process is null) { throw new ArgumentNullException(nameof(process)); } var processBasicInformation = new ProcessBasicInformation(); var status = NativeMethods.NtQueryInformationProcess(process.Handle, 0, ref processBasicInformation, Marshal.SizeOf(processBasicInformation), out _); if (status != 0) { throw new Win32Exception(status); } try { return(Process.GetProcessById(processBasicInformation.InheritedFromUniqueProcessId.ToInt32())); } catch { return(null); } }
/// <summary> /// Gets the parent process of a specified process. /// </summary> /// <param name="handle">The process handle.</param> /// <returns>An instance of the Process class or null if an error occurred.</returns> //Source: https://stackoverflow.com/questions/394816/how-to-get-parent-process-in-net-in-managed-way public static int GetParentProcess(IntPtr handle) { var pbi = new ProcessBasicInformation(); int returnLength; int status = NativeMethods.NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength); if (status != 0) { return(-1); } try { return(pbi.InheritedFromUniqueProcessId.ToInt32()); } catch (ArgumentException) { // not found return(-1); } }
/// <summary> /// 遍历杀进程 /// </summary> /// <param name="parent"></param> public static void KillProcessTree(this Process parent) { var processes = Process.GetProcesses(); foreach (var p in processes) { var pbi = new ProcessBasicInformation(); try { uint bytesWritten; if (NtQueryInformationProcess(p.Handle, 0, ref pbi, (uint)Marshal.SizeOf(pbi), out bytesWritten) == 0) // == 0 is OK { if (pbi.InheritedFromUniqueProcessId == parent.Id) { using (var newParent = Process.GetProcessById((int)pbi.UniqueProcessId)) newParent.KillProcessTree(); } } } catch { } } parent.Kill(); }
private void UnlinkNessesaryModules() { var address = LocalHook.GetProcAddress("ntdll.dll", "NtQueryInformationProcess"); var getInfo = Marshal.GetDelegateForFunctionPointer <NtQueryInformationProcessDelegate>(address); var process = Process.GetCurrentProcess(); var returnLength = 0; var pbi = new ProcessBasicInformation(); var status = getInfo(process.Handle, 0, ref pbi, (uint)Marshal.SizeOf(pbi), ref returnLength); if (status == 0) { client.DebugMessage($"PEB address: 0x{pbi.pebAddress.ToString("X")}"); var peb = Marshal.PtrToStructure <ProcessEnviromentBlock>(pbi.pebAddress); client.DebugMessage($"LDR address: 0x{peb.ldr.ToString("X")}"); var ldr = Marshal.PtrToStructure <PebLdrData>(peb.ldr); var head = ldr.InLoadOrder.next; var tmp = Marshal.PtrToStructure <LdrModule>(head); while (tmp.InLoadOrderList.next != head) { var libName = tmp.BaseDllName.GetString(); if (dllsToUnlink.Contains(libName) || libName.EndsWith(".ni.dll")) { UnlinkModule(tmp.InLoadOrderList); UnlinkModule(tmp.InMemoryOrderList); UnlinkModule(tmp.InInitialisationOrderList); } tmp = Marshal.PtrToStructure <LdrModule>(tmp.InLoadOrderList.next); } } else { client.SendMessage($"Error during NtQuery.. : 0x{(uint)status:X}"); } }
public static int ParentId(this Process process) { var pbi = new ProcessBasicInformation(); int returnLength; int status = NtQueryInformationProcess(process.Handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength); if (status != 0) throw new Exception("ParentId has failed with status: " + status); return pbi.InheritedFromUniqueProcessId.ToInt32(); }
private static extern int _NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ProcessBasicInformation processInformation, int processInformationLength, out int returnLength);
public static extern NtStatus NtQueryInformationProcess(IntPtr hProcess, int pic, ref ProcessBasicInformation pbi, int cb, out int pSize);
public static extern int NtQueryInformationProcess(SafeMemoryHandle processHandle, ProcessInformationClass infoclass, ref ProcessBasicInformation processinfo, int length, IntPtr bytesread);
public static extern Int32 NtQueryInformationProcess(IntPtr processHandle, ProcessInformationClass processInformationClass, ref ProcessBasicInformation processInformation, Int32 processInformationLength, out Int32 returnLength);
/// <summary> /// Finds the Process Environment Block address of a specified process. /// </summary> /// <param name="processHandle">A handle of the process.</param> /// <returns>A <see cref="IntPtr"/> pointer of the PEB.</returns> private IEnumerable <IntPtr> FindPebs(IntPtr processHandle) { List <IntPtr> pebs = new List <IntPtr>(); ProcessBasicInformation processBasicInformation = new ProcessBasicInformation(); Int32 sizeInfoReturned; Int32 queryStatus = NtQueryInformationProcess(processHandle, ProcessInformationClass.ProcessBasicInformation, ref processBasicInformation, processBasicInformation.Size, out sizeInfoReturned); pebs.Add(processBasicInformation.PebBaseAddress); if (Processes.Default.IsSelf64Bit() && Processes.Default.IsOpenedProcess32Bit()) { // When a 32 bit process runs on a 64 bit OS (also known as a WoW64 process), two PEB blocks are loaded. // Apparently the only solution is to navigate the TEB to find the PEB. So TODO: Port this code to C#: /* #define TEB32OFFSET 0x2000 * * void interceptNtDll32(HANDLE hProcess) * { * THREAD_BASIC_INFORMATION tbi; * NTSTATUS ntrv; * TEB32 teb32; * void *teb32addr; * PEB_LDR_DATA32 ldrData; * PEB32 peb32; * LIST_ENTRY32 *pMark = NULL; * LDR_DATA_TABLE_ENTRY32 ldrDataTblEntry; * size_t bytes_read; * HANDLE hThread = getThreadHandle(hProcess); * * /* Used to be able to get 32 bit PEB from PEB64 with 0x1000 offset but * Windows 8 changed that so we do it indirectly from the TEB * if (!hThread) * return; * * // Get thread basic information to get 64 bit TEB * ntrv = NtQueryInformationThread(hThread, ThreadBasicInformation, &tbi, sizeof(tbi), NULL); * if (ntrv != 0) * { * goto out; * } * * // Use magic to find 32 bit TEB * teb32addr = (char*)tbi.TebBaseAddress + TEB32OFFSET; // Magic... * ntrv = NtReadVirtualMemory(hProcess, teb32addr, &teb32, sizeof(teb32), NULL); * if (ntrv != 0 || teb32.NtTib.Self != (DWORD)teb32addr) * { // Verify magic... * goto out; * } * * // TEB32 has address for 32 bit PEB. * ntrv = NtReadVirtualMemory(hProcess, (void*)teb32.ProcessEnvironmentBlock, &peb32, sizeof(peb32), NULL); * if (ntrv != 0) * { * goto out; * } */ } return(pebs); }
static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ProcessBasicInformation processInformation, int processInformationLength, out int returnLength);
public static extern uint NtQueryInformationProcess(IntPtr processHandle, ProcessInformationClass processInformationClass, ref ProcessBasicInformation processInformation, int bufferSize, out int returnLength);