// 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); }