public void UpdateContext() { bool Result = NativeMethods.GetThreadContext(Handle, ref ContextCache); if (!Result) { return; } uint ebp = ContextCache.ebp; CallstackCache = new DebuggerCallstack(); CallstackCache.AddFrame(new DebuggerStackFrame(new IntPtr(ContextCache.eip), new IntPtr(ebp), new IntPtr(ContextCache.esp))); uint ReturnAddr = 0; do { if (!OwningProcess.ReadMemory(new IntPtr(ebp + 4), ref ReturnAddr)) { break; } if (!OwningProcess.ReadMemory(new IntPtr(ebp), ref ebp)) { break; } if (ebp == 0 || ReturnAddr == ebp) { break; } CallstackCache.AddFrame(new DebuggerStackFrame(new IntPtr(ReturnAddr), new IntPtr(ebp))); }while (CallstackCache.CanCollect); }
public void UpdateContext() { bool Result = NativeMethods.GetThreadContext(Handle, ref ContextCache); if (!Result) { return; } uint ebp = ContextCache.ebp; CallstackCache = new DebuggerCallstack(); CallstackCache.AddFrame(new DebuggerStackFrame(ContextCache)); // Walk the stack to find the return address of the previous call // This only works for specific calling conventions uint ReturnAddr = 0; do { try { if (!OwningProcess.ReadMemory(new IntPtr(ebp + 4), ref ReturnAddr)) { break; } if (!OwningProcess.ReadMemory(new IntPtr(ebp), ref ebp)) { break; } if (ebp == 0 || ReturnAddr == ebp) { break; } CallstackCache.AddFrame(new DebuggerStackFrame(ReturnAddr, ebp)); } catch { break; } }while (CallstackCache.CanCollect); }