Example #1
0
        public void RunThreaded()
        {
            WinDebug.DEBUG_EVENT DbgEvt = new WinDebug.DEBUG_EVENT();
            ContinueStatus = WinDebug.CONTINUE_STATUS.DBG_CONTINUE;

            foreach (IDebuggerGeneralEvents Event in GeneralEvents)
            {
                Event.OnDebugStart();
            }

            // Loop until told to stop
            while (bContinue == true)
            {
                // Pause until a debug event notification happens
                bContinue = WinDebug.NativeMethods.WaitForDebugEvent(out DbgEvt, VsChromium.Core.Win32.Constants.INFINITE);

                switch (DbgEvt.dwDebugEventCode)
                {
                case WinDebug.DEBUG_EVENT_CODE.EXCEPTION_DEBUG_EVENT:
                    HandleException(DbgEvt);
                    break;

                case WinDebug.DEBUG_EVENT_CODE.CREATE_THREAD_DEBUG_EVENT:
                    HandleCreateThread(DbgEvt);
                    break;

                case WinDebug.DEBUG_EVENT_CODE.CREATE_PROCESS_DEBUG_EVENT:
                    HandleCreateProcess(DbgEvt);
                    break;

                case WinDebug.DEBUG_EVENT_CODE.EXIT_THREAD_DEBUG_EVENT:
                    HandleExitThread(DbgEvt);
                    break;

                case WinDebug.DEBUG_EVENT_CODE.EXIT_PROCESS_DEBUG_EVENT:
                    HandleExitProcess(DbgEvt);

                    // XX Temporary
                    bContinue = false;
                    break;

                case WinDebug.DEBUG_EVENT_CODE.LOAD_DLL_DEBUG_EVENT:
                    HandleLoadDll(DbgEvt);
                    break;

                case WinDebug.DEBUG_EVENT_CODE.UNLOAD_DLL_DEBUG_EVENT:
                    HandleUnloadDll(DbgEvt);
                    break;

                case WinDebug.DEBUG_EVENT_CODE.OUTPUT_DEBUG_STRING_EVENT:
                    HandleOutputDebugString(DbgEvt);
                    break;

                case WinDebug.DEBUG_EVENT_CODE.RIP_EVENT:
                    // TODO: Handle
                    break;
                }

                // TODO: Stop doing this once we raise an exception
                WinDebug.NativeMethods.ContinueDebugEvent(DbgEvt.dwProcessId, DbgEvt.dwThreadId, ContinueStatus);
                ContinueStatus = WinDebug.CONTINUE_STATUS.DBG_CONTINUE;
            }

            State = RunState.Ended;

            foreach (IDebuggerGeneralEvents Event in GeneralEvents)
            {
                Event.OnDebugEnd();
            }
        }
Example #2
0
        private void HandleException(WinDebug.DEBUG_EVENT DebugEvent)
        {
            var DebugInfo = DebugEvent.Exception;

            switch ((ExceptionCode)DebugInfo.ExceptionRecord.ExceptionCode)
            {
            case ExceptionCode.AccessViolation:
            {
                // Ignore all access violation errors.

                // This will fallback to the debugee (Cxbx) and the exception handling routine.
                // Should they be unsupported, the debugger "OVERRIDE_EXCEPTION" message is thrown
                // which means the exception is usually fatal

                ContinueStatus = WinDebug.CONTINUE_STATUS.DBG_EXCEPTION_NOT_HANDLED;
            }
            break;

            case (ExceptionCode)DebuggerMessages.ReportType.OVERRIDE_EXCEPTION:
            {
                var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
                if (Thread != null)
                {
                    var Query = DebuggerMessages.GetExceptionHandledQuery(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);

                    bool Handled = false;
                    foreach (IDebuggerExceptionEvents Event in ExceptionEvents)
                    {
                        Handled |= Event.OnAccessViolation(Thread, Query.ExceptionCode, Query.ExceptionAddress);
                    }

                    // Write the reponse to memory
                    Thread.OwningProcess.WriteMemory(Query.ReponseAddr, Handled);
                }
            }
            break;

            case (ExceptionCode)DebuggerMessages.ReportType.HLECACHE_FILE:
            {
                var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
                if (Thread != null)
                {
                    var Report = DebuggerMessages.GetHLECacheReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
                    SetupHLECacheProvider(Report.FileName);
                }
            }
            break;

            case (ExceptionCode)DebuggerMessages.ReportType.KERNEL_PATCH:
            {
                var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
                if (Thread != null)
                {
                    var Report = DebuggerMessages.GetKernelPatchReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);

                    KernelSymbolProvider.AddKernelSymbolFromMessage(Report);
                }
            }
            break;

            case (ExceptionCode)DebuggerMessages.ReportType.FILE_OPENED:
            {
                var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
                if (Thread != null)
                {
                    var Report = DebuggerMessages.GetFileOpenedReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);

                    foreach (IDebuggerFileEvents Event in FileEvents)
                    {
                        Event.OnFileOpened(Report);
                    }
                }
            }
            break;

            case (ExceptionCode)DebuggerMessages.ReportType.FILE_READ:
            {
                var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
                if (Thread != null)
                {
                    var Report = DebuggerMessages.GetFileReadReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);

                    foreach (IDebuggerFileEvents Event in FileEvents)
                    {
                        Event.OnFileRead(Report);
                    }
                }
            }
            break;

            case (ExceptionCode)DebuggerMessages.ReportType.FILE_WRITE:
            {
                var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
                if (Thread != null)
                {
                    var Report = DebuggerMessages.GetFileWriteReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);

                    foreach (IDebuggerFileEvents Event in FileEvents)
                    {
                        Event.OnFileWrite(Report);
                    }
                }
            }
            break;

            case (ExceptionCode)DebuggerMessages.ReportType.FILE_CLOSED:
            {
                var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
                if (Thread != null)
                {
                    var Report = DebuggerMessages.GetFileClosedReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
                    if (Report != null)
                    {
                        foreach (IDebuggerFileEvents Event in FileEvents)
                        {
                            Event.OnFileClosed(Report);
                        }
                    }
                }
            }
            break;

            case (ExceptionCode)DebuggerMessages.ReportType.DEBUGGER_INIT:
            {
                var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
                if (Thread != null)
                {
                    var Report = DebuggerMessages.GetDebuggerInitReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);

                    InitParams = Report;

                    foreach (IDebuggerGeneralEvents Event in GeneralEvents)
                    {
                        Event.OnDebugTitleLoaded(InitParams.Title);
                    }
                }
            }
            break;

            case (ExceptionCode)DebuggerMessages.ReportType.MS_VC_EXCEPTION:
            {
                var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
                if (Thread != null)
                {
                    var Report = DebuggerMessages.GetMSVCThreadName(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
                    if (Report != null)
                    {
                        // Resolve the ThreadId of an invalid ID to the current thread name
                        if (Report.ThreadId == uint.MaxValue)
                        {
                            Report.ThreadId = (uint)DebugEvent.dwThreadId;
                        }

                        var ResolvedThread = DebugInstance.MainProcess.FindThread(Report.ThreadId);
                        if (ResolvedThread != null)
                        {
                            // Update the resolved thread name
                            ResolvedThread.DebugName = Report.Name;

                            foreach (IDebuggerThreadEvents Event in ThreadEvents)
                            {
                                Event.OnThreadNamed(Thread);
                            }
                        }
                    }
                }
            }
            break;

            case ExceptionCode.Breakpoint:
            {
                var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
                if (Thread != null)
                {
                    uint BpAddr      = (uint)DebugInfo.ExceptionRecord.ExceptionAddress;
                    uint BpCode      = DebugInfo.ExceptionRecord.ExceptionCode;
                    bool FirstChance = (DebugInfo.dwFirstChance != 0);

                    bpStall.Reset();

                    foreach (IDebuggerExceptionEvents Event in ExceptionEvents)
                    {
                        Event.OnBreakpoint(Thread, BpAddr, BpCode, FirstChance);
                    }

                    bpStall.WaitOne();
                }
            }
            break;

            case ExceptionCode.SingleStep:
                // TODO Handle
                break;

            default:
                ContinueStatus = WinDebug.CONTINUE_STATUS.DBG_EXCEPTION_NOT_HANDLED;
                break;
            }
        }