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 Int3Breakpoint SetSoftwareBreakpoint(IntPtr address) { if (!_int3Breakpoints.TryGetValue(address, out var breakpoint)) { breakpoint = new Int3Breakpoint(this, address, true); _int3Breakpoints[address] = breakpoint; } return(breakpoint); }
public void RemoveSoftwareBreakpoint(Int3Breakpoint breakpoint) { if (breakpoint == null) { throw new ArgumentNullException(nameof(breakpoint)); } if (_int3Breakpoints.Remove(breakpoint.Address)) { breakpoint.Enabled = false; } }
public bool HandleBreakpointEvent(DEBUG_EVENT debugEvent, out DebuggerAction nextAction) { // If signalled by an int3, the exception was thrown after the execution of int3. // Find corresponding breakpoint and restore the instruction pointer so that it seems // it has paused execution before the int3. var process = _session.GetProcessById((int)debugEvent.dwProcessId); var thread = process.GetThreadById((int)debugEvent.dwThreadId); uint eip = (uint)thread.GetThreadContext().GetRegisterByName("eip").Value - 1; var breakpoint = process.GetSoftwareBreakpointByAddress((IntPtr)eip); // Check if breakpoint originated from a step-over action. if (breakpoint == null && _stepOverBreakpoint?.Address == (IntPtr)eip) { _stepOverBreakpoint.HandleBreakpointEvent(new BreakpointEventArgs(thread, _stepOverBreakpoint)); _stepOverBreakpoint = null; nextAction = FinalizeStep(thread); return(true); } if (breakpoint != null) { _breakpointsToRestore.Add(breakpoint); var eventArgs = new BreakpointEventArgs(thread, breakpoint) { NextAction = DebuggerAction.Stop }; breakpoint.HandleBreakpointEvent(eventArgs); OnBreakpointHit(eventArgs); nextAction = eventArgs.NextAction; return(true); } nextAction = DebuggerAction.ContinueWithException; return(false); }