예제 #1
0
        private void HandleCreateThread(WinDebug.DEBUG_EVENT DebugEvent)
        {
            var DebugInfo = DebugEvent.CreateThread;

            if ((uint)DebugEvent.dwProcessId != DebugInstance.MainProcess.ProcessID)
            {
                throw new Exception("Handling event for unknown process");
            }

            var Process = DebugInstance.FindProcess((uint)DebugEvent.dwProcessId);

            if (Process == null)
            {
                throw new Exception("Unable to create tread with untracked process id");
            }

            var Thread = new DebuggerThread(Process);

            Thread.Handle       = DebugInfo.hThread;
            Thread.ThreadID     = NativeMethods.GetThreadId(Thread.Handle);
            Thread.StartAddress = DebugInfo.lpStartAddress;
            Thread.ThreadBase   = DebugInfo.lpThreadLocalBase;

            foreach (IDebuggerThreadEvents Event in ThreadEvents)
            {
                Event.OnThreadCreate(Thread);
            }
        }
예제 #2
0
        private void HandleOutputDebugString(WinDebug.DEBUG_EVENT DebugEvent)
        {
            var DebugInfo = DebugEvent.DebugString;

            string debugString = ReadProcessString(DebugInfo.lpDebugStringData, DebugInfo.nDebugStringLength, DebugInfo.fUnicode == 1);

            Parallel.ForEach(OutputEvents, Event => Event.OnDebugOutput(debugString));
        }
예제 #3
0
        private void HandleOutputDebugString(WinDebug.DEBUG_EVENT DebugEvent)
        {
            var DebugInfo = DebugEvent.DebugString;

            string debugString = ReadProcessString(DebugInfo.lpDebugStringData, DebugInfo.nDebugStringLength, DebugInfo.fUnicode == 1);

            foreach (IDebuggerOutputEvents Event in OutputEvents)
            {
                Event.OnDebugOutput(debugString);
            }
        }
예제 #4
0
        private void HandleCreateProcess(WinDebug.DEBUG_EVENT DebugEvent)
        {
            var DebugInfo = DebugEvent.CreateProcessInfo;

            var Process = new DebuggerProcess();

            Process.Core      = true;
            Process.Handle    = DebugInfo.hProcess;
            Process.ProcessID = WinLowLevel.GetProcessId(Process.Handle);
            Process.Path      = ResolveProcessPath(DebugInfo.hFile);

            // Skip over allocated Xbox memory
            Process.ImageBase = DebugInfo.lpBaseOfImage + VM_PLACEHOLDER_SIZE;

            var MainThread = new DebuggerThread(Process);

            MainThread.Handle     = DebugInfo.hThread;
            MainThread.ThreadID   = NativeMethods.GetThreadId(DebugInfo.hThread);
            MainThread.ThreadBase = DebugInfo.lpThreadLocalBase;

            // Setup as the main thread
            // TODO Check that we need to treat this as a special case
            Process.MainThread = MainThread;

            DebugInstance = new DebuggerInstance(Process);
            RegisterEventInterfaces(DebugInstance);

            foreach (IDebuggerProcessEvents Event in ProcessEvents)
            {
                Event.OnProcessCreate(Process);
            }

            foreach (IDebuggerThreadEvents Event in ThreadEvents)
            {
                Event.OnThreadCreate(MainThread);
            }

            var XboxModule = new DebuggerModule();

            XboxModule.Path      = Target;
            XboxModule.ImageBase = DebugInfo.lpBaseOfImage;
            XboxModule.Core      = true;

            foreach (IDebuggerModuleEvents Event in ModuleEvents)
            {
                Event.OnModuleLoaded(XboxModule);
            }
        }
예제 #5
0
        private void HandleUnloadDll(WinDebug.DEBUG_EVENT DebugEvent)
        {
            var DebugInfo = DebugEvent.UnloadDll;

            if ((uint)DebugEvent.dwProcessId != DebugInstance.MainProcess.ProcessID)
            {
                throw new Exception("Handling event for unknown process");
            }

            var TargetModule = DebugInstance.MainProcess.Modules.Find(Module => Module.ImageBase == DebugInfo.lpBaseOfDll);

            if (TargetModule != null)
            {
                Parallel.ForEach(ModuleEvents, Event => Event.OnModuleUnloaded(TargetModule));
            }
        }
예제 #6
0
        private void HandleLoadDll(WinDebug.DEBUG_EVENT DebugEvent)
        {
            var DebugInfo = DebugEvent.LoadDll;

            if ((uint)DebugEvent.dwProcessId != DebugInstance.MainProcess.ProcessID)
            {
                throw new Exception("Handling event for unknown process");
            }

            var Module = new DebuggerModule();

            Module.Path      = ResolveProcessPath(DebugInfo.hFile);
            Module.ImageBase = DebugInfo.lpBaseOfDll;

            Parallel.ForEach(ModuleEvents, Event => Event.OnModuleLoaded(Module));
        }
예제 #7
0
        private void HandleExitProcess(WinDebug.DEBUG_EVENT DebugEvent)
        {
            var DebugInfo = DebugEvent.ExitProcess;

            if ((uint)DebugEvent.dwProcessId != DebugInstance.MainProcess.ProcessID)
            {
                throw new Exception("Handling event for unknown process");
            }

            var  TargetProcess = DebugInstance.FindProcess((uint)DebugEvent.dwProcessId);
            uint ExitCode      = DebugInfo.dwExitCode;

            if (TargetProcess != null)
            {
                Parallel.ForEach(ProcessEvents, Event => Event.OnProcessExit(TargetProcess, ExitCode));
            }
        }
예제 #8
0
        private void HandleExitThread(WinDebug.DEBUG_EVENT DebugEvent)
        {
            var DebugInfo = DebugEvent.ExitThread;

            if ((uint)DebugEvent.dwProcessId != DebugInstance.MainProcess.ProcessID)
            {
                throw new Exception("Handling event for unknown process");
            }

            var TargetThread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);

            if (TargetThread != null)
            {
                uint ExitCode = DebugInfo.dwExitCode;

                Parallel.ForEach(ThreadEvents, Event => Event.OnThreadExit(TargetThread, ExitCode));
            }
        }
예제 #9
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();
            }
        }
예제 #10
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;
            }
        }
예제 #11
0
 public static extern bool WaitForDebugEvent(out DEBUG_EVENT debugEvent, uint timeout);