示例#1
0
        public DebuggerEventArgs(
            IntPtr processHandle,
            byte[] faultingInstructions,
            string instructionHash,
            DEBUG_EVENT debugEvent,
            ProcessMemory memory
#if FULL_DBG
            ,
            BreakpointManager breakpoints,
            HookManager hooks
#endif
            )
        {
            ProcessHandle        = processHandle;
            FaultingInstructions = faultingInstructions;
            InstructionHash      = instructionHash;
            DebugEvent           = debugEvent;
            Memory = memory;
#if FULL_DBG
            Breakpoints = breakpoints;
            Hooks       = hooks;
#endif
        }
示例#2
0
        public void ProcessDebugEvents()
        {
            IsStarted = true;
            var debugEvent = new DEBUG_EVENT();

            while (!_killProcesses && IsStarted && Processes.Count != 0)
            {
                if (!Kernel32.WaitForDebugEvent(ref debugEvent, 200))
                {
                    var error = Marshal.GetLastWin32Error();

                    //if (error == 121 || _killProcesses)

                    /*if (_killProcesses)
                     * {
                     *  KillCore();
                     *  break;
                     * }
                     * else */if (error != 121)
                    {
                        throw new Win32Exception(error);
                    }

                    if (Timeout > 0 &&
                        (DateTime.Now - StartTime).TotalMilliseconds > Timeout)
                    {
                        Kill();

                        return;
                    }

                    continue;
                }

                Process p = null;

                LockProcesses(() =>
                {
                    if (_processTable.ContainsKey(debugEvent.dwProcessId))
                    {
                        p = _processTable[debugEvent.dwProcessId];
                    }
                });

                byte[] buffer = null;
                var    hash   = "[NO HASH]";

                switch (debugEvent.dwDebugEventCode)
                {
                case DebugEventType.CREATE_PROCESS_DEBUG_EVENT:
                    if (p != null)
                    {
                        var mem = new ProcessMemory(p.Handle);
                        lock (_readers)
                        {
                            _readers.Add(p.Handle, mem);
                        }

#if FULL_DBG
                        if (!_hookManagers.ContainsKey(p.Handle))
                        {
                            _hookManagers.Add(p.Handle, new HookManager(mem));
                            _breakpointManagers.Add(p.Handle, new BreakpointManager(mem));
                        }
#endif
                    }
                    lock (_loaderBreakpointTable)
                    {
                        if (!_loaderBreakpointTable.ContainsKey(debugEvent.dwProcessId))
                        {
                            _loaderBreakpointTable.Add(debugEvent.dwProcessId, false);
                        }
                    }
                    LockProcesses(() =>
                    {
                        AddProcess(debugEvent.dwProcessId);
                        p = _processTable[debugEvent.dwProcessId];
                    });
                    Kernel32.CloseHandle(debugEvent.CreateProcessInfo.hFile);
                    break;

                case DebugEventType.EXIT_PROCESS_DEBUG_EVENT:
                    lock (_loaderBreakpointTable)
                    {
                        if (_loaderBreakpointTable.ContainsKey(debugEvent.dwProcessId))
                        {
                            _loaderBreakpointTable.Remove(debugEvent.dwProcessId);
                        }
                    }

                    LockProcesses(() => RemoveProcess(debugEvent.dwProcessId));

                    if (p != null)
                    {
                        lock (_readers)
                        {
                            try
                            {
                                // Swallow exceptions caused by accessing Process.Handle after
                                // process has exited.
                                _readers.Remove(p.Handle);
                            }
                            catch { }
                        }
                    }
                    break;

                case DebugEventType.LOAD_DLL_DEBUG_EVENT:
                    Kernel32.CloseHandle(debugEvent.LoadDll.hFile);
                    break;

                case DebugEventType.EXCEPTION_DEBUG_EVENT:
                    lock (_loaderBreakpointTable)
                    {
                        if (debugEvent.Exception.ExceptionRecord.ExceptionCode == ExceptionCode.EXCEPTION_BREAKPOINT)
                        {
                            if (!_loaderBreakpointTable.ContainsKey(debugEvent.dwProcessId))
                            {
                                _loaderBreakpointTable.Add(debugEvent.dwProcessId, false);
                            }

                            if (!_loaderBreakpointTable[debugEvent.dwProcessId])
                            {
                                _loaderBreakpointTable[debugEvent.dwProcessId] = true;

                                debugEvent.ContinueUnhandled();
                                continue;
                            }
                        }
                    }

                    if (p != null)
                    {
                        if (HashException)
                        {
                            hash = GetExceptionHash(p, debugEvent);
                        }

                        if (ReadFaultingInstructions)
                        {
                            buffer = new byte[32];
                            var exPtr = IntPtr.Zero;

                            try
                            {
                                exPtr = (IntPtr)debugEvent.Exception.ExceptionRecord.ExceptionAddress;
                            }
                            catch (OverflowException)
                            {
                            }

                            if (Kernel32.ReadProcessMemory(
                                    p.Handle,
                                    exPtr,
                                    buffer,
                                    new IntPtr(buffer.Length),
                                    out var bytesRead))
                            {
                                if (bytesRead < buffer.Length)
                                {
                                    Array.Resize(ref buffer, bytesRead);
                                }
                            }
                            else
                            {
                                buffer = null;
                            }

                            //hash = CreateInstructionHash(buffer.Take(HashSize));
                        }
                    }
                    //elser
                    //{
                    //    throw new InvalidOperationException();
                    //}

                    break;
                }

                if (DebugEventReceived != null)
                {
                    IntPtr handle;
                    try
                    {
                        handle = p != null ? p.Handle : IntPtr.Zero;
                    }
                    catch
                    {
                        handle = IntPtr.Zero;
                    }

#if FULL_DBG
                    if (!_breakpointManagers.TryGetValue(handle, out var breakpoints))
                    {
                        _breakpointManagers.Add(handle, breakpoints = new BreakpointManager(GetMemory(handle)));
                    }

                    if (!_hookManagers.TryGetValue(handle, out var hooks))
                    {
                        _hookManagers.Add(handle, hooks = new HookManager(GetMemory(handle)));
                    }
#endif
                    DebugEventReceived(this,
                                       new DebuggerEventArgs(
                                           handle,
                                           buffer,
                                           hash,
                                           debugEvent,
                                           GetMemory(handle)
#if FULL_DBG
                                           ,
                                           breakpoints,
                                           hooks
#endif
                                           ));
                }

                if (Timeout > 0 &&
                    (DateTime.Now - StartTime).TotalMilliseconds > Timeout)
                {
                    Kill();

                    return;
                }
            }

            //KillCore();
        }