public bool HandlePageGuardViolationEvent(DEBUG_EVENT debugEvent, out DebuggerAction nextAction) { // Memory breakpoints are implemented using page guards. We need to check if the page guard // violation originated from a breakpoint or not, and pause or continue execution when appropriate. const int ExceptionInformationReadWrite = 0; const int ExceptionInformationAddress = 1; var info = debugEvent.InterpretDebugInfoAs <EXCEPTION_DEBUG_INFO>(); var process = _session.GetProcessById((int)debugEvent.dwProcessId); var thread = process.GetThreadById((int)debugEvent.dwThreadId); if (info.ExceptionRecord.NumberParameters >= 2) { bool isWrite = info.ExceptionRecord.ExceptionInformation[ExceptionInformationReadWrite] == 1; IntPtr address = (IntPtr)info.ExceptionRecord.ExceptionInformation[ExceptionInformationAddress]; var pageGuard = process.GetContainingPageGuard(address); if (pageGuard != null) { // Restore page guard after continuing. _pageGuardsToRestore.Add(pageGuard); if (pageGuard.Breakpoints.TryGetValue(address, out var breakpoint) && (breakpoint.BreakOnRead == !isWrite || breakpoint.BreakOnWrite == isWrite)) { // Violation originated from a breakpoint. var eventArgs = new BreakpointEventArgs(thread, breakpoint) { NextAction = DebuggerAction.Stop }; breakpoint.HandleBreakpointEvent(eventArgs); OnBreakpointHit(eventArgs); nextAction = eventArgs.NextAction; } else { // Violation did not originate from a breakpoint. _isRestoringFromGuard = true; PrepareContextForSingleStep(thread); nextAction = DebuggerAction.Continue; } return(true); } } nextAction = DebuggerAction.ContinueWithException; return(false); }
private DebuggerAction HandleExitProcessDebugEvent(DEBUG_EVENT debugEvent) { var info = debugEvent.InterpretDebugInfoAs <EXIT_PROCESS_DEBUG_INFO>(); var process = GetProcessById((int)debugEvent.dwProcessId); process.ExitCode = (int)info.dwExitCode; var eventArgs = new DebuggeeProcessEventArgs(process); OnProcessTerminated(eventArgs); _processes.Remove((int)debugEvent.dwProcessId); return(eventArgs.NextAction); }
private DebuggerAction HandleExitThreadDebugEvent(DEBUG_EVENT debugEvent) { var info = debugEvent.InterpretDebugInfoAs <EXIT_THREAD_DEBUG_INFO>(); var process = GetProcessById((int)debugEvent.dwProcessId); var thread = process.GetThreadById((int)debugEvent.dwThreadId); thread.ExitCode = (int)info.dwExitCode; var eventArgs = new DebuggeeThreadEventArgs(thread); OnThreadTerminated(eventArgs); process.RemoveThread(thread); return(eventArgs.NextAction); }
private DebuggerAction HandleCreateThreadDebugEvent(DEBUG_EVENT debugEvent) { var info = debugEvent.InterpretDebugInfoAs <CREATE_THREAD_DEBUG_INFO>(); var process = GetProcessById((int)debugEvent.dwProcessId); var thread = new DebuggeeThread(process, info.hThread, (int)debugEvent.dwThreadId, info.lpStartAddress); process.AddThread(thread); var eventArgs = new DebuggeeThreadEventArgs(thread); OnThreadStarted(eventArgs); return(eventArgs.NextAction); }
private DebuggerAction HandleOutputStringDebugEvent(DEBUG_EVENT debugEvent) { var info = debugEvent.InterpretDebugInfoAs <OUTPUT_DEBUG_STRING_INFO>(); var process = GetProcessById((int)debugEvent.dwProcessId); var thread = process.GetThreadById((int)debugEvent.dwThreadId); var eventArgs = new DebuggeeOutputStringEventArgs(thread, process.ReadString( info.lpDebugStringData, info.nDebugStringLength, info.fUnicode == 0)); OnOutputStringSent(eventArgs); return(eventArgs.NextAction); }
private DebuggerAction HandleCreateProcessDebugEvent(DEBUG_EVENT debugEvent) { var info = debugEvent.InterpretDebugInfoAs <CREATE_PROCESS_DEBUG_INFO>(); var process = GetOrCreateProcess(info.hProcess, (int)debugEvent.dwProcessId); process.BaseAddress = info.lpBaseOfImage; // Create process event also spawns a new thread. _currentThread = new DebuggeeThread(process, info.hThread, (int)debugEvent.dwThreadId, info.lpStartAddress); process.AddThread(_currentThread); var eventArgs = new DebuggeeProcessEventArgs(process); OnProcessStarted(eventArgs); return(eventArgs.NextAction); }
private DebuggerAction HandleExceptionDebugEvent(DEBUG_EVENT debugEvent) { var info = debugEvent.InterpretDebugInfoAs <EXCEPTION_DEBUG_INFO>(); var process = GetProcessById((int)debugEvent.dwProcessId); var thread = process.GetThreadById((int)debugEvent.dwThreadId); var nextAction = DebuggerAction.Stop; bool handled = false; switch (info.ExceptionRecord.ExceptionCode) { case ExceptionCode.EXCEPTION_BREAKPOINT: { handled = _executionController.HandleBreakpointEvent(debugEvent, out nextAction); break; } case ExceptionCode.EXCEPTION_SINGLE_STEP: { handled = _executionController.HandleStepEvent(debugEvent, out nextAction); break; } case ExceptionCode.EXCEPTION_GUARD_PAGE: { handled = _executionController.HandlePageGuardViolationEvent(debugEvent, out nextAction); break; } } if (!handled) { // Forward exception to debugger. var eventArgs = new DebuggeeExceptionEventArgs(thread, new DebuggeeException((uint)info.ExceptionRecord.ExceptionCode, info.ExceptionRecord.ExceptionCode.ToString(), info.dwFirstChance == 1, info.ExceptionRecord.ExceptionFlags == 0)); OnExceptionOccurred(eventArgs); nextAction = eventArgs.NextAction; } return(nextAction); }
private DebuggerAction HandleUnloadDllDebugEvent(DEBUG_EVENT debugEvent) { var info = debugEvent.InterpretDebugInfoAs <UNLOAD_DLL_DEBUG_INFO>(); var process = GetProcessById((int)debugEvent.dwProcessId); var thread = process.GetThreadById((int)debugEvent.dwThreadId); var library = process.GetLibraryByBase(info.lpBaseOfDll); if (library != null) { process.RemoveLibrary(library); var eventArgs = new DebuggeeLibraryEventArgs(thread, library); OnLibraryUnloaded(eventArgs); return(eventArgs.NextAction); } return(DebuggerAction.Continue); }
private DebuggerAction HandleLoadDllDebugEvent(DEBUG_EVENT debugEvent) { var info = debugEvent.InterpretDebugInfoAs <LOAD_DLL_DEBUG_INFO>(); var process = GetProcessById((int)debugEvent.dwProcessId); var thread = process.GetThreadById((int)debugEvent.dwThreadId); // LOAD_DLL_DEBUG_INFO.lpImageName is a char** or a wchar_t**, which can be null. string name = null; try { if (info.lpImageName != IntPtr.Zero) { var buffer = new byte[8]; process.ReadMemory(info.lpImageName, buffer, 0, IntPtr.Size); var ptr = new IntPtr(BitConverter.ToInt64(buffer, 0)); if (ptr != IntPtr.Zero) { name = process.ReadZeroTerminatedString(ptr, info.fUnicode == 0); } } } catch (Win32Exception) { // Reading failed, possibly due to an invalid pointer address. Set to no name instead. name = null; } var library = new DebuggeeLibrary(process, name, info.lpBaseOfDll); process.AddLibrary(library); var eventArgs = new DebuggeeLibraryEventArgs(thread, library); OnLibraryLoaded(eventArgs); return(eventArgs.NextAction); }