// Sets the next statement to the given stack frame and code context. int IDebugThread2.SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { // CLRDBG TODO: This implementation should be changed to call an MI command ulong addr = ((AD7MemoryAddress)codeContext).Address; AD7StackFrame frame = ((AD7StackFrame)stackFrame); if (frame.ThreadContext.Level != 0 || frame.Thread != this || !frame.ThreadContext.pc.HasValue || _engine.DebuggedProcess.MICommandFactory.Mode == MIMode.Clrdbg) { return(Constants.S_FALSE); } string toFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, addr); string fromFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, frame.ThreadContext.pc.Value); if (toFunc != fromFunc) { return(Constants.S_FALSE); } string result = frame.EvaluateExpression("$pc=" + EngineUtils.AsAddr(addr)); if (result != null) { _engine.DebuggedProcess.ThreadCache.MarkDirty(); return(Constants.S_OK); } return(Constants.S_FALSE); }
private DisassemblyData FetchBadInstruction(enum_DISASSEMBLY_STREAM_FIELDS dwFields) { DisassemblyData dis = new DisassemblyData(); if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0) { dis.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS; dis.bstrAddress = EngineUtils.AsAddr(_addr, _engine.DebuggedProcess.Is64BitArch); } if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0) { dis.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID; dis.uCodeLocationId = _addr; } if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL) != 0) { dis.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL; dis.bstrSymbol = string.Empty; } if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0) { dis.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE; dis.bstrOpcode = "??"; } return(dis); }
// Sets the next statement to the given stack frame and code context. int IDebugThread2.SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { ulong addr = ((AD7MemoryAddress)codeContext).Address; AD7StackFrame frame = ((AD7StackFrame)stackFrame); if (frame.ThreadContext.Level != 0 || frame.Thread != this || !frame.ThreadContext.pc.HasValue) { return(Constants.S_FALSE); } string toFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, addr); string fromFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, frame.ThreadContext.pc.Value); if (toFunc != fromFunc) { return(Constants.S_FALSE); } string result = frame.EvaluateExpression("$pc=" + EngineUtils.AsAddr(addr, _engine.DebuggedProcess.Is64BitArch)); if (result != null) { _engine.DebuggedProcess.ThreadCache.MarkDirty(); return(Constants.S_OK); } return(Constants.S_FALSE); }
// Gets information that describes this context. public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo) { try { pinfo[0].dwFields = 0; if ((dwFields & (enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS | enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE)) != 0) { string addr = EngineUtils.AsAddr(_address, _engine.DebuggedProcess.Is64BitArch); if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0) { pinfo[0].bstrAddress = addr; pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS; } if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE) != 0) { pinfo[0].bstrAddressAbsolute = addr; pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE; } } // Fields not supported by the sample if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSOFFSET) != 0) { } if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0) { DebuggedModule module = _engine.DebuggedProcess.ResolveAddress(_address); if (module != null) { pinfo[0].bstrModuleUrl = module.Name; pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL; } } if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION) != 0) { if (string.IsNullOrEmpty(_functionName)) { _functionName = Engine.GetAddressDescription(_address); } if (!(string.IsNullOrEmpty(_functionName))) { pinfo[0].bstrFunction = _functionName; pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION; } } return(Constants.S_OK); } catch (MIException e) { return(e.HResult); } catch (Exception e) { return(EngineUtils.UnexpectedException(e)); } }
// this is inefficient so we try and grab everything in one gulp internal static async Task <DisasmInstruction[]> Disassemble(DebuggedProcess process, ulong startAddr, ulong endAddr) { string cmd = "-data-disassemble -s " + EngineUtils.AsAddr(startAddr, process.Is64BitArch) + " -e " + EngineUtils.AsAddr(endAddr, process.Is64BitArch) + " -- 2"; Results results = await process.CmdAsync(cmd, ResultClass.None); if (results.ResultClass != ResultClass.done) { return(null); } return(DecodeDisassemblyInstructions(results.Find <ValueListValue>("asm_insns").AsArray <TupleValue>())); }
internal async Task <uint> ReadProcessMemory(ulong address, uint count, byte[] bytes) { string cmd = "-data-read-memory-bytes " + EngineUtils.AsAddr(address) + " " + count.ToString(); Results results = await CmdAsync(cmd, ResultClass.None); if (results.ResultClass == ResultClass.error) { return(uint.MaxValue); } ValueListValue mem = results.Find <ValueListValue>("memory"); if (mem.IsEmpty()) { return(0); } TupleValue res = mem.Content[0] as TupleValue; if (res == null) { return(0); } ulong start = res.FindAddr("begin"); ulong end = res.FindAddr("end"); ulong offset = res.FindAddr("offset"); // for some reason this is formatted as hex string content = res.FindString("contents"); uint toRead = (uint)content.Length / 2; if (toRead > count) { toRead = count; } // ensure the buffer contains the desired bytes. if (start + offset != address) { throw new MIException(Constants.E_FAIL); } for (int pos = 0; pos < toRead; ++pos) { // Decode one byte string strByte = content.Substring(pos * 2, 2); bytes[pos] = Convert.ToByte(strByte, 16); } return(toRead); }
// Gets the breakpoint resolution information that describes this breakpoint. int IDebugBreakpointResolution2.GetResolutionInfo(enum_BPRESI_FIELDS dwFields, BP_RESOLUTION_INFO[] pBPResolutionInfo) { if ((dwFields & enum_BPRESI_FIELDS.BPRESI_BPRESLOCATION) != 0) { BP_RESOLUTION_LOCATION location = new BP_RESOLUTION_LOCATION(); location.bpType = (uint)_breakType; if (_breakType == enum_BP_TYPE.BPT_CODE) { // The debugger will not QI the IDebugCodeContex2 interface returned here. We must pass the pointer // to IDebugCodeContex2 and not IUnknown. AD7MemoryAddress codeContext = new AD7MemoryAddress(_engine, Addr, _functionName); codeContext.SetDocumentContext(_documentContext); location.unionmember1 = HostMarshal.RegisterCodeContext(codeContext); pBPResolutionInfo[0].bpResLocation = location; pBPResolutionInfo[0].dwFields |= enum_BPRESI_FIELDS.BPRESI_BPRESLOCATION; } else if (_breakType == enum_BP_TYPE.BPT_DATA) { location.unionmember1 = HostMarshal.GetIntPtrForDataBreakpointAddress(EngineUtils.AsAddr(Addr, _engine.DebuggedProcess.Is64BitArch)); pBPResolutionInfo[0].bpResLocation = location; pBPResolutionInfo[0].dwFields |= enum_BPRESI_FIELDS.BPRESI_BPRESLOCATION; } } if ((dwFields & enum_BPRESI_FIELDS.BPRESI_PROGRAM) != 0) { pBPResolutionInfo[0].pProgram = (IDebugProgram2)_engine; pBPResolutionInfo[0].dwFields |= enum_BPRESI_FIELDS.BPRESI_PROGRAM; } return(Constants.S_OK); }