Ejemplo n.º 1
0
 private Dictionary <uint, ReportedProcess> GetSurvivingChildProcesses(JobObject jobObject)
 {
     if (!jobObject.TryGetProcessIds(m_loggingContext, out uint[] survivingChildProcessIds) || survivingChildProcessIds.Length == 0)
Ejemplo n.º 2
0
        private void HandleSurvivingChildProcesses(JobObject jobObject)
        {
            bool tooManySurvivingChildProcesses;

            uint[] survivingChildProcessIds;
            if (!jobObject.TryGetProcessIds(out survivingChildProcessIds, out tooManySurvivingChildProcesses) ||
                (!tooManySurvivingChildProcesses && survivingChildProcessIds.Length == 0))
            {
                // no surviving child processes reported to us
                return;
            }

            m_survivingChildProcesses = new Dictionary <uint, ReportedProcess>();
            if (tooManySurvivingChildProcesses)
            {
                m_survivingChildProcesses.Add(0, new ReportedProcess(0, "too many surviving processes"));
            }
            else
            {
                foreach (uint processId in survivingChildProcessIds)
                {
                    using (SafeProcessHandle processHandle = Native.Processes.ProcessUtilities.OpenProcess(
                               ProcessSecurityAndAccessRights.PROCESS_QUERY_INFORMATION |
                               ProcessSecurityAndAccessRights.PROCESS_VM_READ,
                               false,
                               processId))
                    {
                        if (processHandle.IsInvalid)
                        {
                            // we are too late: could not open process
                            continue;
                        }

                        if (!jobObject.ContainsProcess(processHandle))
                        {
                            // we are too late: process id got reused by another process
                            continue;
                        }

                        int exitCode;
                        if (!Native.Processes.ProcessUtilities.GetExitCodeProcess(processHandle, out exitCode))
                        {
                            // we are too late: process id got reused by another process
                            continue;
                        }

                        using (PooledObjectWrapper <StringBuilder> wrap = Pools.GetStringBuilder())
                        {
                            StringBuilder sb = wrap.Instance;
                            if (sb.Capacity < MaxProcessPathLength)
                            {
                                sb.Capacity = MaxProcessPathLength;
                            }

                            if (Native.Processes.ProcessUtilities.GetModuleFileNameEx(processHandle, IntPtr.Zero, sb, (uint)sb.Capacity) <= 0)
                            {
                                // we are probably too late
                                continue;
                            }

                            // Attempt to read the process arguments (command line) from the process
                            // memory. This is not fatal if it does not succeed.
                            string processArgs = string.Empty;

                            var  basicInfoSize = (uint)Marshal.SizeOf <Native.Processes.Windows.ProcessUtilitiesWin.PROCESS_BASIC_INFORMATION>();
                            var  basicInfoPtr  = Marshal.AllocHGlobal((int)basicInfoSize);
                            uint basicInfoReadLen;
                            try
                            {
                                if (Native.Processes.Windows.ProcessUtilitiesWin.NtQueryInformationProcess(
                                        processHandle,
                                        Native.Processes.Windows.ProcessUtilitiesWin.ProcessInformationClass.ProcessBasicInformation,
                                        basicInfoPtr, basicInfoSize, out basicInfoReadLen) == 0)
                                {
                                    Native.Processes.Windows.ProcessUtilitiesWin.PROCESS_BASIC_INFORMATION basicInformation = Marshal.PtrToStructure <Native.Processes.Windows.ProcessUtilitiesWin.PROCESS_BASIC_INFORMATION>(basicInfoPtr);
                                    Contract.Assert(basicInformation.UniqueProcessId == processId);

                                    // NativeMethods.ReadProcessStructure and NativeMethods.ReadUnicodeString handle null\zero addresses
                                    // passed into them. Since these are all value types, then there is no need to do any type
                                    // of checking as passing zero through will just result in an empty process args string.
                                    var peb = Native.Processes.Windows.ProcessUtilitiesWin.ReadProcessStructure <Native.Processes.Windows.ProcessUtilitiesWin.PEB>(processHandle, basicInformation.PebBaseAddress);
                                    var processParameters = Native.Processes.Windows.ProcessUtilitiesWin.ReadProcessStructure <Native.Processes.Windows.ProcessUtilitiesWin.RTL_USER_PROCESS_PARAMETERS>(processHandle, peb.ProcessParameters);
                                    processArgs = Native.Processes.Windows.ProcessUtilitiesWin.ReadProcessUnicodeString(processHandle, processParameters.CommandLine);
                                }
                            }
                            finally
                            {
                                Marshal.FreeHGlobal(basicInfoPtr);
                            }

                            string path = sb.ToString();
                            m_survivingChildProcesses.Add(processId, new ReportedProcess(processId, path, processArgs));
                        }
                    }
                }
            }

            if (m_survivingChildProcesses.Count > 0)
            {
                m_detouredProcess.Kill(ExitCodes.KilledSurviving);
            }
        }