Browse Source

Refresh memory addresses

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

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

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

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

@ -97,7 +97,7 @@ namespace Debugger.Interop @@ -97,7 +97,7 @@ namespace Debugger.Interop
public static class NativeMethods
{
[DllImport("kernel32.dll")]
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr handle);
[DllImport("mscoree.dll", CharSet=CharSet.Unicode, PreserveSig=false)]
@ -133,38 +133,41 @@ namespace Debugger.Interop @@ -133,38 +133,41 @@ namespace Debugger.Interop
[DllImport("kernel32.dll", SetLastError = true)]
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)
{
var result = new List<Tuple<long, long>>();
SYSTEM_INFO sysinfo = new SYSTEM_INFO();
GetSystemInfo(out sysinfo);
uint handle = process.CorProcess.GetHandle();
long address = 0;
MEMORY_BASIC_INFORMATION m = new MEMORY_BASIC_INFORMATION();
while (address < sysinfo.lpMaximumApplicationAddress.ToInt64())
{
if (!VirtualQueryEx(new IntPtr(handle), new IntPtr(address), out m, (uint)Marshal.SizeOf(m)))
break;
IntPtr openedProcess = IntPtr.Zero;
try {
openedProcess = OpenProcess(ProcessAccessFlags.All, false, (int)process.Id);
try {
byte[] temp = new byte[m.RegionSize.ToInt64()];
int outSize;
if (!ReadProcessMemory(new IntPtr(handle), new IntPtr(address), temp, temp.Length, out outSize))
while (address < sysinfo.lpMaximumApplicationAddress.ToInt64())
{
if (!VirtualQueryEx(openedProcess, new IntPtr(address), out m, (uint)Marshal.SizeOf(m)))
break;
try {
byte[] temp = new byte[m.RegionSize.ToInt64()];
int outSize;
if (!ReadProcessMemory(openedProcess, new IntPtr(address), temp, temp.Length, out outSize))
continue;
} catch {
continue;
} catch {
continue;
} finally {
// next address
address = m.BaseAddress.ToInt64() + m.RegionSize.ToInt64();
} finally {
// next address
address = m.BaseAddress.ToInt64() + m.RegionSize.ToInt64();
}
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;
@ -172,15 +175,22 @@ namespace Debugger.Interop @@ -172,15 +175,22 @@ namespace Debugger.Interop
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];
int outSize;
bool success = ReadProcessMemory(new IntPtr(handle), new IntPtr(startAddress), temp, temp.Length, out outSize);
if (!success || outSize == 0) {
var proc = System.Diagnostics.Process.GetProcessById((int)process.Id);
return process.ReadProcessMemory(proc.MainModule.BaseAddress.ToInt64(), (long)4096);
try {
openedProcess = OpenProcess(ProcessAccessFlags.All, false, (int)process.Id);
int outSize;
bool success = ReadProcessMemory(openedProcess, new IntPtr(startAddress), temp, temp.Length, out outSize);
if (!success || outSize == 0) {
var proc = System.Diagnostics.Process.GetProcessById((int)process.Id);
return process.ReadProcessMemory(proc.MainModule.BaseAddress.ToInt64(), (long)4096);
}
} finally {
if (openedProcess != IntPtr.Zero)
CloseHandle(openedProcess);
}
return temp;

Loading…
Cancel
Save