protected override nint AllocateChunk(nint hint) { while (true) { var mbi = new WinApi.MEMORY_BASIC_INFORMATION(); if (WinApi.VirtualQuery(hint, ref mbi, Marshal.SizeOf <WinApi.MEMORY_BASIC_INFORMATION>()) == 0) { throw Win32Error($"Failed to query memory information of 0x{(long) hint:X9}"); } if (mbi.State == WinApi.PageState.MEM_FREE) { var nextAddress = RoundUp(mbi.BaseAddress, ALLOCATION_UNIT); var d = nextAddress - mbi.BaseAddress; if (d >= 0 && mbi.RegionSize - d >= ALLOCATION_UNIT) { hint = nextAddress; break; } } hint = mbi.BaseAddress + mbi.RegionSize; } var chunk = WinApi.VirtualAlloc(hint, ALLOCATION_UNIT, WinApi.AllocationType.MEM_RESERVE, WinApi.ProtectConstant.PAGE_NOACCESS); if (chunk == 0) { throw Win32Error($"Failed to reserve address: 0x{(long) hint:X8}"); } var addr = WinApi.VirtualAlloc(chunk, PAGE_SIZE, WinApi.AllocationType.MEM_COMMIT, WinApi.ProtectConstant.PAGE_READWRITE); if (addr == 0) { var error = Marshal.GetLastWin32Error(); WinApi.VirtualFree(chunk, 0, WinApi.FreeType.MEM_RELEASE); throw Win32Error($"Failed to commit memory 0x{(long) addr:X8} for read-write access for 0x{(long) chunk:X8}", error); } return(chunk); }
protected override nint AllocateChunk(nint hint) { while (true) { var mbi = new WinApi.MEMORY_BASIC_INFORMATION(); if (WinApi.VirtualQuery(hint, ref mbi, Marshal.SizeOf <WinApi.MEMORY_BASIC_INFORMATION>()) == 0) { throw new Win32Exception(Marshal.GetLastWin32Error()); } if (mbi.State == WinApi.PageState.MEM_FREE) { var nextAddress = RoundUp(mbi.BaseAddress, ALLOCATION_UNIT); var d = nextAddress - mbi.BaseAddress; if (d >= 0 && mbi.RegionSize - d >= ALLOCATION_UNIT) { hint = nextAddress; break; } } hint = mbi.BaseAddress + mbi.RegionSize; } var chunk = WinApi.VirtualAlloc(hint, ALLOCATION_UNIT, WinApi.AllocationType.MEM_RESERVE, WinApi.ProtectConstant.PAGE_NOACCESS); if (chunk == 0) { throw new Win32Exception(Marshal.GetLastWin32Error()); } var addr = WinApi.VirtualAlloc(chunk, PAGE_SIZE, WinApi.AllocationType.MEM_COMMIT, WinApi.ProtectConstant.PAGE_READWRITE); if (addr == 0) { int error = Marshal.GetLastWin32Error(); WinApi.VirtualFree(chunk, 0, WinApi.FreeType.MEM_RELEASE); throw new Win32Exception(error); } return(chunk); }
protected override IntPtr AllocateChunk(IntPtr hint) { while (true) { var mbi = new WinApi.MEMORY_BASIC_INFORMATION(); if (WinApi.VirtualQuery(hint, ref mbi, Marshal.SizeOf <WinApi.MEMORY_BASIC_INFORMATION>()) == 0) { throw new Win32Exception(Marshal.GetLastWin32Error()); } if (mbi.State == WinApi.PageState.MEM_FREE) { long nextAddress = RoundUp(mbi.BaseAddress.ToInt64(), ALLOCATION_UNIT); long d = nextAddress - mbi.BaseAddress.ToInt64(); if (d >= 0 && mbi.RegionSize.ToInt64() - d >= ALLOCATION_UNIT) { hint = (IntPtr)nextAddress; break; } } hint = (IntPtr)(mbi.BaseAddress.ToInt64() + mbi.RegionSize.ToInt64()); } var chunk = WinApi.VirtualAlloc(hint, (UIntPtr)ALLOCATION_UNIT, WinApi.AllocationType.MEM_RESERVE, WinApi.ProtectConstant.PAGE_NOACCESS); if (chunk == null) { throw new Win32Exception(Marshal.GetLastWin32Error()); } var addr = WinApi.VirtualAlloc(chunk, (UIntPtr)PAGE_SIZE, WinApi.AllocationType.MEM_COMMIT, WinApi.ProtectConstant.PAGE_READWRITE); if (addr == IntPtr.Zero) { int error = Marshal.GetLastWin32Error(); WinApi.VirtualFree(chunk, UIntPtr.Zero, WinApi.FreeType.MEM_RELEASE); throw new Win32Exception(error); } return(chunk); }
/// <summary> /// Searches through the target process's memory and identifies regions that are of interest, when scanning. /// Creates a Region and saves it to the list of Regions for future scans. /// </summary> /// <param name="minAddress">The minimum address that should be used, during this search.</param> /// <param name="maxAddress">The maximum address that should be used, during this search.</param> /// <returns>Returns true on successfully identifying regions in the target's memory.</returns> public bool IdentifyRegions(ulong minAddress = 0, ulong maxAddress = 0) { if (!this.IsOpen) { this.Status.Log( "Unable to identify regions, because the target process has not been opened.", Logger.Level.HIGH); return false; } if (maxAddress == 0) { maxAddress = (ulong)SysInteractor.MaxAddress; } WinApi.MEMORY_BASIC_INFORMATION mbi = new WinApi.MEMORY_BASIC_INFORMATION(); ulong address = minAddress; bool result = true; this.Regions.Clear(); while (address < maxAddress) { result = WinApi.VirtualQueryEx(Proc.Handle, (IntPtr)address, out mbi, (uint)Marshal.SizeOf(mbi)); if (result && IsReadable(mbi)) { Region r = new Region((IntPtr)address, (uint)mbi.RegionSize, mbi.Protect, mbi.Type); this.Regions.Add(r); } address += (ulong)mbi.RegionSize; } return this.Regions.Count > 0; }