void BuildCallStack() { callstack.Clear(); var ebp = lastReadCtxt.ebp; const int MaxFrames = 128; var proc = Thread.OwnerProcess; var p = proc.Handle; callstack.Add(new Stackframe(new IntPtr(ebp), new IntPtr(lastReadCtxt.eip))); do { // The return address is stored at ebp+1 var returnTo = APIIntermediate.Read <uint>(p, new IntPtr(ebp + 4)); ebp = APIIntermediate.Read <uint>(p, new IntPtr(ebp)); if (ebp == 0 || returnTo == ebp) { break; } callstack.Add(new Stackframe(new IntPtr(ebp), new IntPtr(returnTo))); }while (callstack.Count < MaxFrames); string file = ""; ushort line = 0; Console.WriteLine("------------------------\r\nCall stack begin:\r\n------------------------"); foreach (var sf in callstack) { Console.Write("0x" + sf.CodeAddress.ToString("X8")); if (proc.MainModule.ContainsSymbolData && proc.MainModule.ModuleMetaInfo.TryDetermineCodeLocation((uint)sf.CodeAddress.ToInt32(), out file, out line)) { Console.WriteLine(" @ " + file + ":" + line); } else { Console.WriteLine(); } } }
/// <summary> /// Executes until the currently executed method's point of return has been reached. /// </summary> public void StepOut(DebugThread th) { var returnPtr = APIIntermediate.Read <IntPtr>(th.OwnerProcess.Handle, new IntPtr(th.Context.lastReadCtxt.ebp + 4)); var tempBreakPoint = Breakpoints.ByAddress(returnPtr); bool keepBpAfterStepComplete = false; if (keepBpAfterStepComplete = tempBreakPoint == null) { tempBreakPoint = Breakpoints.CreateBreakpoint(returnPtr); } th.ContinueDebugging(); Debuggee.WaitForDebugEvent(); if (!keepBpAfterStepComplete) { Breakpoints.Remove(tempBreakPoint); } }