0

I'm creating this VS2010 Addin project in C#, which will be used to debug my other c++ projects. The data I want to process is stored in a block of memory of the c++ project. In the VS2010 watch window i can see the array of memory by a expression like "&myobject,100".

In my addin project, I try using expression "&myobject,100", this only return me a value of the address, same as "&myobject". I was expecting an array of bytes, or any other way to get me that block of memory.

The stupid workaround is using a loop to get each byte of that memory with the expression of "*(char *)&myobject[i]"but this is just too slow.

From my research,it looks like I can implement a Expression evaluator to read memory and return object containing that memory's data. How to do that? What's the simplest way to do that? (implementing minimal amount of interfaces etc).

Thanks

joeyzhao
  • 61
  • 1
  • 6

2 Answers2

1

You can read the debuggee's memory using win32 api. To do so you need to import two kernel32.dll functions in your C# class: ReadProcessMemory and OpenProcess

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(
  IntPtr hProcess,
  IntPtr lpBaseAddress,
  [Out] byte[] lpBuffer,
  int dwSize,
  out int lpNumberOfBytesRead
 );

[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

[Flags]
enum ProcessAccessFlags : uint
{
  All = 0x001F0FFF,
  Terminate = 0x00000001,
  CreateThread = 0x00000002,
  VMOperation = 0x00000008,
  VMRead = 0x00000010,
  VMWrite = 0x00000020,
  DupHandle = 0x00000040,
  SetInformation = 0x00000200,
  QueryInformation = 0x00000400,
  Synchronize = 0x00100000
}

The process ID can be obtained from your DTE instance and the memory address by evaluating &myobject.

int pid = _applicationObject.Debugger.CurrentProcess.ProcessID;
IntPtr phandle = OpenProcess((int)ProcessAccessFlags.VMRead, true, pid);
byte[] buffer = new byte[size];
int read;
ReadProcessMemory(phandle, (IntPtr)addr, buffer, (int)size, out read);

Be aware that this only works if your debugee is a 32 Bit process. Otherwise you can use a 64 Bit helper process to read the memory from your debugee (why is Visual Studio still a 32 Bit proces??). Use sockets to communicate with this process.

tofucoder
  • 191
  • 1
  • 7
  • Thanks tofucoder, I no longer work in that company and not touching VS since. nevertheless, it's good to know it's doable, maybe oneday when I'm back into C#. – joeyzhao Mar 12 '14 at 21:50
0

Have you tried to look at the Memory watch window from Debug -> Windows -> Memory?

josephthomas
  • 3,256
  • 15
  • 20
  • Thanks tom. I did, but that is for human debugging purpose I guess. What i'm trying to do here is create a VS2010 add-in that can evaluate the data in that block of memory, I don't know how to achieve that. – joeyzhao Apr 02 '12 at 20:53