private unsafe void InitMemoryRegionInfo() { SYSTEM_INFO sys_info; //Get the maximum and minimum addresses of the process. GetSystemInfo(out sys_info); IntPtr proc_min_address = sys_info.minimumApplicationAddress; IntPtr proc_max_address = sys_info.maximumApplicationAddress; byte *current_address = (byte *)proc_min_address.ToPointer(); byte *lproc_max_address = (byte *)proc_max_address.ToPointer(); IntPtr handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_WM_READ, false, m_vProcess.Id); if (handle == IntPtr.Zero) { Logger.Error($"Error Code:0x{Marshal.GetLastWin32Error():X8}"); return; } MemoryBasicInformation mem_basic_info = new MemoryBasicInformation(); while (current_address < lproc_max_address) { //Query the current memory page information. bool ok = QueryMemoryBasicInformation(handle, (IntPtr)current_address, ref mem_basic_info); if (!ok) { Logger.Error($"Error Code:0x{Marshal.GetLastWin32Error():X8}"); break; } //Dump JIT code if ((mem_basic_info.Protect & AllocationProtect.PAGE_EXECUTE_READWRITE) > 0 && mem_basic_info.State == MEM_COMMIT) { var region = new MemoryRegion() { BaseAddress = mem_basic_info.BaseAddress, AllocationBase = mem_basic_info.AllocationBase, RegionSize = mem_basic_info.RegionSize }; m_memoryRegionList.Add(region); } //if (Setting.DebugMode) //{ // LogHelper.EncryptLog($"BaseAddress: 0x{mem_basic_info.BaseAddress:X8} RegionSize: 0x{mem_basic_info.RegionSize:X8} AllocationBase: 0x{mem_basic_info.AllocationBase:X8} Protect: {mem_basic_info.Protect} Commit: {mem_basic_info.State==MEM_COMMIT}(0x{mem_basic_info.State:X8})"); //} current_address += mem_basic_info.RegionSize; } CloseHandle(handle); if (m_memoryRegionList.Count == 0) { Logger.Error($"Error:List is Empty"); } }
public void ReadRegions() { MemoryBasicInformation memInfo = new MemoryBasicInformation(); IntPtr current = IntPtr.Zero; while (current.ToInt64() < m_maxAddress.ToInt64() && Kernel32.VirtualQueryEx(m_handle, current, out memInfo, (uint)Marshal.SizeOf(memInfo)) != 0) { if ((int)memInfo.State == 4096 && (int)memInfo.Protect == 4 && (uint)memInfo.RegionSize != 0) { byte[] regionData = new byte[(int)memInfo.RegionSize]; ulong bytesRead = 0; if (!Kernel32.ReadProcessMemory(m_handle, memInfo.BaseAddress, regionData, (ulong)memInfo.RegionSize, ref bytesRead)) { throw new Exception("Failed to read process memory at " + memInfo.BaseAddress + ". Error code: " + Marshal.GetLastWin32Error()); } m_regions.Add(memInfo.BaseAddress, regionData); } current = PointerUtils.Add(memInfo.BaseAddress, memInfo.RegionSize); } Console.WriteLine("Regions: {0}", m_regions.Count); }
/// <summary> /// </summary> /// <param name="handle"> /// </param> /// <param name="search"> /// </param> /// <param name="mbi"> /// </param> /// <returns> /// </returns> private static IntPtr FindKey(SafeMemoryHandle handle, string search, MemoryBasicInformation mbi) { byte[] memCopy = ReadBytes(handle, mbi.BaseAddress, mbi.RegionSize); int len = ASCIIEncoding.ASCII.GetByteCount(search); byte[] src = ASCIIEncoding.ASCII.GetBytes(search); int iPointer = 0; while (iPointer < memCopy.Length - len) { int dPointer = 0; while (dPointer < len) { if (src[dPointer] != memCopy[iPointer + dPointer]) { break; } dPointer++; if (dPointer == len) { return((IntPtr)((int)mbi.BaseAddress + iPointer)); } } iPointer++; } return((IntPtr)0); }
public static UIntPtr VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MemoryBasicInformation lpBuffer) { UIntPtr retVal; if (Is64Bit()) { var tmp64 = new MemoryBasicInformation64(); retVal = Native_VirtualQueryEx(hProcess, lpAddress, out tmp64, new UIntPtr((uint)Marshal.SizeOf(tmp64))); lpBuffer.BaseAddress = tmp64.BaseAddress; lpBuffer.AllocationBase = tmp64.AllocationBase; lpBuffer.AllocationProtect = tmp64.AllocationProtect; lpBuffer.RegionSize = (long)tmp64.RegionSize; lpBuffer.State = tmp64.State; lpBuffer.Protect = tmp64.Protect; lpBuffer.Type = tmp64.Type; return(retVal); } var tmp32 = new MemoryBasicInformation32(); retVal = Native_VirtualQueryEx(hProcess, lpAddress, out tmp32, new UIntPtr((uint)Marshal.SizeOf(tmp32))); lpBuffer.BaseAddress = tmp32.BaseAddress; lpBuffer.AllocationBase = tmp32.AllocationBase; lpBuffer.AllocationProtect = tmp32.AllocationProtect; lpBuffer.RegionSize = tmp32.RegionSize; lpBuffer.State = tmp32.State; lpBuffer.Protect = tmp32.Protect; lpBuffer.Type = tmp32.Type; return(retVal); }
private void listResults_DoubleClick(object sender, EventArgs e) { this.Cursor = Cursors.WaitCursor; try { long s_a = (long)BaseConverter.ToNumberParse(_so.Searcher.Results[listResults.SelectedIndices[0]][0]) + (long)BaseConverter.ToNumberParse(_so.Searcher.Results[listResults.SelectedIndices[0]][1]); var lastInfo = new MemoryBasicInformation(); ProcessHandle phandle; try { phandle = new ProcessHandle(_pid, ProcessAccess.QueryInformation); } catch { this.Cursor = Cursors.Default; return; } phandle.EnumMemory((info) => { if (info.BaseAddress.ToInt64() > s_a) { long selectlength = (long)BaseConverter.ToNumberParse(_so.Searcher.Results[listResults.SelectedIndices[0]][2]); MemoryEditor ed = Program.GetMemoryEditor(_pid, lastInfo.BaseAddress, lastInfo.RegionSize.ToInt64(), new Program.MemoryEditorInvokeAction(delegate(MemoryEditor f) { try { f.ReadOnly = false; f.Activate(); f.Select(s_a - lastInfo.BaseAddress.ToInt64(), selectlength); } catch { } })); return(false); } lastInfo = info; return(true); }); } catch { } this.Cursor = Cursors.Default; }
internal MemoryInformation(MemoryBasicInformation basic_info, string mapped_image_path) { BaseAddress = basic_info.BaseAddress.ToInt64(); AllocationBase = basic_info.AllocationBase.ToInt64(); AllocationProtect = basic_info.AllocationProtect; RegionSize = basic_info.RegionSize.ToInt64(); State = basic_info.State; Protect = basic_info.Protect; Type = basic_info.Type; MappedImagePath = mapped_image_path ?? string.Empty; }
public bool RemapViewBase(MemProtection newProtection = MemProtection.ExecuteWriteCopy) { var mbi = new MemoryBasicInformation(); if (VirtualQueryEx(ProcessHandle, BaseAddress, out mbi, mbi.Size) != 0) { return(RemapView(mbi.BaseAddress, mbi.RegionSize.ToInt32(), newProtection)); } return(false); }
public bool RemapAndPatch(Dictionary <string, Tuple <long, byte[]> > patches) { var mbi = new MemoryBasicInformation(); if (NativeWindows.VirtualQueryEx(ProcessHandle, BaseAddress, out mbi, mbi.Size) != 0) { return(RemapAndPatch(mbi.BaseAddress, mbi.RegionSize.ToInt32(), patches)); } return(false); }
public static bool VirtualQueryEx(Process p, IntPtr baseAddress, out MemoryBasicInformation memoryBasicInformation) { SafeProcessHandle handle = new SafeProcessHandle(p.Handle, false); if (!VirtualQueryEx(handle, baseAddress, out memoryBasicInformation, Marshal.SizeOf <MemoryBasicInformation>())) { Console.WriteLine("Failed to query a region of virtual memory in the remote process"); return(false); } return(true); }
/// <summary> /// Gets the memory region information of a 64 bits process. /// </summary> /// <param name="Address">The address.</param> /// <exception cref="ArgumentException">Address is equal to zero</exception> public bool TryGetMemoryRegionInfo(ulong Address, out MemoryBasicInformation RegionInfo) { if (Address == 0) { throw new ArgumentException("Address is equal to zero"); } var Size = (uint)Marshal.SizeOf <MemoryBasicInformation>(); var Success = VirtualQueryEx(this.Handle, Address, out RegionInfo, Size) > 0; if (!Success) { return(false); } return(true); }
protected void MemInfo(IntPtr pHandle) { var addy = new IntPtr(); while (true) { var memInfo = new MemoryBasicInformation(); var memDump = VirtualQueryEx(pHandle, addy, out memInfo, Marshal.SizeOf(memInfo)); if (memDump == 0) { break; } if ((memInfo.State & 0x1000) != 0 && (memInfo.Protect & 0x100) == 0) { MemoryRegion.Add(memInfo); } addy = new IntPtr(memInfo.BaseAddress.ToInt32() + (int)memInfo.RegionSize); } }
/// <summary> /// Retrieves information about a range of pages within the virtual address space of a specified process. /// </summary> /// <param name="processHandle">A handle to the process whose memory information is queried.</param> /// <param name="baseAddress">A pointer to the base address of the region of pages to be queried.</param> /// <param name="query">The original return value from the native API</param> /// <returns> /// A <see cref="MemoryBasicInformation64" /> structures in which information about the specified page range is /// returned. /// </returns> public static MemoryBasicInformation Query(ASafeMemoryHandle processHandle, IntPtr baseAddress, out IntPtr query) { var ret = new MemoryBasicInformation(); if (Environment.Is64BitProcess) { var sz = MarshalType <MemoryBasicInformation64> .Size; query = Kernel32.VirtualQueryEx(processHandle, baseAddress, out MemoryBasicInformation64 memoryInfo, (IntPtr)sz); if (query == IntPtr.Zero) { return(ret); } ret.BaseAddress = memoryInfo.BaseAddress; ret.AllocationBase = memoryInfo.AllocationBase; ret.AllocationProtect = memoryInfo.AllocationProtect; ret.Protect = memoryInfo.Protect; ret.RegionSize = (Int64)memoryInfo.RegionSize; ret.State = memoryInfo.State; ret.Type = memoryInfo.Type; } else { var sz = MarshalType <MemoryBasicInformation32> .Size; query = Kernel32.VirtualQueryEx(processHandle, baseAddress, out MemoryBasicInformation32 memoryInfo, (IntPtr)sz); if (query == IntPtr.Zero) { return(ret); } ret.BaseAddress = memoryInfo.BaseAddress; ret.AllocationBase = memoryInfo.AllocationBase; ret.AllocationProtect = memoryInfo.AllocationProtect; ret.Protect = memoryInfo.Protect; ret.RegionSize = memoryInfo.RegionSize; ret.State = memoryInfo.State; ret.Type = memoryInfo.Type; } return(ret); }
public unsafe static void GetModules(IntPtr ProcessHandle, string dllName) { MemoryBasicInformation mbi = new MemoryBasicInformation(); MEMORY_SECTION_NAME usSectionName = new MEMORY_SECTION_NAME(); int dwStartAddr = 0x00000000; do { int rt1 = 0; if (ZwQueryVirtualMemory(ProcessHandle, dwStartAddr, MemoryInformationClass.MemoryBasicInformation, &mbi, Marshal.SizeOf(mbi), out rt1) >= 0) { if (mbi.lType == (int)MbiType.MEM_IMAGE) { byte[] bt = new byte[260 * 2]; int rt = 0; int result = ZwQueryVirtualMemory(ProcessHandle, dwStartAddr, MemoryInformationClass.MemorySectionName, out usSectionName, bt.Length, out rt); if (result >= 0) { UnicodeEncoding une = new UnicodeEncoding(); string path = une.GetString(usSectionName.bt).TrimEnd('\0'); if (path.Trim().ToLower().LastIndexOf(dllName) != -1) { dllBaseInfo.BaseAddress = mbi.AllocationBase; dllBaseInfo.path = path; break; } } else { break; } dwStartAddr += (int)mbi.RegionSize; dwStartAddr -= ((int)mbi.RegionSize % 0x10000); } } dwStartAddr += 0x10000; } while (dwStartAddr < 0x7FFEFFFF); }
private void MapView() { var ptr = MapViewOfFile(_sharedMemoryHandle.GetHandle(), FileMapAccess.FileMapRead | FileMapAccess.FileMapWrite, 0, 0, Size); if (ptr == IntPtr.Zero) { throw new InvalidOperationException("File map not valid!"); } if (Size == 0) { var info = new MemoryBasicInformation(); VirtualQuery(ref ptr, ref info, Marshal.SizeOf(info)); Size = info.RegionSize; } ShareMemoryStream = new SharedMemoryStream(ptr, Size); }
internal static extern int VirtualQuery(ref IntPtr lpAddress, ref MemoryBasicInformation lpBuffer, int dwLength);
private void MapView() { var ptr = MapViewOfFile(_sharedMemoryHandle.GetHandle(), FileMapAccess.FileMapRead | FileMapAccess.FileMapWrite, 0, 0, Size); if (ptr == IntPtr.Zero) { throw new InvalidOperationException("File map not valid!"); } if (Size == 0) { var info = new MemoryBasicInformation(); VirtualQuery(ref ptr, ref info, Marshal.SizeOf(info)); Size = info.RegionSize; } ShareMemoryStream = new SharedMemoryStream(ptr, Size); }
public static extern int VirtualQueryEx(IntPtr hProcess, uint lpAddress, out MemoryBasicInformation lpBuffer, uint dwLength);
public bool RemapAndPatch(IntPtr viewAddress, int viewSize, Dictionary <string, Tuple <long, byte[]> > patches) { // Suspend before remapping to prevent crashes. NativeWindows.NtSuspendProcess(ProcessHandle); Data = Read(viewAddress, viewSize); if (Data != null) { var newViewHandle = IntPtr.Zero; var maxSize = new LargeInteger { Quad = viewSize }; if (NativeWindows.NtCreateSection(ref newViewHandle, 0xF001F, IntPtr.Zero, ref maxSize, 0x40u, 0x8000000, IntPtr.Zero) == NtStatus.Success && NativeWindows.NtUnmapViewOfSection(ProcessHandle, viewAddress) == NtStatus.Success) { var viewBase = viewAddress; // Map the view with original protections. var result = NativeWindows.NtMapViewOfSection(newViewHandle, ProcessHandle, ref viewBase, IntPtr.Zero, (ulong)viewSize, out var viewOffset, out var newViewSize, 2, IntPtr.Zero, (int)MemProtection.ExecuteRead); if (result == NtStatus.Success) { // Apply our patches. foreach (var p in patches) { var address = p.Value.Item1; var patch = p.Value.Item2; // We are in a different section here. if (address > Data.Length) { if (address < BaseAddress.ToInt64()) { address += BaseAddress.ToInt64(); } Write(address, patch, MemProtection.ReadWrite); continue; } for (var i = 0; i < patch.Length; i++) { Data[address + i] = patch[i]; } } var viewBase2 = IntPtr.Zero; // Create a writable view to write our patches through to preserve the original protections. result = NativeWindows.NtMapViewOfSection(newViewHandle, ProcessHandle, ref viewBase2, IntPtr.Zero, (uint)viewSize, out var viewOffset2, out var newViewSize2, 2, IntPtr.Zero, (int)MemProtection.ReadWrite); if (result == NtStatus.Success) { // Write our patched data trough the writable view to the memory. if (NativeWindows.WriteProcessMemory(ProcessHandle, viewBase2, Data, viewSize, out var dummy)) { // Unmap them writeable view, it's not longer needed. NativeWindows.NtUnmapViewOfSection(ProcessHandle, viewBase2); var mbi = new MemoryBasicInformation(); // Check if the allocation protections is the right one. if (NativeWindows.VirtualQueryEx(ProcessHandle, BaseAddress, out mbi, mbi.Size) != 0 && mbi.AllocationProtect == MemProtection.ExecuteRead) { // Also check if we can change the page protection. if (!NativeWindows.VirtualProtectEx(ProcessHandle, BaseAddress, 0x4000, (uint)MemProtection.ReadWrite, out var oldProtect)) { NativeWindows.NtResumeProcess(ProcessHandle); } return(true); } } } } Console.WriteLine("Error while mapping the view with the given protection."); } } else { Console.WriteLine("Error while creating the view backup."); } NativeWindows.NtResumeProcess(ProcessHandle); return(false); }
private bool QueryMemoryBasicInformation(IntPtr handle, IntPtr current_address, ref MemoryBasicInformation memoryBasicInformation) { if (isX64()) { MEMORY_BASIC_INFORMATION_X64 mem_basic_info = new MEMORY_BASIC_INFORMATION_X64(); int mem_info_size = Marshal.SizeOf <MEMORY_BASIC_INFORMATION_X64>(); int size = VirtualQueryEx_X64(handle, current_address, out mem_basic_info, (uint)mem_info_size); if (size != mem_info_size) { Logger.Error($"(X64)Error Code:0x{Marshal.GetLastWin32Error():X8}"); return(false); } memoryBasicInformation.RegionSize = mem_basic_info.RegionSize; memoryBasicInformation.BaseAddress = mem_basic_info.BaseAddress; memoryBasicInformation.AllocationProtect = mem_basic_info.AllocationProtect; memoryBasicInformation.AllocationBase = mem_basic_info.AllocationBase; memoryBasicInformation.Type = mem_basic_info.Type; memoryBasicInformation.State = mem_basic_info.State; memoryBasicInformation.Protect = mem_basic_info.Protect; return(true); } else { MEMORY_BASIC_INFORMATION_X86 mem_basic_info = new MEMORY_BASIC_INFORMATION_X86(); int mem_info_size = Marshal.SizeOf <MEMORY_BASIC_INFORMATION_X86>(); int size = VirtualQueryEx_X86(handle, current_address, out mem_basic_info, (uint)mem_info_size); if (size != mem_info_size) { Logger.Error($"(X86)Error Code:0x{Marshal.GetLastWin32Error():X8}"); return(false); } memoryBasicInformation.RegionSize = mem_basic_info.RegionSize; memoryBasicInformation.BaseAddress = mem_basic_info.BaseAddress; memoryBasicInformation.AllocationProtect = mem_basic_info.AllocationProtect; memoryBasicInformation.AllocationBase = mem_basic_info.AllocationBase; memoryBasicInformation.Type = mem_basic_info.Type; memoryBasicInformation.State = mem_basic_info.State; memoryBasicInformation.Protect = mem_basic_info.Protect; return(true); } }
static public extern System.IntPtr VirtualQuery(System.IntPtr address, out MemoryBasicInformation buffer, System.IntPtr length);
private static extern bool VirtualQueryEx(SafeProcessHandle processHandle, IntPtr baseAddress, out MemoryBasicInformation memoryInformation, int length);
public static IntPtr VQueryEx(IntPtr hProcess, IntPtr lpAddress, out MemoryBasicInformation lpBuffer, IntPtr dwLength) { return(VirtualQueryEx(hProcess, lpAddress, out lpBuffer, dwLength)); }
private static extern int VirtualQueryEx(IntPtr Handle, ulong Address, out MemoryBasicInformation Buffer, uint Length);
private static extern int VirtualQuery(IntPtr lpAddress, out MemoryBasicInformation lpBuffer, uint dwLength);
private static extern int UnmanagedVirtualQueryEx(IntPtr hProcess, UIntPtr lpAddress, out MemoryBasicInformation lpBuffer, uint dwLength);
internal static extern bool VirtualQueryEx(SafeHandle processHandle, IntPtr address, out MemoryBasicInformation mbi, int length);
internal static extern bool VirtualQueryEx(SafeProcessHandle processHandle, IntPtr baseAddress, out MemoryBasicInformation buffer, int length);
private bool Start(string appPath) { var startupInfo = new StartupInfo(); var processInfo = new ProcessInformation(); try { Logger.Instance.WriteLine($"Starting WoW ....", LogLevel.Debug); // Start process with suspend flags. if (NativeWindows.CreateProcess(null, $"{appPath}", IntPtr.Zero, IntPtr.Zero, false, 4U, IntPtr.Zero, null, ref startupInfo, out processInfo)) { var memory = new WinMemory(processInfo.ProcessHandle); var modulusOffset = IntPtr.Zero; // Get RSA modulus offset from file. modulusOffset = File.ReadAllBytes(appPath).FindPattern(Patterns.Common.Modulus, memory.BaseAddress.ToInt64()).ToIntPtr(); var sectionOffset = memory.Read(modulusOffset, 0x2000).FindPattern(Patterns.Common.Modulus); modulusOffset = (modulusOffset.ToInt64() + sectionOffset).ToIntPtr(); // Be sure that the modulus is written before the client is initialized. while (memory.Read(modulusOffset, 1)[0] != Patches.Common.Modulus[0]) { memory.Write(modulusOffset, Patches.Common.Modulus); } // Resume the process to initialize it. NativeWindows.NtResumeProcess(processInfo.ProcessHandle); var mbi = new MemoryBasicInformation(); // Wait for the memory region to be initialized. while (NativeWindows.VirtualQueryEx(processInfo.ProcessHandle, memory.BaseAddress, out mbi, mbi.Size) == 0 || mbi.RegionSize.ToInt32() <= 0x1000) { } if (mbi.BaseAddress != IntPtr.Zero) { // Get the memory content. var binary = new byte[0]; // Wait for client initialization. var initOffset = memory?.Read(mbi.BaseAddress, mbi.RegionSize.ToInt32())?.FindPattern(Store.InitializePattern) ?? 0; while (initOffset == 0) { initOffset = memory?.Read(mbi.BaseAddress, mbi.RegionSize.ToInt32())?.FindPattern(Store.InitializePattern) ?? 0; Logger.Instance.WriteLine($"Waiting initialization ...", LogLevel.Debug); } initOffset += BitConverter.ToUInt32(memory.Read((long)initOffset + memory.BaseAddress.ToInt64() + 2, 4), 0) + 10; while (memory?.Read((long)initOffset + memory.BaseAddress.ToInt64(), 1)?[0] == null || memory?.Read((long)initOffset + memory.BaseAddress.ToInt64(), 1)?[0] == 0) { binary = memory.Read(mbi.BaseAddress, mbi.RegionSize.ToInt32()); } // Suspend the process and handle the patches. NativeWindows.NtSuspendProcess(processInfo.ProcessHandle); //! Re-read the memory region for each pattern search. var certBundleOffset = memory.Read(mbi.BaseAddress, mbi.RegionSize.ToInt32()).FindPattern(Store.CertificateBundle); var signatureOffset = memory.Read(mbi.BaseAddress, mbi.RegionSize.ToInt32()).FindPattern(Store.SignatureBundle); if (certBundleOffset == 0 || signatureOffset == 0) { Logger.Instance.WriteLine("Can't find all patterns.", LogLevel.Error); Logger.Instance.WriteLine($"CertBundle: {certBundleOffset == 0}", LogLevel.Error); Logger.Instance.WriteLine($"Signature: {signatureOffset == 0}", LogLevel.Error); } // Add the patches to the patch list. PatchList.Add("CertBundle", Tuple.Create(certBundleOffset, Store.CertificatePatch)); PatchList.Add("Signature", Tuple.Create(signatureOffset, Store.SignaturePatch)); NativeWindows.NtResumeProcess(processInfo.ProcessHandle); if (memory.RemapAndPatch(PatchList)) { Logger.Instance.WriteLine($"Executeable successfully patched!", LogLevel.Debug); binary = null; return(true); } else { binary = null; Logger.Instance.WriteLine("Error while launching the client.", LogLevel.Error); NativeWindows.TerminateProcess(processInfo.ProcessHandle, 0); return(false); } } } } catch (Exception ex) { Logger.Instance.WriteLine(ex.ToString(), LogLevel.Error); NativeWindows.TerminateProcess(processInfo.ProcessHandle, 0); return(false); } return(false); }
protected override void Update() { if (_processHandle == null) { return; } var modules = new Dictionary <IntPtr, ProcessModule>(); try { foreach (var m in _processHandle.GetModules()) { modules.Add(m.BaseAddress, m); } } catch { } var memoryInfo = new Dictionary <IntPtr, MemoryBasicInformation>(); var newdictionary = new Dictionary <IntPtr, MemoryItem>(this.Dictionary); _processHandle.EnumMemory(info => { if ((this.IgnoreFreeRegions && info.State != MemoryState.Free) || !this.IgnoreFreeRegions) { memoryInfo.Add(info.BaseAddress, info); } return(true); }); // look for freed memory regions foreach (IntPtr address in Dictionary.Keys) { if (!memoryInfo.ContainsKey(address)) { this.OnDictionaryRemoved(this.Dictionary[address]); newdictionary.Remove(address); } } string lastModuleName = null; IntPtr lastModuleAddress = IntPtr.Zero; int lastModuleSize = 0; foreach (IntPtr address in memoryInfo.Keys) { MemoryBasicInformation info = memoryInfo[address]; if (!this.Dictionary.ContainsKey(address)) { MemoryItem item = new MemoryItem { RunId = this.RunCount, Address = address, Size = info.RegionSize.ToInt64(), Type = info.Type, State = info.State, Protection = info.Protect }; if (modules.ContainsKey(item.Address)) { lastModuleName = modules[item.Address].BaseName; lastModuleAddress = modules[item.Address].BaseAddress; lastModuleSize = modules[item.Address].Size; } if ( item.Address.IsGreaterThanOrEqualTo(lastModuleAddress) && item.Address.CompareTo(lastModuleAddress.Increment(lastModuleSize)) == -1 ) { item.ModuleName = lastModuleName; } else { item.ModuleName = null; } newdictionary.Add(address, item); this.OnDictionaryAdded(item); } else { MemoryItem item = this.Dictionary[address]; if ( info.RegionSize.ToInt64() != item.Size || info.Type != item.Type || info.State != item.State || info.Protect != item.Protection ) { MemoryItem newitem = item.Clone() as MemoryItem; newitem.Size = info.RegionSize.ToInt64(); newitem.Type = info.Type; newitem.State = info.State; newitem.Protection = info.Protect; newdictionary[address] = newitem; this.OnDictionaryModified(item, newitem); } } } this.Dictionary = newdictionary; }
internal static extern IntPtr VirtualQuery(IntPtr address, ref MemoryBasicInformation buffer, int length);
public static extern int VirtualQueryEx(SafeMemoryHandle hProcess, IntPtr lpAddress, out MemoryBasicInformation lpBuffer, int dwLength);
public static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpBaseAddress, out MemoryBasicInformation mbi, int dwSize);
internal static extern int VirtualQuery(ref IntPtr lpAddress, ref MemoryBasicInformation lpBuffer, int dwLength);
public static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MemoryBasicInformation lpBuffer, int dwLength);
/// <summary> /// </summary> /// <param name="handle"> /// </param> /// <param name="search"> /// </param> /// <param name="mbi"> /// </param> /// <returns> /// </returns> private static IntPtr FindKey(SafeMemoryHandle handle, string search, MemoryBasicInformation mbi) { byte[] memCopy = ReadBytes(handle, mbi.BaseAddress, mbi.RegionSize); int len = ASCIIEncoding.ASCII.GetByteCount(search); byte[] src = ASCIIEncoding.ASCII.GetBytes(search); int iPointer = 0; while (iPointer < memCopy.Length - len) { int dPointer = 0; while (dPointer < len) { if (src[dPointer] != memCopy[iPointer + dPointer]) { break; } dPointer++; if (dPointer == len) { return (IntPtr)((int)mbi.BaseAddress + iPointer); } } iPointer++; } return (IntPtr)0; }