Exemple #1
0
        /// <summary>
        /// Process the event, this is where most of the work for the debugger is done at run time.
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        private WinAPI.ContinueStatus ProcessEvent(Debug_Event e)
        {
            switch (e.Code)
            {
                case EventCode.CREATE_PROCESS_DEBUG_INFO:
                    return this.HandleCreateProcess(e);
                case EventCode.CREATE_THREAD_DEBUG_INFO:
                    return this.HandleThreadCreation(e);
                case EventCode.EXCEPTION_DEBUG_INFO:
                    return this.HandleExceptions(e);
                case EventCode.EXIT_PROCESS_DEBUG_INFO:
                    return this.HandleProcessExit(e);
                case EventCode.EXIT_THREAD_DEBUG_INFO:
                    return this.HandleExitThread(e);
                case EventCode.LOAD_DLL_DEBUG_INFO:
                    return HandleLoadDLL(e);
                case EventCode.UNLOAD_DLL_DEBUG_INFO:
                    return this.HandleUnloadDLL(e);
                case EventCode.RIP_INFO:
                    return this.HandleRIP(e);
                case EventCode.OUTPUT_DEBUG_STRING_INFO:
                    return this.HandleOutputString(e);
            }

            return WinAPI.ContinueStatus.DBG_CONTINUE;
        }
Exemple #2
0
 /// <summary>
 /// Performs any actions necessary when a DLL is unloaded
 /// </summary>
 /// <param name="e"></param>
 /// <returns></returns>
 private WinAPI.ContinueStatus HandleUnloadDLL(Debug_Event e)
 {
     return WinAPI.ContinueStatus.DBG_CONTINUE;
 }
Exemple #3
0
        /// <summary>
        /// The main loop of the debugger, waits for events and processes actions accordingly.
        /// </summary>
        private void MainDebuggerLoop()
        {
            while (true)
            {
                if (this.enterTerminateSequence)
                {
                    if (!WinAPI.DebugActiveProcessStop((uint)this.debuggee.Id))
                        throw new Exception("Error 0x" + WinAPI.GetLastError().ToString("X") + " - " + Enum.GetName(typeof(WinAPI.SYSTEM_ERROR_CODE), WinAPI.GetLastError()) + " - when detatching from process");

                    try
                    {
                        this.debuggee.Kill();  // XP seems to be choking on this.  Errors out with permission denied, then the same call throws an exception that the process is already dead.
                        // Adding a check to see if the process has exited yet before calling this did not seem to fix it.  best fix so far is an empty try/catch, sloppy but it worked

                        if (this.settings.EnableKillAlso) // Allows the debugger to kill other processes when it kills the debugee
                        {
                            Process[] processes = Process.GetProcessesByName(this.settings.KillAlso);

                            if (processes.Length > 0)
                            {
                                foreach (Process p in processes)
                                {
                                    if (p != this.debuggee)
                                    {
                                        if (!p.HasExited)
                                        {
                                            p.Kill();
                                        }
                                    }
                                }
                            }
                        }

                        this.debuggee.WaitForExit();
                    }
                    catch (Exception e)
                    {
                        try
                        {
                            if (!this.debuggee.HasExited)
                                throw new Exception("Error - Debuggee Never Exited.  " + e.Message);
                        }
                        catch (Exception exception)
                        {
                            if (!(exception is InvalidOperationException) && !(exception.Message == "There is no process associated with the object"))
                                throw exception;
                        }
                    }
                    finally
                    {
                        this.enterTerminateSequence = false;
                    }

                    return;
                }

                if (this.WindowThread == null) // Allows us to only have one thread cleaning windows at a time.
                {
                    this.WindowThread = new Thread(this.CheckWindows);
                    this.WindowThread.Start();
                }

                Debug_Event Event = new Debug_Event();
                if (!WinAPI.WaitForDebugEvent(out Event, 0))
                    if (WinAPI.GetLastError() == 121) // Error 121 is a timeout error, since we are not pausing at all for events.  We don't pause so that we can continue to launch threads to check windows.
                        continue;
                    else
                        throw new DebuggerException("Error 0x" + WinAPI.GetLastError().ToString("X") + " - " + Enum.GetName(typeof(WinAPI.SYSTEM_ERROR_CODE), WinAPI.GetLastError()) + " - while waiting for debug event");

                this.lastEvent = DateTime.Now.Millisecond;

                WinAPI.ContinueStatus action = this.ProcessEvent(Event);

                if (!WinAPI.ContinueDebugEvent(Event.ProcessID, Event.ThreadID, action))
                    throw new DebuggerException("Error 0x" + WinAPI.GetLastError().ToString("X") + " - " + Enum.GetName(typeof(WinAPI.SYSTEM_ERROR_CODE), WinAPI.GetLastError()) + " - while attempting to continue a debug event.");
            }
        }
Exemple #4
0
        /// <summary>
        /// Performs any actions necessary when the debuggee exits a process
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        private WinAPI.ContinueStatus HandleProcessExit(Debug_Event e)
        {
            if (this.debuggee.Id == e.ProcessID)
            {
                if (this.settings.ErrorCodes.Contains((ErrorCode)e.u.ExitProcess.ExitCode))
                {
                    this.ErrorInformation.Append("***PROCESS EXIT WITH WATCHED CODE***" + "\r\n");
                }
                else
                {
                    this.ErrorInformation.Append("PROCESS EXIT" + "\r\n");
                }
            }
            else
            {
                this.ErrorInformation.Append("SPAWNED PROCESS EXIT" + "\r\n");
            }

            this.ErrorInformation.Append("=============================================" + "\r\n");
            this.ErrorInformation.Append("Process: " + e.ProcessID + "\r\n");
            this.ErrorInformation.Append("Thread: " + e.ThreadID + "\r\n");
            this.ErrorInformation.Append("Error: " + Enum.GetName(typeof(ErrorCode), e.u.ExitProcess.ExitCode) + " - " + e.u.ExitProcess.ExitCode.ToString("X") + "\r\n");
            this.ErrorInformation.Append("\r\n" + this.GetRegisterContext(e.ThreadID) + "\r\n");

            this.ErrorInformation.Append("\r\n\r\n" + "\r\n");

            if (this.debuggee.Id == e.ProcessID)
            {
                this.debuggee.Kill();
                this.debuggee.WaitForExit();
            }

            return WinAPI.ContinueStatus.DBG_CONTINUE;
        }
Exemple #5
0
 /// <summary>
 /// Performs any actions necessary when the debuggee creates a thread
 /// </summary>
 /// <param name="e"></param>
 /// <returns></returns>
 private WinAPI.ContinueStatus HandleThreadCreation(Debug_Event e)
 {
     return WinAPI.ContinueStatus.DBG_CONTINUE;
 }
Exemple #6
0
 /// <summary>
 /// Performs any actions necessary when an output string is encountered.
 /// </summary>
 /// <param name="e"></param>
 /// <returns></returns>
 private WinAPI.ContinueStatus HandleOutputString(Debug_Event e)
 {
     // This function doesn't much matter because strings and Debug_Event in C# doesn't seem to get along very well, should probably look into that.  Probably around the same time I start caring about debug strings.
     return WinAPI.ContinueStatus.DBG_CONTINUE;
 }
Exemple #7
0
 /// <summary>
 /// Performs any actions necessary when a DLL is loaded
 /// </summary>
 /// <param name="e"></param>
 /// <returns></returns>
 private WinAPI.ContinueStatus HandleLoadDLL(Debug_Event e)
 {
     if (!WinAPI.CloseHandle(e.u.LoadDll.File))
         throw new Exception("Error closing file handle during dll load");
     return WinAPI.ContinueStatus.DBG_CONTINUE;
 }
Exemple #8
0
 /// <summary>
 /// Performs any actions necessary when a thread exits
 /// </summary>
 /// <param name="e"></param>
 /// <returns></returns>
 private WinAPI.ContinueStatus HandleExitThread(Debug_Event e)
 {
     return WinAPI.ContinueStatus.DBG_CONTINUE;
 }
Exemple #9
0
        /// <summary>
        /// Performs any actions necessary when the debuggee raises an exception
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        private WinAPI.ContinueStatus HandleExceptions(Debug_Event e)
        {
            // Handle the breakpoint exception at startup, this is where we hide the debugger if necessary
            if ((ErrorCode)e.u.Exception.ExceptionRecord.ExceptionCode == ErrorCode.STATUS_BREAKPOINT && !this.doneStarting)
            {
                this.doneStarting = true;

                if (this.settings.HideDebugger)
                {
                    WinAPI.BasicProcessInformation ProcessInformation = new WinAPI.BasicProcessInformation();
                    int returnLength;
                    WinAPI.SYSTEM_ERROR_CODE code = WinAPI.NtQueryInformationProcess(this.debuggee.Handle, 0x00, ref ProcessInformation, (uint)Marshal.SizeOf(ProcessInformation), out returnLength);
                    if (code != 0)
                        throw new DebuggerException("Error 0x" + WinAPI.GetLastError().ToString("X") + " - " + Enum.GetName(typeof(WinAPI.SYSTEM_ERROR_CODE), WinAPI.GetLastError()) + " - while getting PEB address. - 0x" + code.ToString("X") + " - " + Enum.GetName(typeof(ErrorCode), code));

                    byte[] DebuggerPresent = new Byte[1];

                    int Length;

                    DebuggerPresent[0] = 0;
                    WinAPI.WriteProcessMemory(this.debuggee.Handle, ProcessInformation.PebBaseAddress + 2, DebuggerPresent, 1, out Length);
                }

                return WinAPI.ContinueStatus.DBG_CONTINUE;
            }

            this.ErrorInformation.Append("EXCEPTION" + "\r\n");
            this.ErrorInformation.Append("=============================================" + "\r\n");
            this.ErrorInformation.Append("Process: " + e.ProcessID + "\r\n");
            this.ErrorInformation.Append("Thread: " + e.ThreadID + "\r\n");
            this.ErrorInformation.Append("Error: " + Enum.GetName(typeof(ErrorCode), e.u.Exception.ExceptionRecord.ExceptionCode) + " - " + e.u.Exception.ExceptionRecord.ExceptionCode.ToString("X") + "\r\n");
            this.ErrorInformation.Append("\r\n" + this.GetRegisterContext(e.ThreadID) + "\r\n");
            this.ErrorInformation.Append("\r\n\r\n" + "\r\n");

            return WinAPI.ContinueStatus.DBG_EXCEPTION_NOT_HANDLED;
        }
Exemple #10
0
        /// <summary>
        /// Performs any actions necessary when a process is created.
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        private WinAPI.ContinueStatus HandleCreateProcess(Debug_Event e)
        {
            if (!WinAPI.CloseHandle(e.u.CreateProcessInfo.File))
                throw new Exception("Error closing file handle in create process event");

            return WinAPI.ContinueStatus.DBG_CONTINUE;
        }