// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) #pragma warning disable 1591 using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using Debugger.Interop.CorDebug; namespace Debugger.Interop { [StructLayout(LayoutKind.Sequential)] public struct MEMORY_BASIC_INFORMATION { public IntPtr BaseAddress; public IntPtr AllocationBase; public uint AllocationProtect; public IntPtr RegionSize; public uint State; public uint Protect; public uint Type; } [Flags] public enum ProcessAccessFlags : uint { All = 0x001F0FFF, Terminate = 0x00000001, CreateThread = 0x00000002, VMOperation = 0x00000008, VMRead = 0x00000010, VMWrite = 0x00000020, DupHandle = 0x00000040, SetInformation = 0x00000200, QueryInformation = 0x00000400, Synchronize = 0x00100000 } [StructLayout(LayoutKind.Sequential)] public struct SYSTEM_INFO { internal _PROCESSOR_INFO_UNION uProcessorInfo; public uint dwPageSize; public IntPtr lpMinimumApplicationAddress; public IntPtr lpMaximumApplicationAddress; public IntPtr dwActiveProcessorMask; public uint dwNumberOfProcessors; public uint dwProcessorType; public uint dwAllocationGranularity; public ushort dwProcessorLevel; public ushort dwProcessorRevision; } [StructLayout(LayoutKind.Explicit)] public struct _PROCESSOR_INFO_UNION { [FieldOffset(0)] internal uint dwOemId; [FieldOffset(0)] internal ushort wProcessorArchitecture; [FieldOffset(2)] internal ushort wReserved; } [Flags] public enum AllocationType { Commit = 0x1000, Reserve = 0x2000, Decommit = 0x4000, Release = 0x8000, Reset = 0x80000, Physical = 0x400000, TopDown = 0x100000, WriteWatch = 0x200000, LargePages = 0x20000000 } [Flags] public enum MemoryProtection { Execute = 0x10, ExecuteRead = 0x20, ExecuteReadWrite = 0x40, ExecuteWriteCopy = 0x80, NoAccess = 0x01, ReadOnly = 0x02, ReadWrite = 0x04, WriteCopy = 0x08, GuardModifierflag = 0x100, NoCacheModifierflag = 0x200, WriteCombineModifierflag = 0x400 } public static class NativeMethods { [DllImport("kernel32.dll", SetLastError = true)] public static extern bool CloseHandle(IntPtr handle); [DllImport("mscoree.dll", CharSet=CharSet.Unicode, PreserveSig=false)] public static extern Debugger.Interop.CorDebug.ICorDebug CreateDebuggingInterfaceFromVersion(int debuggerVersion, string debuggeeVersion); [DllImport("mscoree.dll", CharSet=CharSet.Unicode)] public static extern int GetCORVersion([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName, Int32 cchBuffer, out Int32 dwLength); [DllImport("mscoree.dll", CharSet=CharSet.Unicode)] public static extern int GetRequestedRuntimeVersion(string exeFilename, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pVersion, Int32 cchBuffer, out Int32 dwLength); [DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool ReadProcessMemory( IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead ); [DllImport("kernel32.dll", SetLastError = true)] public static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo); public static List> GetVirtualMemoryAddresses(this Process process) { var result = new List>(); SYSTEM_INFO sysinfo = new SYSTEM_INFO(); GetSystemInfo(out sysinfo); long address = 0; 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()) { try { if (!VirtualQueryEx(openedProcess, new IntPtr(address), out m, (uint)Marshal.SizeOf(m))) continue; } finally { // next address address = m.BaseAddress.ToInt64() + m.RegionSize.ToInt64(); } result.Add(new Tuple(m.BaseAddress.ToInt64(), m.RegionSize.ToInt64())); } } finally { if (openedProcess != IntPtr.Zero) CloseHandle(openedProcess); } return result; } public static byte[] ReadProcessMemory(this Process process, long startAddress, long size) { IntPtr openedProcess = IntPtr.Zero; byte[] temp = null; try { temp = new byte[size]; 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); } } catch { return null; } finally { if (openedProcess != IntPtr.Zero) CloseHandle(openedProcess); } return temp; } } } #pragma warning restore 1591