我正在开发一个使用VSIX的visual studio的调试器插件。我的问题是我有一个地址数组,但我不能将IDebugMemoryBytes2设置为一个特定的地址。我使用DEBUG_PROPERTY_INFO并获取地址数组,我也可以使用IDebugMemoryContext2中的Add函数将上下文设置为数组中的特定地址。但是,我需要使用ReadAt函数从指定地址(从IDebugMemoryBytes2)中检索n个字节。使用VSIX从任意内存地址检索数据
有没有人有任何想法如何从内存中的任意地址检索数据?
我加入同一信息
我现在用的是微软的Visual Studio扩展包来建立我的调试器插件。在我尝试使用这个插件进行调试的应用程序中,有一个双指针,我需要阅读这些值以在我的插件中进一步处理它们。为此,无法在监视窗口中显示所有指针变量,因此,我无法获得指针变量所指向的所有数组块的DEBUG_PROPERTY_INFO。这是我想解决的问题。我没有办法读取这个双指针指向的内存。
现在至于调试进程中的事件,由于插件是用于调试变量的,我在我知道这个指针被填充的地方放置一个断点,然后返回插件进行进一步评估。
作为一个开始,我以某种方式能够获得每个数组的起始地址。但是,我仍然无法从每个这些起始地址读取x个字节的内存。
即,例如,如果我有INT ** PTR = //指向东西
我有存在于PTR地址[0],PTR [1],PTR [2]等。但我需要去这些地址中的每一个地址并获取它们指向的内存块。
为此,经过多次搜索,我发现这个链接:https://macropolygon.wordpress.com/2012/12/16/evaluating-debugged-process-memory-in-a-visual-studio-extension/这似乎解决我的问题。
所以要使用表达式计算器函数,我需要一个IDebugStackFrame2对象来获取ExpressionContext。为了得到这个对象,我需要注册到调试对象进程中用于断点的事件。至于在帖子中说,我所做的:
public int Event(IDebugEngine2 engine, IDebugProcess2 process,
IDebugProgram2 program, IDebugThread2 thread, IDebugEvent2
debugEvent, ref Guid riidEvent, uint attributes)
{
if (debugEvent is IDebugBreakpointEvent2)
{
this.thread = thread;
}
return VSConstants.S_OK;
}
我的注册是这样的:
private void GetCurrentThread()
{
uint cookie;
DBGMODE[] modeArray = new DBGMODE[1];
// Get the Debugger service.
debugService = Package.GetGlobalService(typeof(SVsShellDebugger)) as
IVsDebugger;
if (debugService != null)
{
// Register for debug events.
// Assumes the current class implements IDebugEventCallback2.
debugService.AdviseDebuggerEvents(this, out cookie);
debugService.AdviseDebugEventCallback(this);
debugService.GetMode(modeArray);
modeArray[0] = modeArray[0] & ~DBGMODE.DBGMODE_EncMask;
if (modeArray[0] == DBGMODE.DBGMODE_Break)
{
GetCurrentStackFrame();
}
}
}
但是,这似乎并没有在所有调用事件功能,因此,我不知道怎么样获取IDebugThread2对象。
我也试过在同一职位建议的其他方式:
namespace Microsoft.VisualStudio.Debugger.Interop.Internal
{
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("1DA40549-8CCC-48CF-B99B-FC22FE3AFEDF")]
public interface IDebuggerInternal11 {
[DispId(0x6001001f)]
IDebugThread2 CurrentThread { [return:
MarshalAs(UnmanagedType.Interface)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime)]
get; [param: In, MarshalAs(UnmanagedType.Interface)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime)] set; }
}
}
private void GetCurrentThread()
{
debugService = Package.GetGlobalService(typeof(SVsShellDebugger)) as IVsDebugger;
if (debugService != null)
{
IDebuggerInternal11 debuggerServiceInternal =
(IDebuggerInternal11)debugService;
thread = debuggerServiceInternal.CurrentThread;
GetCurrentStackFrame();
}
}
但在这个方法中,我想我失去了一些东西,但我不知道,因为该行的执行后
IDebuggerInternal11 debuggerServiceInternal =
(IDebuggerInternal11)debugService;
当我检查debuggerServiceInternal变量的值,我看到有一个System.Security.SecurityException为CurrentThread,CurrentStackFrame(和如此明显的下一行导致系统崩溃)。为此,我搜索了该错误,发现我错过了该类的ComImport属性。所以我补充说,现在,我得到一个System.AccessViolationException:试图读取或写入受保护的内存。这通常表明其他内存已损坏。
我是C#编程的新手,因此,在短时间内掌握很多东西有点困难。我现在失去了如何继续前进。
任何帮助相同或建议尝试另一种方式来实现我的目标将不胜感激。
非常感谢,
Esash