private void StartListener(uint WaitInterval = 200) { var DebugEvent = new DEBUG_EVENT(); for (; IsDebugging;) { if (!Kernel32.WaitForDebugEvent(ref DebugEvent, WaitInterval)) { if (!IsDebugging) { break; } continue; } //Console.WriteLine("Debug Event Code: {0} ", DebugEvent.dwDebugEventCode); bool okEvent = false; switch (DebugEvent.dwDebugEventCode) { case DebugEventType.RIP_EVENT: case DebugEventType.EXIT_PROCESS_DEBUG_EVENT: //Console.WriteLine("Process has exited"); IsDebugging = false; IsDetached = true; if (!Kernel32.ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, okEvent ? (uint)DebugContinueStatus.DBG_CONTINUE : (uint)DebugContinueStatus.DBG_EXCEPTION_NOT_HANDLED)) { throw new DebuggerException("Failed to continue debug event"); } if (!Kernel32.DebugActiveProcessStop(Process.Id)) { throw new DebuggerException("Failed to stop process debugging"); } return; case DebugEventType.EXCEPTION_DEBUG_EVENT: //Console.WriteLine("Exception Code: {0:X}", DebugEvent.Exception.ExceptionRecord.ExceptionCode); if (DebugEvent.Exception.ExceptionRecord.ExceptionCode == (uint)ExceptonStatus.STATUS_SINGLE_STEP) { okEvent = true; /*if (DebugEvent.dwThreadId != threadId) * { * Console.WriteLine("Debug event thread id does not match breakpoint thread"); * break; * }*/ var hThread = Kernel32.OpenThread(ThreadAccess.THREAD_ALL_ACCESS, false, DebugEvent.dwThreadId); if (hThread == IntPtr.Zero) { throw new DebuggerException("Failed to open thread"); } var Context = new CONTEXT(); Context.ContextFlags = (uint)CONTEXT_FLAGS.CONTEXT_FULL; if (!Kernel32.GetThreadContext(hThread, Context)) { throw new DebuggerException("Failed to get thread context"); } if (!Breakpoints.Any(e => e != null && e.IsSet && e.Address.ToUInt32() == Context.Eip)) { break; } var bp = Breakpoints.First(e => e != null && e.IsSet && e.Address.ToUInt32() == Context.Eip); var ContextWrapper = new ContextWrapper(this, Context); if (bp.HandleException(ContextWrapper)) { if (!Kernel32.SetThreadContext(hThread, ContextWrapper.Context)) { throw new DebuggerException("Failed to set thread context"); } } } break; case DebugEventType.CREATE_THREAD_DEBUG_EVENT: { foreach (var bp in Breakpoints) { bp.SetToThread(DebugEvent.CreateThread.hThread, DebugEvent.dwThreadId); } break; } case DebugEventType.EXIT_THREAD_DEBUG_EVENT: { foreach (var bp in Breakpoints) { bp.UnregisterThread(DebugEvent.dwThreadId); } break; } default: break; } if (!IsDebugging) { IsDetached = true; RemoveBreakPoints(); if (!Kernel32.ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, okEvent ? (uint)DebugContinueStatus.DBG_CONTINUE : (uint)DebugContinueStatus.DBG_EXCEPTION_NOT_HANDLED)) { throw new DebuggerException("Failed to continue debug event"); } if (!Kernel32.DebugActiveProcessStop(Process.Id)) { throw new DebuggerException("Failed to stop process debugging"); } return; } if (!Kernel32.ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, okEvent ? (uint)DebugContinueStatus.DBG_CONTINUE : (uint)DebugContinueStatus.DBG_EXCEPTION_NOT_HANDLED)) { throw new DebuggerException("Failed to continue debug event"); } } Detach(); }
public virtual bool HandleException(ContextWrapper Wrapper) { return(false); }