Browse Source

Refresh memory addresses

pull/21/head
Eusebiu Marcu 14 years ago
parent
commit
45b5c233a9
  1. 131
      src/AddIns/Debugger/Debugger.AddIn/Pads/MemoryPad.cs
  2. 30
      src/AddIns/Debugger/Debugger.Core/Interop/NativeMethods.cs

131
src/AddIns/Debugger/Debugger.AddIn/Pads/MemoryPad.cs

@ -2,9 +2,11 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization; using System.Globalization;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
@ -24,7 +26,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
Process debuggedProcess; Process debuggedProcess;
List<Tuple<long, long>> memoryAddresses = new List<Tuple<long, long>>(); List<Tuple<long, long>> memoryAddresses = new List<Tuple<long, long>>();
Dictionary<long, int> addressesMapping = new Dictionary<long, int>(); Dictionary<string, int> addressesMapping = new Dictionary<string, int>();
public MemoryPad() public MemoryPad()
{ {
@ -64,8 +66,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
long addr = Int64.Parse(address, NumberStyles.AllowHexSpecifier); long addr = Int64.Parse(address, NumberStyles.AllowHexSpecifier);
memoryAddresses = debuggedProcess.GetMemoryAddresses();
// find index for the address or the near addess // find index for the address or the near addess
currentAddressIndex = memoryAddresses.Search(addr); currentAddressIndex = memoryAddresses.BinarySearch(addr);
if (currentAddressIndex == -1) { if (currentAddressIndex == -1) {
MessageService.ShowMessage( MessageService.ShowMessage(
string.Format(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.AddressNotFound"), address), string.Format(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.AddressNotFound"), address),
@ -76,13 +79,15 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
} }
// refresh pad // refresh pad
Refresh(); if (!Refresh())
return;
// find line // find line
long mod = addr % addressStep; long mod = addr % addressStep;
int line; int line;
if (addressesMapping.ContainsKey(addr - mod)) string key = (addr - mod).ToString("X8");
line = addressesMapping[addr - mod]; if (addressesMapping.ContainsKey(key))
line = addressesMapping[key];
else else
line = 1; line = 1;
@ -97,15 +102,41 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
} }
} }
public void Refresh() public bool Refresh()
{ {
if (debuggedProcess == null || debugger.IsProcessRunning) console.Clear();
return;
if (memoryAddresses.Count == 0) if (debuggedProcess == null || debugger.IsProcessRunning) {
return; console.Append("Not debugging or process is running!");
return false;
}
if (currentAddressIndex <= -1) {
console.Append("No mappings for memory addresses!");
currentAddressIndex = -1;
return false;
}
console.Clear();addressesMapping.Clear(); memoryAddresses = debuggedProcess.GetMemoryAddresses();
if (memoryAddresses.Count == 0) {
console.Append("No mappings for memory addresses!");
return false;
}
if (currentAddressIndex >= memoryAddresses.Count) {
console.Append("No mappings for memory addresses!");
currentAddressIndex = memoryAddresses.Count ;
return false;
}
console.Append(DoWork());
return true;
}
string DoWork()
{
// refresh data
addressesMapping.Clear();
// get current address // get current address
var item = memoryAddresses[currentAddressIndex]; var item = memoryAddresses[currentAddressIndex];
@ -115,25 +146,25 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
byte[] memory = debuggedProcess.ReadProcessMemory(address, size); byte[] memory = debuggedProcess.ReadProcessMemory(address, size);
System.Diagnostics.Debug.Assert(memory != null); System.Diagnostics.Debug.Assert(memory != null);
int div = memory.Length / addressStep; int numberOfLines = memory.Length / addressStep;
int mod = memory.Length % addressStep; int mod = memory.Length % addressStep;
int index = 0; int currentLine = 0;
while (index < div) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
addressesMapping.Add(address, index + 1);
while (currentLine < numberOfLines) {
addressesMapping.Add(address.ToString("X8"), currentLine + 1);
// write address // write address
sb.Append(address.ToString("X8")); address += (long)addressStep; sb.Append(address.ToString("X8")); address += (long)addressStep;
sb.Append(" "); sb.Append(" ");
// write bytes // write bytes
for (int i = 0; i < addressStep; ++i) { for (int i = 0; i < addressStep; ++i) {
sb.Append(memory[index * addressStep + i].ToString("X2") + " "); sb.Append(memory[currentLine * addressStep + i].ToString("X2") + " ");
} }
// write chars // write chars
StringBuilder sb1 = new StringBuilder(); StringBuilder sb1 = new StringBuilder();
for (int i = 0; i < addressStep; ++i) { for (int i = 0; i < addressStep; ++i) {
sb1.Append(((char)memory[index * addressStep + i]).ToString()); sb1.Append(((char)memory[currentLine * addressStep + i]).ToString());
} }
string s = sb1.ToString(); string s = sb1.ToString();
s = Regex.Replace(s, @"\r\n", string.Empty); s = Regex.Replace(s, @"\r\n", string.Empty);
@ -142,61 +173,43 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
sb.Append(s); sb.Append(s);
sb.Append(Environment.NewLine); sb.Append(Environment.NewLine);
// start writing in console currentLine++;
console.Append(sb.ToString());
index++;
} }
if (mod != 0) { if (mod != 0) {
// write the rest of memory // write the rest of memory
StringBuilder sb = new StringBuilder(); addressesMapping.Add(address.ToString("X8"), currentLine + 1);
addressesMapping.Add(address, index + 1);
// write address // write address
sb.Append(address.ToString("X8")); sb.Append(address.ToString("X8"));
sb.Append(" "); sb.Append(" ");
// write bytes // write bytes
for (int i = 0; i < mod; ++i) { for (int i = 0; i < mod; ++i) {
sb.Append(memory[index * addressStep + i].ToString("X2") + " "); sb.Append(memory[currentLine * addressStep + i].ToString("X2") + " ");
} }
// write chars // write chars
StringBuilder sb1 = new StringBuilder(); StringBuilder sb1 = new StringBuilder();
for (int i = 0; i < mod; ++i) { for (int i = 0; i < mod; ++i) {
sb1.Append(((char)memory[index * addressStep + i]).ToString()); sb1.Append(((char)memory[currentLine * addressStep + i]).ToString());
} }
string s = sb1.ToString(); string s = sb1.ToString();
s = Regex.Replace(s, @"\r\n", string.Empty); s = Regex.Replace(s, @"\r\n", string.Empty);
s = Regex.Replace(s, @"\n", string.Empty); s = Regex.Replace(s, @"\n", string.Empty);
s = Regex.Replace(s, @"\r", string.Empty); s = Regex.Replace(s, @"\r", string.Empty);
sb.Append(s); sb.Append(s);
sb.Append(Environment.NewLine);
// start writing in console
console.Append(sb.ToString());
} }
return sb.ToString();
} }
public void MoveToPreviousAddress() public void MoveToPreviousAddress()
{ {
if (debuggedProcess == null || debugger.IsProcessRunning)
return;
if (currentAddressIndex == 0)
return;
currentAddressIndex--; currentAddressIndex--;
Refresh(); Refresh();
} }
public void MoveToNextAddress() public void MoveToNextAddress()
{ {
if (debuggedProcess == null || debugger.IsProcessRunning)
return;
if (currentAddressIndex == memoryAddresses.Count)
return;
currentAddressIndex++; currentAddressIndex++;
Refresh(); Refresh();
} }
@ -204,19 +217,41 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
internal static class MemoryPadExtensions internal static class MemoryPadExtensions
{ {
internal static int Search(this List<Tuple<long, long>> source, long item1) /// <summary>
/// Does a binary search when the Item1 from Tuple is sorted.
/// </summary>
/// <param name="source">Source of data.</param>
/// <param name="item1">Item to search.</param>
/// <returns>The nearast index.</returns>
internal static int BinarySearch(this List<Tuple<long, long>> source, long item1)
{ {
// base checks
if (source == null) if (source == null)
throw new NullReferenceException("Source is null!"); throw new NullReferenceException("Source is null!");
for (int i = 0; i < source.Count - 1; i++) { if (source.Count == 0)
if (source[i + 1].Item1 < item1) return -1;
continue;
if (item1 < source[0].Item1)
return 0;
return i; if (item1 > source[source.Count - 1].Item1)
return source.Count;
// do a binary search since the source is sorted
int first = 0; int last = source.Count;
while (first < last - 1) {
int middle = (first + last) / 2;
if (source[middle].Item1 == item1)
return middle;
else
if (source[middle].Item1 < item1)
first = middle;
else
last = middle;
} }
return -1; return first;
} }
} }
} }

30
src/AddIns/Debugger/Debugger.Core/Interop/NativeMethods.cs

@ -97,7 +97,7 @@ namespace Debugger.Interop
public static class NativeMethods public static class NativeMethods
{ {
[DllImport("kernel32.dll")] [DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr handle); public static extern bool CloseHandle(IntPtr handle);
[DllImport("mscoree.dll", CharSet=CharSet.Unicode, PreserveSig=false)] [DllImport("mscoree.dll", CharSet=CharSet.Unicode, PreserveSig=false)]
@ -134,28 +134,27 @@ namespace Debugger.Interop
[DllImport("kernel32.dll", SetLastError = true)] [DllImport("kernel32.dll", SetLastError = true)]
public static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo); public static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);
[DllImport("kernel32.dll", SetLastError=true, ExactSpelling=true)]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
public static List<Tuple<long, long>> GetMemoryAddresses(this Process process) public static List<Tuple<long, long>> GetMemoryAddresses(this Process process)
{ {
var result = new List<Tuple<long, long>>(); var result = new List<Tuple<long, long>>();
SYSTEM_INFO sysinfo = new SYSTEM_INFO(); SYSTEM_INFO sysinfo = new SYSTEM_INFO();
GetSystemInfo(out sysinfo); GetSystemInfo(out sysinfo);
uint handle = process.CorProcess.GetHandle();
long address = 0; long address = 0;
MEMORY_BASIC_INFORMATION m = new MEMORY_BASIC_INFORMATION(); MEMORY_BASIC_INFORMATION m = new MEMORY_BASIC_INFORMATION();
IntPtr openedProcess = IntPtr.Zero;
try {
openedProcess = OpenProcess(ProcessAccessFlags.All, false, (int)process.Id);
while (address < sysinfo.lpMaximumApplicationAddress.ToInt64()) while (address < sysinfo.lpMaximumApplicationAddress.ToInt64())
{ {
if (!VirtualQueryEx(new IntPtr(handle), new IntPtr(address), out m, (uint)Marshal.SizeOf(m))) if (!VirtualQueryEx(openedProcess, new IntPtr(address), out m, (uint)Marshal.SizeOf(m)))
break; break;
try { try {
byte[] temp = new byte[m.RegionSize.ToInt64()]; byte[] temp = new byte[m.RegionSize.ToInt64()];
int outSize; int outSize;
if (!ReadProcessMemory(new IntPtr(handle), new IntPtr(address), temp, temp.Length, out outSize)) if (!ReadProcessMemory(openedProcess, new IntPtr(address), temp, temp.Length, out outSize))
continue; continue;
} catch { } catch {
continue; continue;
@ -166,22 +165,33 @@ namespace Debugger.Interop
result.Add(new Tuple<long, long>(m.BaseAddress.ToInt64(), m.RegionSize.ToInt64())); result.Add(new Tuple<long, long>(m.BaseAddress.ToInt64(), m.RegionSize.ToInt64()));
} }
} finally {
if (openedProcess != IntPtr.Zero)
CloseHandle(openedProcess);
}
return result; return result;
} }
public static byte[] ReadProcessMemory(this Process process, long startAddress, long size) public static byte[] ReadProcessMemory(this Process process, long startAddress, long size)
{ {
uint handle = process.CorProcess.GetHandle(); IntPtr openedProcess = IntPtr.Zero;
byte[] temp = new byte[size]; byte[] temp = new byte[size];
try {
openedProcess = OpenProcess(ProcessAccessFlags.All, false, (int)process.Id);
int outSize; int outSize;
bool success = ReadProcessMemory(new IntPtr(handle), new IntPtr(startAddress), temp, temp.Length, out outSize); bool success = ReadProcessMemory(openedProcess, new IntPtr(startAddress), temp, temp.Length, out outSize);
if (!success || outSize == 0) { if (!success || outSize == 0) {
var proc = System.Diagnostics.Process.GetProcessById((int)process.Id); var proc = System.Diagnostics.Process.GetProcessById((int)process.Id);
return process.ReadProcessMemory(proc.MainModule.BaseAddress.ToInt64(), (long)4096); return process.ReadProcessMemory(proc.MainModule.BaseAddress.ToInt64(), (long)4096);
} }
} finally {
if (openedProcess != IntPtr.Zero)
CloseHandle(openedProcess);
}
return temp; return temp;
} }

Loading…
Cancel
Save