private static void PrepareContextForSingleStep(DebuggeeThread thread) { var threadContext = thread.GetThreadContext(); threadContext.GetRegisterByName("tf").Value = true; threadContext.Flush(); }
private void SignalStepIn(DebuggeeThread thread, DebuggerAction nextAction) { // Set trap flag to signal an EXCEPTION_SINGLE_STEP event after next instruction. PrepareContextForSingleStep(thread); _session.SignalDebuggerLoop(nextAction); }
private void SignalStepOver(DebuggeeThread thread, DebuggerAction nextAction) { // Stepping over means step one instruction, but skip call instructions. // Therefore, if the current instruction is a call, we set a temporary breakpoint // to the next instruction and continue execution, otherwise we perform a normal step. var threadContext = thread.GetThreadContext(); var eip = (uint)threadContext.GetRegisterByName("eip").Value; var info = _disassemblers[thread.Process]; info.Reader.Position = eip; var instruction = info.Disassembler.ReadNextInstruction(); switch (instruction.Mnemonic) { case X86Mnemonic.Call: case X86Mnemonic.Call_Far: _stepOverBreakpoint = new Int3Breakpoint(thread.Process, (IntPtr)info.Reader.Position, true); _session.SignalDebuggerLoop(nextAction); break; default: SignalStepIn(thread, nextAction); break; } }
public void Continue(DebuggeeThread thread, DebuggerAction nextAction) { _isContinuing = true; _continueAction = nextAction; if (HasBreakpointsToRestore) { SignalStep(thread, StepType.StepIn, nextAction); } else { _session.SignalDebuggerLoop(FinalizeContinue(thread)); } }
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 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); }
public void SignalStep(DebuggeeThread thread, StepType stepType, DebuggerAction nextAction) { _isStepping = true; switch (stepType) { case StepType.StepIn: SignalStepIn(thread, nextAction); break; case StepType.StepOver: SignalStepOver(thread, nextAction); break; case StepType.StepOut: SignalStepOut(thread, nextAction); break; default: throw new ArgumentOutOfRangeException(nameof(stepType), stepType, null); } }
private void DebuggerLoop() { while (IsActive) { // Handle next debugger event. var nextEvent = NativeMethods.WaitForDebugEvent(uint.MaxValue); _isPaused = true; _currentThread = GetProcessById((int)nextEvent.dwProcessId)?.GetThreadById((int)nextEvent.dwThreadId); var nextAction = HandleDebugEvent(nextEvent); // Handle action that might have been set by subscribed event handlers. HandleNextAction(nextAction, nextEvent); // Continue execution. NativeMethods.ContinueDebugEvent( nextEvent.dwProcessId, nextEvent.dwThreadId, _nextContinueStatus); _isPaused = false; } }
private DebuggerAction FinalizeStep(DebuggeeThread thread) { RestoreBreakpoints(); _isStepping = false; if (_isRestoringFromGuard) { return(FinalizeRestoreFromGuard(thread)); } if (_isContinuing) { return(FinalizeContinue(thread)); } var eventArgs = new DebuggeeThreadEventArgs(thread) { NextAction = DebuggerAction.Stop }; OnStepCompleted(eventArgs); return(eventArgs.NextAction); }
internal void RemoveThread(DebuggeeThread thread) { _threads.Remove(thread.Id); OnThreadTerminated(new DebuggeeThreadEventArgs(thread)); }
internal void AddThread(DebuggeeThread thread) { _threads.Add(thread.Id, thread); OnThreadStarted(new DebuggeeThreadEventArgs(thread)); }
private DebuggerAction FinalizeRestoreFromGuard(DebuggeeThread thread) { _isRestoringFromGuard = false; return(DebuggerAction.Continue); }