Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        /// <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;
        }