Exemple #1
0
 internal PageInfo(MEMORY_BASIC_INFORMATION mbi)
 {
     _address         = mbi.BaseAddress;
     _size            = mbi.RegionSize;
     _protectionFlags = (MemoryProtectionFlags)mbi.Protect;
     _typeFlags       = (MemoryTypeFlags)mbi.Type;
 }
Exemple #2
0
        public void VirtualProtectEx()
        {
            IntPtr handle = ProcessMemory.OpenProcess(ProcessAccessFlags.All, _processId);

            Assert.IsFalse(handle == IntPtr.Zero);

            IntPtr address = ProcessMemory.VirtualAllocEx(handle, IntPtr.Zero, (IntPtr)1024, AllocationType.Reserve | AllocationType.Commit, MemoryProtectionFlags.ExecuteReadWrite);

            MemoryProtectionFlags oldProtection = default;

            Assert.IsTrue(ProcessMemory.VirtualProtectEx(handle, address, (IntPtr)1024, MemoryProtectionFlags.NoAccess, ref oldProtection));

            Assert.IsTrue(oldProtection == MemoryProtectionFlags.ExecuteReadWrite);

            try
            {
                Marshal.WriteInt32(address, 1337);
                throw new Exception();
            }
            catch
            {
            }

            Assert.IsTrue(ProcessMemory.VirtualFreeEx(handle, address, IntPtr.Zero, FreeType.Release));

            ProcessMemory.CloseHandle(handle);
        }
 /// <summary>
 ///     Initializes a new instance of the <see cref="RemoteAllocation" /> class.
 /// </summary>
 /// <param name="memorySharp">The reference of the <see cref="MemorySharp" /> object.</param>
 /// <param name="size">The size of the allocated memory.</param>
 /// <param name="protection">The protection of the allocated memory.</param>
 /// <param name="mustBeDisposed">The allocated memory will be released when the finalizer collects the object.</param>
 internal RemoteAllocation(MemorySharp memorySharp, int size, MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite, bool mustBeDisposed = true)
     : base(memorySharp, MemoryCore.Allocate(memorySharp.Handle, size, protection))
 {
     // Set local vars
     MustBeDisposed = mustBeDisposed;
     IsDisposed = false;
 }
Exemple #4
0
        /// <summary>
        ///     Changes the protection on a region of committed pages in the virtual address space of a specified process.
        /// </summary>
        /// <param name="processHandle">A handle to the process whose memory protection is to be changed.</param>
        /// <param name="address">
        ///     A pointer to the base address of the region of pages whose access protection attributes are to be
        ///     changed.
        /// </param>
        /// <param name="size">The size of the region whose access protection attributes are changed, in bytes.</param>
        /// <param name="protection">The memory protection option.</param>
        /// <returns>The old protection of the region in a structure.</returns>
        public MemoryProtectionFlags ChangeMemoryProtection(MemoryProtectionFlags protection)
        {
            // Create the variable storing the old protection of the memory page
            MemoryProtectionFlags oldProtection;

            bool result;

            // Change the protection in the target process
            if (Internal)
            {
                result = NativeMethods.VirtualProtect(BaseAddress, Size, protection, out oldProtection);
            }
            else
            {
                result = NativeMethods.VirtualProtectEx(Handle, BaseAddress, Size, protection, out oldProtection);
            }

            if (result)
            {
                // Return the old protection
                return(oldProtection);
            }

            // Else the protection couldn't be changed, throws an exception
            throw new Win32Exception(
                      string.Format("Couldn't change the protection of the memory at 0x{0} of {1} byte(s) to {2}.",
                                    BaseAddress.ToString("X"), Size, protection));
        }
Exemple #5
0
        public RemoteAllocation Allocate(int size, MemoryProtectionFlags protection, bool mustBeDisposed = true)
        {
            var memory = new RemoteAllocation(m_Process, size, protection, mustBeDisposed);

            m_RemoteAllocations.Add(memory);
            return(memory);
        }
Exemple #6
0
        /// <summary>
        /// Reserves a region of memory within the virtual address space of a specified process.
        /// </summary>
        /// <param name="processHandle">The handle to a process.</param>
        /// <param name="allocAddress">The rough address of where the allocation should take place.</param>
        /// <param name="size">The size of the region of memory to allocate, in bytes.</param>
        /// <param name="protectionFlags">The memory protection for the region of pages to be allocated.</param>
        /// <param name="allocationFlags">The type of memory allocation.</param>
        /// <returns>The base address of the allocated region</returns>
        public static IntPtr Allocate(
            IntPtr processHandle,
            IntPtr allocAddress,
            Int32 size,
            MemoryProtectionFlags protectionFlags = MemoryProtectionFlags.ExecuteReadWrite,
            MemoryAllocationFlags allocationFlags = MemoryAllocationFlags.Commit | MemoryAllocationFlags.Reserve)
        {
            if (allocAddress != IntPtr.Zero)
            {
                /* A specific address has been given. We will modify it to support the following constraints:
                 *  - Aligned by 0x10000 / 65536
                 *  - Pointing to an unallocated region of memory
                 *  - Within +/- 2GB (using 1GB for safety) of address space of the originally specified address, such as to always be in range of a far jump instruction
                 * Note: A retry count has been put in place because VirtualAllocEx with an allocAddress specified may be invalid by the time we request the allocation.
                 */

                IntPtr result     = IntPtr.Zero;
                Int32  retryCount = 0;

                // Request all chunks of unallocated memory. These will be very large in a 64-bit process.
                IEnumerable <MemoryBasicInformation64> freeMemory = Memory.QueryUnallocatedMemory(
                    processHandle,
                    allocAddress.Subtract(Int32.MaxValue >> 1, wrapAround: false),
                    allocAddress.Add(Int32.MaxValue >> 1, wrapAround: false));

                // Convert to normalized regions
                IEnumerable <NormalizedRegion> regions = freeMemory.Select(x => new NormalizedRegion(x.BaseAddress, x.RegionSize.ToInt32()));

                // Chunk the large regions into smaller regions based on the allocation size (minimum size is the alloc alignment to prevent creating too many chunks)
                List <NormalizedRegion> subRegions = new List <NormalizedRegion>();
                foreach (NormalizedRegion region in regions)
                {
                    region.BaseAddress = region.BaseAddress.Subtract(region.BaseAddress.Mod(Memory.AllocAlignment), wrapAround: false);
                    IEnumerable <NormalizedRegion> chunkedRegions = region.ChunkNormalizedRegion(Math.Max(size, Memory.AllocAlignment)).Take(128).Where(x => x.RegionSize >= size);
                    subRegions.AddRange(chunkedRegions);
                }

                do
                {
                    // Sample a random chunk and attempt to allocate the memory
                    result = subRegions.ElementAt(StaticRandom.Next(0, subRegions.Count())).BaseAddress;
                    result = NativeMethods.VirtualAllocEx(processHandle, result, size, allocationFlags, protectionFlags);

                    if (result != IntPtr.Zero || retryCount >= Memory.AllocateRetryCount)
                    {
                        break;
                    }

                    retryCount++;
                }while (result == IntPtr.Zero);

                return(result);
            }
            else
            {
                // Allocate a memory page
                return(NativeMethods.VirtualAllocEx(processHandle, allocAddress, size, allocationFlags, protectionFlags));
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="RemoteAllocation"/> class.
 /// </summary>
 /// <param name="memorySharp">The reference of the <see cref="MemorySharp"/> object.</param>
 /// <param name="size">The size of the allocated memory.</param>
 /// <param name="protection">The protection of the allocated memory.</param>
 /// <param name="mustBeDisposed">The allocated memory will be released when the finalizer collects the object.</param>
 internal RemoteAllocation(MemorySharp memorySharp, int size, MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite,
                           bool mustBeDisposed = true)
     : base(memorySharp, MemoryCore.Allocate(memorySharp.Handle, size, protection))
 {
     // Set local vars
     MustBeDisposed = mustBeDisposed;
     IsDisposed     = false;
 }
Exemple #8
0
 public AAlloc()
 {
     Name       = "";
     Address    = UIntPtr.Zero;
     Size       = 0;
     Preferred  = UIntPtr.Zero;
     Protection = MemoryProtectionFlags.ExecuteReadWrite;
 }
Exemple #9
0
 public AAlloc(String name, UIntPtr address, UInt32 size, UIntPtr preferred, MemoryProtectionFlags protection)
 {
     Name       = name;
     Address    = address;
     Size       = size;
     Preferred  = preferred;
     Protection = protection;
 }
Exemple #10
0
 /// <summary>
 /// Allocates a region of memory within the virtual address space of the remote process.
 /// </summary>
 /// <param name="size">The size of the memory to allocate.</param>
 /// <param name="protection">The protection of the memory to allocate.</param>
 /// <param name="mustBeDisposed">The allocated memory will be released when the finalizer collects the object.</param>
 /// <returns>A new instance of the <see cref="RemoteAllocation"/> class.</returns>
 public RemoteAllocation Allocate(int size, MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite, bool mustBeDisposed = true)
 {
     // Allocate a memory space
     var memory = new RemoteAllocation(MemorySharp, size, protection, mustBeDisposed);
     // Add the memory in the list
     InternalRemoteAllocations.Add(memory);
     return memory;
 }
Exemple #11
0
        public MemoryProtection(SafeMemoryHandle handle, IntPtr address, int size, bool @internal = true, MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite)
        {
            BaseAddress   = address;
            NewProtection = protection;
            Size          = size;
            Internal      = @internal;
            Handle        = handle;

            OldProtection = ChangeMemoryProtection(protection);
        }
        public MemoryProtection(SafeMemoryHandle handle, IntPtr address, int size,bool @internal = true, MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite)
        {
            BaseAddress = address;
            NewProtection = protection;
            Size = size;
            Internal = @internal;
            Handle = handle;

            OldProtection = ChangeMemoryProtection(protection);
        }
Exemple #13
0
        /// <summary>
        ///     Allocates a region of memory within the virtual address space of the remote process.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="size">The size of the memory to allocate.</param>
        /// <param name="protection">The protection of the memory to allocate.</param>
        /// <param name="mustBeDisposed">The allocated memory will be released when the finalizer collects the object.</param>
        public IAAllocatedMemory Allocate(string name, int size,
                                          MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite, bool mustBeDisposed = true)
        {
            // Allocate a memory space
            var memory = new AAllocatedMemory(Process, name, size, protection, mustBeDisposed);

            // Add the memory in the list
            InternalRemoteAllocations.Add(memory);
            return(memory);
        }
Exemple #14
0
 /// <summary>Changes the protection of the n next bytes in remote process.</summary>
 /// <param name="handle"></param>
 /// <param name="size">The size of the memory to change.</param>
 /// <param name="protection">The new protection to apply.</param>
 /// <param name="mustBeDisposed">
 ///   The resource will be automatically disposed when the finalizer
 ///   collects the object.
 /// </param>
 /// <returns>A new instance of the <see cref="MemoryProtection" /> class.</returns>
 public MemoryProtection ChangeProtection(SafeMemoryHandle handle,
                                          int size,
                                          MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite,
                                          bool mustBeDisposed = true)
 {
     return(new MemoryProtection(handle,
                                 BaseAddress,
                                 size,
                                 protection,
                                 mustBeDisposed));
 }
Exemple #15
0
        public static IntPtr Allocate(SafeMemoryHandle handle, int size, MemoryProtectionFlags protectionFlags = MemoryProtectionFlags.ExecuteReadWrite, MemoryAllocationFlags allocationFlags = MemoryAllocationFlags.Commit)
        {
            var address    = IntPtr.Zero;
            var regionSize = new IntPtr(size);

            if (NativeMethods.NtAllocateVirtualMemory(handle, ref address, 0x7FFF_FFFF, ref regionSize, allocationFlags, protectionFlags) == 0)
            {
                return(address);
            }
            return(NativeMethods.VirtualAllocEx(handle, IntPtr.Zero, size, allocationFlags, protectionFlags));
        }
 /// <summary>
 ///     Initializes a new instance of the <see cref="AAllocatedMemory" /> class.
 /// </summary>
 /// <param name="processPlus">The reference of the <see cref="AProcessSharp" /> object.</param>
 /// <param name="name"></param>
 /// <param name="size">The size of the allocated memory.</param>
 /// <param name="protection">The protection of the allocated memory.</param>
 /// <param name="mustBeDisposed">The allocated memory will be released when the finalizer collects the object.</param>
 public AAllocatedMemory(AProcessSharp processPlus, string name, int size,
                         MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite,
                         bool mustBeDisposed = true)
     : base(processPlus, AMemoryHelper.Allocate(processPlus.Handle, size, protection))
 {
     // Set local vars
     Identifier     = name;
     MustBeDisposed = mustBeDisposed;
     IsDisposed     = false;
     Size           = size;
 }
Exemple #17
0
        public void CacheMemoryRegions()
        {
            memoryRegions.Clear();
            InitMemoryRegions();

            MemoryProtectionFlags MemFlagsExecutable =
                MemoryProtectionFlags.PAGE_EXECUTE |
                MemoryProtectionFlags.PAGE_EXECUTE_READ |
                MemoryProtectionFlags.PAGE_EXECUTE_READWRITE |
                MemoryProtectionFlags.PAGE_EXECUTE_WRITECOPY;

            MemoryProtectionFlags MemFlagsWriteable =
                MemoryProtectionFlags.PAGE_EXECUTE_READWRITE |
                MemoryProtectionFlags.PAGE_EXECUTE_WRITECOPY |
                MemoryProtectionFlags.PAGE_READWRITE |
                MemoryProtectionFlags.PAGE_WRITECOPY;

            int regionInfoSize = Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION));

            for (long scanAddress = 0; scanAddress < Int64.MaxValue;)
            {
                MEMORY_BASIC_INFORMATION regionInfo;
                int result = VirtualQueryEx(cachedProcessHandle, (IntPtr)scanAddress, out regionInfo, (uint)regionInfoSize);
                if (result != regionInfoSize)
                {
                    break;
                }

                bool bIsCommited        = (regionInfo.State & MemoryStateFlags.MEM_COMMIT) != 0;
                bool bIsGuarded         = (regionInfo.Protect & MemoryProtectionFlags.PAGE_GUARD) != 0;
                bool bIsWritebale       = (regionInfo.Protect & MemFlagsWriteable) != 0;
                bool bIsExecutable      = (regionInfo.Protect & MemFlagsExecutable) != 0;
                bool bShouldCacheRegion = bIsCommited && !bIsGuarded && (bIsWritebale || bIsExecutable);

                Logger.WriteLine("scan:0x{0}, size:0x{1}, state:[{2}], protect:[{3}], type:0x{4} => {5}",
                                 scanAddress.ToString("x"), regionInfo.RegionSize.ToString("x"), regionInfo.State, regionInfo.Protect, regionInfo.Type.ToString("x"),
                                 bShouldCacheRegion ? "CACHE" : "meh");

                if (bShouldCacheRegion)
                {
                    MemoryRegionFlags storeType = (bIsWritebale ? MemoryRegionFlags.Writeable : 0) | (bIsExecutable ? MemoryRegionFlags.Executable : 0);
                    MemoryRegionInfo  storeInfo = new MemoryRegionInfo
                    {
                        BaseAddress = regionInfo.BaseAddress,
                        Size        = regionInfo.RegionSize,
                        Type        = storeType,
                    };

                    memoryRegions.Add(storeInfo);
                }

                scanAddress = (long)regionInfo.BaseAddress + (long)regionInfo.RegionSize;
            }
        }
        /// <summary>
        ///     Initializes a new instance of the <see cref="MemoryProtection" /> class.
        /// </summary>
        /// <param name="memorySharp">The reference of the <see cref="MemorySharp" /> object.</param>
        /// <param name="baseAddress">The base address of the memory to change the protection.</param>
        /// <param name="size">The size of the memory to change.</param>
        /// <param name="protection">The new protection to apply.</param>
        /// <param name="mustBeDisposed">The resource will be automatically disposed when the finalizer collects the object.</param>
        public MemoryProtection(MemorySharp memorySharp, IntPtr baseAddress, int size, MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite, bool mustBeDisposed = true)
        {
            // Save the parameters
            _memorySharp = memorySharp;
            BaseAddress = baseAddress;
            NewProtection = protection;
            Size = size;
            MustBeDisposed = mustBeDisposed;

            // Change the memory protection
            OldProtection = MemoryCore.ChangeProtection(_memorySharp.Handle, baseAddress, size, protection);
        }
Exemple #19
0
        /// <summary>
        /// Gets regions of memory allocated in the remote process based on provided parameters
        /// </summary>
        /// <param name="requiredProtection">Protection flags required to be present</param>
        /// <param name="excludedProtection">Protection flags that must not be present</param>
        /// <param name="allowedTypes">Memory types that can be present</param>
        /// <param name="startAddress">The start address of the query range</param>
        /// <param name="endAddress">The end address of the query range</param>
        /// <returns>A collection of pointers to virtual pages in the target process</returns>
        public IEnumerable <NormalizedRegion> GetVirtualPages(
            MemoryProtectionEnum requiredProtection,
            MemoryProtectionEnum excludedProtection,
            MemoryTypeEnum allowedTypes,
            IntPtr startAddress,
            IntPtr endAddress)
        {
            MemoryProtectionFlags requiredFlags = 0;
            MemoryProtectionFlags excludedFlags = 0;

            if ((requiredProtection & MemoryProtectionEnum.Write) != 0)
            {
                requiredFlags |= MemoryProtectionFlags.ExecuteReadWrite;
                requiredFlags |= MemoryProtectionFlags.ReadWrite;
            }

            if ((requiredProtection & MemoryProtectionEnum.Execute) != 0)
            {
                requiredFlags |= MemoryProtectionFlags.Execute;
                requiredFlags |= MemoryProtectionFlags.ExecuteRead;
                requiredFlags |= MemoryProtectionFlags.ExecuteReadWrite;
                requiredFlags |= MemoryProtectionFlags.ExecuteWriteCopy;
            }

            if ((requiredProtection & MemoryProtectionEnum.CopyOnWrite) != 0)
            {
                requiredFlags |= MemoryProtectionFlags.WriteCopy;
                requiredFlags |= MemoryProtectionFlags.ExecuteWriteCopy;
            }

            if ((excludedProtection & MemoryProtectionEnum.Write) != 0)
            {
                excludedFlags |= MemoryProtectionFlags.ExecuteReadWrite;
                excludedFlags |= MemoryProtectionFlags.ReadWrite;
            }

            if ((excludedProtection & MemoryProtectionEnum.Execute) != 0)
            {
                excludedFlags |= MemoryProtectionFlags.Execute;
                excludedFlags |= MemoryProtectionFlags.ExecuteRead;
                excludedFlags |= MemoryProtectionFlags.ExecuteReadWrite;
                excludedFlags |= MemoryProtectionFlags.ExecuteWriteCopy;
            }

            if ((excludedProtection & MemoryProtectionEnum.CopyOnWrite) != 0)
            {
                excludedFlags |= MemoryProtectionFlags.WriteCopy;
                excludedFlags |= MemoryProtectionFlags.ExecuteWriteCopy;
            }

            return(Memory.VirtualPages(this.SystemProcess == null ? IntPtr.Zero : this.SystemProcess.Handle, startAddress, endAddress, requiredFlags, excludedFlags, allowedTypes)
                   .Select(x => new NormalizedRegion(x.BaseAddress, x.RegionSize.ToUInt64())));
        }
 internal MemoryProtection(RemoteProcess process, IntPtr baseAddress, long size, MemoryProtectionFlags newProtect = MemoryProtectionFlags.ExecuteReadWrite, bool mustBeDisposed = true)
 {
     m_Process      = process;
     MustBeDisposed = mustBeDisposed;
     BaseAddress    = baseAddress;
     Size           = size;
     NewProtection  = newProtect;
     if (!NativeMethods.VirtualProtectEx(m_Process.Handle, baseAddress, size, newProtect, out var oldProtect))
     {
         throw new Win32Exception();
     }
     OldProtection = oldProtect;
 }
Exemple #21
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MemoryProtection"/> class.
        /// </summary>
        /// <param name="memorySharp">The reference of the <see cref="MemorySharp"/> object.</param>
        /// <param name="baseAddress">The base address of the memory to change the protection.</param>
        /// <param name="size">The size of the memory to change.</param>
        /// <param name="protection">The new protection to apply.</param>
        /// <param name="mustBeDisposed">The resource will be automatically disposed when the finalizer collects the object.</param>
        public MemoryProtection(MemorySharp memorySharp, IntPtr baseAddress, int size, MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite,
                                bool mustBeDisposed = true)
        {
            // Save the parameters
            _memorySharp   = memorySharp;
            BaseAddress    = baseAddress;
            NewProtection  = protection;
            Size           = size;
            MustBeDisposed = mustBeDisposed;

            // Change the memory protection
            OldProtection = MemoryCore.ChangeProtection(_memorySharp.Handle, baseAddress, size, protection);
        }
        public static uint NtAllocateVirtualMemory(
            IntPtr handle,
            IntPtr size,
            AllocationType allocationType,
            MemoryProtectionFlags memoryProtection,
            out IntPtr address)
        {
            IL.DeclareLocals(
                new LocalVar("result", typeof(uint)),
                new LocalVar("localAddress", typeof(IntPtr)));

            address = default;

            Ldloca("localAddress");
            Initobj(typeof(IntPtr));

            Ldarg(nameof(handle));

            Ldloca("localAddress");
            Conv_U();

            Ldc_I4_0();
            Conv_I();

            Ldarga(nameof(size));
            Conv_U();

            Ldarg(nameof(allocationType));
            Ldarg(nameof(memoryProtection));

            Ldsfld(new FieldRef(typeof(NtDll), nameof(_ntAllocateVirtualMemory)));
            Calli(new StandAloneMethodSig(
                      CallingConvention.StdCall,
                      typeof(uint),
                      typeof(IntPtr),
                      typeof(IntPtr).MakePointerType(),
                      typeof(IntPtr),
                      typeof(IntPtr).MakePointerType(),
                      typeof(AllocationType),
                      typeof(MemoryProtectionFlags)));

            Stloc("result");

            Ldarg(nameof(address));
            Ldloc("localAddress");
            Stind_I();

            Ldloc("result");
            return(IL.Return <uint>());
        }
Exemple #23
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="MemoryProtection" /> class.
        /// </summary>
        /// <param name="handle">The reference of the <see cref="SafeMemoryHandle" /> object.</param>
        /// <param name="baseAddress">The base address of the memory to change the protection.</param>
        /// <param name="size">The size of the memory to change.</param>
        /// <param name="protection">The new protection to apply.</param>
        /// <param name="mustBeDisposed">The resource will be automatically disposed when the finalizer collects the object.</param>
        public MemoryProtection(SafeMemoryHandle handle, IntPtr baseAddress, int size,
                                MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite,
                                bool mustBeDisposed = true)
        {
            // Save the parameters
            Handle         = handle;
            BaseAddress    = baseAddress;
            NewProtection  = protection;
            Size           = size;
            MustBeDisposed = mustBeDisposed;

            // Change the memory protection
            OldProtection = MemoryHelper.ChangeProtection(Handle, baseAddress, size, protection);
        }
Exemple #24
0
        /// <summary>
        /// Reserves a region of memory within the virtual address space of a specified process.
        /// </summary>
        /// <param name="processHandle">The handle to a process.</param>
        /// <param name="size">The size of the region of memory to allocate, in bytes.</param>
        /// <param name="protectionFlags">The memory protection for the region of pages to be allocated.</param>
        /// <param name="allocationFlags">The type of memory allocation.</param>
        /// <returns>The base address of the allocated region.</returns>
        public static IntPtr Allocate(SafeMemoryHandle processHandle, int size, MemoryProtectionFlags protectionFlags = MemoryProtectionFlags.ExecuteReadWrite,
            MemoryAllocationFlags allocationFlags = MemoryAllocationFlags.Commit)
        {
            // Check if the handle is valid
            HandleManipulator.ValidateAsArgument(processHandle, "processHandle");
            
            // Allocate a memory page
            var ret = NativeMethods.VirtualAllocEx(processHandle, IntPtr.Zero, size, allocationFlags, protectionFlags);

            // Check whether the memory page is valid
            if (ret != IntPtr.Zero)
                return ret;

            // If the pointer isn't valid, throws an exception
            throw new Win32Exception(string.Format("Couldn't allocate memory of {0} byte(s).", size));
        }
Exemple #25
0
        /// <summary>
        /// Reserves a region of memory within the virtual address space of a specified process.
        /// </summary>
        /// <param name="processHandle">The handle to a process.</param>
        /// <param name="size">The size of the region of memory to allocate, in bytes.</param>
        /// <param name="protectionFlags">The memory protection for the region of pages to be allocated.</param>
        /// <param name="allocationFlags">The type of memory allocation.</param>
        /// <returns>The base address of the allocated region.</returns>
        public static IntPtr Allocate(SafeMemoryHandle processHandle, int size, MemoryProtectionFlags protectionFlags = MemoryProtectionFlags.ExecuteReadWrite,
                                      MemoryAllocationFlags allocationFlags = MemoryAllocationFlags.Commit)
        {
            // Check if the handle is valid
            HandleManipulator.ValidateAsArgument(processHandle, "processHandle");

            // Allocate a memory page
            var ret = NativeMethods.VirtualAllocEx(processHandle, IntPtr.Zero, size, allocationFlags, protectionFlags);

            // Check whether the memory page is valid
            if (ret != IntPtr.Zero)
            {
                return(ret);
            }

            // If the pointer isn't valid, throws an exception
            throw new Win32Exception(string.Format("Couldn't allocate memory of {0} byte(s).", size));
        }
Exemple #26
0
        /// <summary>
        ///     Changes the protection on a region of committed pages in the virtual address space of a specified process.
        /// </summary>
        /// <param name="processHandle">A handle to the process whose memory protection is to be changed.</param>
        /// <param name="address">
        ///     A pointer to the base address of the region of pages whose access protection attributes are to be
        ///     changed.
        /// </param>
        /// <param name="size">The size of the region whose access protection attributes are changed, in bytes.</param>
        /// <param name="protection">The memory protection option.</param>
        /// <returns>The old protection of the region in a <see cref="Native.MemoryBasicInformation" /> structure.</returns>
        public static MemoryProtectionFlags ChangeProtection(SafeMemoryHandle processHandle, IntPtr address, int size, MemoryProtectionFlags protection)
        {
            // Check if the handles are valid
            HandleManipulator.ValidateAsArgument(processHandle, "processHandle");
            HandleManipulator.ValidateAsArgument(address, "address");

            // Create the variable storing the old protection of the memory page
            MemoryProtectionFlags oldProtection;

            // Change the protection in the target process
            if (NativeMethods.VirtualProtectEx(processHandle, address, size, protection, out oldProtection))
            {
                // Return the old protection
                return oldProtection;
            }

            // Else the protection couldn't be changed, throws an exception
            throw new Win32Exception(string.Format("Couldn't change the protection of the memory at 0x{0} of {1} byte(s) to {2}.", address.ToString("X"), size, protection));
        }
Exemple #27
0
        /// <summary>
        ///     Changes the protection on a region of committed pages in the virtual address space of a specified process.
        /// </summary>
        /// <param name="processHandle">A handle to the process whose memory protection is to be changed.</param>
        /// <param name="address">
        ///     A pointer to the base address of the region of pages whose access protection attributes are to be
        ///     changed.
        /// </param>
        /// <param name="size">The size of the region whose access protection attributes are changed, in bytes.</param>
        /// <param name="protection">The memory protection option.</param>
        /// <returns>The old protection of the region in a <see cref="MemoryBasicInformation" /> structure.</returns>
        public static MemoryProtectionFlags ChangeProtection(SafeMemoryHandle processHandle, IntPtr address, int size,
                                                             MemoryProtectionFlags protection)
        {
            // Check if the handles are valid
            HandleManipulator.ValidateAsArgument(processHandle, "processHandle");
            HandleManipulator.ValidateAsArgument(address, "address");

            // Create the variable storing the old protection of the memory page
            MemoryProtectionFlags oldProtection;

            // Change the protection in the target process
            if (Kernel32.VirtualProtectEx(processHandle, address, size, protection, out oldProtection))
            {
                // Return the old protection
                return(oldProtection);
            }

            // Else the protection couldn't be changed, throws an exception
            throw new Win32Exception(
                      $"Couldn't change the protection of the memory at 0x{address.ToString("X")} of {size} byte(s) to {protection}.");
        }
Exemple #28
0
        /// <summary>
        /// </summary>
        /// <param name="processHandle">
        /// </param>
        /// <param name="address">
        /// </param>
        /// <param name="size">
        /// </param>
        /// <param name="protection">
        /// </param>
        /// <returns>
        /// </returns>
        /// <exception cref="Win32Exception">
        /// </exception>
        public static MemoryProtectionFlags ChangeProtection(
            SafeMemoryHandle processHandle,
            IntPtr address,
            int size,
            MemoryProtectionFlags protection)
        {
            // Create the variable storing the old protection of the memory page
            MemoryProtectionFlags oldProtection;

            // Change the protection in the target process
            if (VirtualProtectEx(processHandle, address, size, protection, out oldProtection))
            {
                // Return the old protection
                return(oldProtection);
            }

            // Else the protection couldn't be changed, throws an exception
            throw new Win32Exception(
                      string.Format(
                          "Couldn't change the protection of the memory at 0x{0} of {1} byte(s) to {2}.",
                          address.ToString("X"),
                          size,
                          protection));
        }
Exemple #29
0
 /// <summary>
 ///     Allocates a region of memory within the virtual address space of the remote process.
 /// </summary>
 /// <param name="size">The size of the memory to allocate.</param>
 /// <param name="protection">The protection of the memory to allocate.</param>
 /// <param name="mustBeDisposed">The allocated memory will be released when the finalizer collects the object.</param>
 /// <returns>A new instance of the <see cref="RemoteAllocation" /> class.</returns>
 public RemoteAllocation Allocate(int size, MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite, bool mustBeDisposed = true)
 {
     // Allocate a memory space
     var memory = new RemoteAllocation(MemorySharp, size, protection, mustBeDisposed);
     // Add the memory in the list
     InternalRemoteAllocations.Add(memory);
     return memory;
 }
Exemple #30
0
 public static extern IntPtr VirtualAllocEx(SafeMemoryHandle hProcess, IntPtr lpAddress, int dwSize,
     MemoryAllocationFlags flAllocationType, MemoryProtectionFlags flProtect);
Exemple #31
0
 public static extern bool VirtualProtect(IntPtr lpAddress, int dwSize,
     MemoryProtectionFlags flNewProtect, out MemoryProtectionFlags lpflOldProtect);
        /// <summary>
        ///     Changes the protection on a region of committed pages in the virtual address space of a specified process.
        /// </summary>
        /// <param name="processHandle">A handle to the process whose memory protection is to be changed.</param>
        /// <param name="address">
        ///     A pointer to the base address of the region of pages whose access protection attributes are to be
        ///     changed.
        /// </param>
        /// <param name="size">The size of the region whose access protection attributes are changed, in bytes.</param>
        /// <param name="protection">The memory protection option.</param>
        /// <returns>The old protection of the region in a structure.</returns>
        public MemoryProtectionFlags ChangeMemoryProtection(MemoryProtectionFlags protection)
        {
            // Create the variable storing the old protection of the memory page
            MemoryProtectionFlags oldProtection;

            bool result;
            // Change the protection in the target process
            if (Internal)
                result = NativeMethods.VirtualProtect(BaseAddress, Size, protection, out oldProtection);
            else
                result = NativeMethods.VirtualProtectEx(Handle, BaseAddress, Size, protection, out oldProtection);

            if (result)
            {
                // Return the old protection
                return oldProtection;
            }

            // Else the protection couldn't be changed, throws an exception
            throw new Win32Exception(
                string.Format("Couldn't change the protection of the memory at 0x{0} of {1} byte(s) to {2}.",
                    BaseAddress.ToString("X"), Size, protection));
        }
Exemple #33
0
 /// <summary>
 /// Changes the protection of the n next bytes in remote process.
 /// </summary>
 /// <param name="protection">The new protection to apply.</param>
 /// <param name="mustBeDisposed">The resource will be automatically disposed when the finalizer collects the object.</param>
 /// <returns>A new instance of the <see cref="MemoryProtection"/> class.</returns>
 public MemoryProtection ChangeProtection(MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite, bool mustBeDisposed = true)
 {
     return(new MemoryProtection(MemorySharp, BaseAddress, Information.RegionSize, protection, mustBeDisposed));
 }
Exemple #34
0
        /// <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="startAddress">A pointer to the starting address of the region of pages to be queried.</param>
        /// <param name="endAddress">A pointer to the ending address of the region of pages to be queried.</param>
        /// <param name="requiredProtection">Protection flags required to be present.</param>
        /// <param name="excludedProtection">Protection flags that must not be present.</param>
        /// <param name="allowedTypes">Memory types that can be present.</param>
        /// <returns>
        /// A collection of <see cref="MemoryBasicInformation64"/> structures containing info about all virtual pages in the target process.
        /// </returns>
        public static IEnumerable <MemoryBasicInformation64> VirtualPages(
            IntPtr processHandle,
            IntPtr startAddress,
            IntPtr endAddress,
            MemoryProtectionFlags requiredProtection,
            MemoryProtectionFlags excludedProtection,
            MemoryTypeEnum allowedTypes)
        {
            if (startAddress.ToUInt64() >= endAddress.ToUInt64())
            {
                yield return(new MemoryBasicInformation64());
            }

            Boolean wrappedAround = false;
            Int32   queryResult;

            // Enumerate the memory pages
            do
            {
                // Allocate the structure to store information of memory
                MemoryBasicInformation64 memoryInfo = new MemoryBasicInformation64();

                if (!Environment.Is64BitProcess)
                {
                    // 32 Bit struct is not the same
                    MemoryBasicInformation32 memoryInfo32 = new MemoryBasicInformation32();

                    // Query the memory region (32 bit native method)
                    queryResult = NativeMethods.VirtualQueryEx(processHandle, startAddress, out memoryInfo32, Marshal.SizeOf(memoryInfo32));

                    // Copy from the 32 bit struct to the 64 bit struct
                    memoryInfo.AllocationBase    = memoryInfo32.AllocationBase;
                    memoryInfo.AllocationProtect = memoryInfo32.AllocationProtect;
                    memoryInfo.BaseAddress       = memoryInfo32.BaseAddress;
                    memoryInfo.Protect           = memoryInfo32.Protect;
                    memoryInfo.RegionSize        = memoryInfo32.RegionSize;
                    memoryInfo.State             = memoryInfo32.State;
                    memoryInfo.Type = memoryInfo32.Type;
                }
                else
                {
                    // Query the memory region (64 bit native method)
                    queryResult = NativeMethods.VirtualQueryEx(processHandle, startAddress, out memoryInfo, Marshal.SizeOf(memoryInfo));
                }

                // Increment the starting address with the size of the page
                IntPtr previousFrom = startAddress;
                startAddress = startAddress.Add(memoryInfo.RegionSize);

                if (previousFrom.ToUInt64() > startAddress.ToUInt64())
                {
                    wrappedAround = true;
                }

                // Ignore free memory. These are unallocated memory regions.
                if ((memoryInfo.State & MemoryStateFlags.Free) != 0)
                {
                    continue;
                }

                // At least one readable memory flag is required
                if ((memoryInfo.Protect & MemoryProtectionFlags.ReadOnly) == 0 && (memoryInfo.Protect & MemoryProtectionFlags.ExecuteRead) == 0 &&
                    (memoryInfo.Protect & MemoryProtectionFlags.ExecuteReadWrite) == 0 && (memoryInfo.Protect & MemoryProtectionFlags.ReadWrite) == 0)
                {
                    continue;
                }

                // Do not bother with this shit, this memory is not worth scanning
                if ((memoryInfo.Protect & MemoryProtectionFlags.ZeroAccess) != 0 || (memoryInfo.Protect & MemoryProtectionFlags.NoAccess) != 0 || (memoryInfo.Protect & MemoryProtectionFlags.Guard) != 0)
                {
                    continue;
                }

                // Enforce allowed types
                switch (memoryInfo.Type)
                {
                case MemoryTypeFlags.None:
                    if ((allowedTypes & MemoryTypeEnum.None) == 0)
                    {
                        continue;
                    }

                    break;

                case MemoryTypeFlags.Private:
                    if ((allowedTypes & MemoryTypeEnum.Private) == 0)
                    {
                        continue;
                    }

                    break;

                case MemoryTypeFlags.Image:
                    if ((allowedTypes & MemoryTypeEnum.Image) == 0)
                    {
                        continue;
                    }

                    break;

                case MemoryTypeFlags.Mapped:
                    if ((allowedTypes & MemoryTypeEnum.Mapped) == 0)
                    {
                        continue;
                    }

                    break;
                }

                // Ensure at least one required protection flag is set
                if (requiredProtection != 0 && (memoryInfo.Protect & requiredProtection) == 0)
                {
                    continue;
                }

                // Ensure no ignored protection flags are set
                if (excludedProtection != 0 && (memoryInfo.Protect & excludedProtection) != 0)
                {
                    continue;
                }

                // Return the memory page
                yield return(memoryInfo);
            }while (startAddress.ToUInt64() < endAddress.ToUInt64() && queryResult != 0 && !wrappedAround);
        }
Exemple #35
0
 public static extern bool VirtualProtectEx(SafeMemoryHandle hProcess, IntPtr lpAddress, int dwSize,
     MemoryProtectionFlags flNewProtect, out MemoryProtectionFlags lpflOldProtect);
Exemple #36
0
        /// <summary>
        /// Gets regions of memory allocated in the remote process based on provided parameters.
        /// </summary>
        /// <param name="requiredProtection">Protection flags required to be present.</param>
        /// <param name="excludedProtection">Protection flags that must not be present.</param>
        /// <param name="allowedTypes">Memory types that can be present.</param>
        /// <param name="startAddress">The start address of the query range.</param>
        /// <param name="endAddress">The end address of the query range.</param>
        /// <returns>A collection of pointers to virtual pages in the target process.</returns>
        public IEnumerable <NormalizedRegion> GetVirtualPages(
            Process process,
            MemoryProtectionEnum requiredProtection,
            MemoryProtectionEnum excludedProtection,
            MemoryTypeEnum allowedTypes,
            UInt64 startAddress,
            UInt64 endAddress)
        {
            MemoryProtectionFlags requiredFlags = 0;
            MemoryProtectionFlags excludedFlags = 0;

            if ((requiredProtection & MemoryProtectionEnum.Write) != 0)
            {
                requiredFlags |= MemoryProtectionFlags.ExecuteReadWrite;
                requiredFlags |= MemoryProtectionFlags.ReadWrite;
            }

            if ((requiredProtection & MemoryProtectionEnum.Execute) != 0)
            {
                requiredFlags |= MemoryProtectionFlags.Execute;
                requiredFlags |= MemoryProtectionFlags.ExecuteRead;
                requiredFlags |= MemoryProtectionFlags.ExecuteReadWrite;
                requiredFlags |= MemoryProtectionFlags.ExecuteWriteCopy;
            }

            if ((requiredProtection & MemoryProtectionEnum.CopyOnWrite) != 0)
            {
                requiredFlags |= MemoryProtectionFlags.WriteCopy;
                requiredFlags |= MemoryProtectionFlags.ExecuteWriteCopy;
            }

            if ((excludedProtection & MemoryProtectionEnum.Write) != 0)
            {
                excludedFlags |= MemoryProtectionFlags.ExecuteReadWrite;
                excludedFlags |= MemoryProtectionFlags.ReadWrite;
            }

            if ((excludedProtection & MemoryProtectionEnum.Execute) != 0)
            {
                excludedFlags |= MemoryProtectionFlags.Execute;
                excludedFlags |= MemoryProtectionFlags.ExecuteRead;
                excludedFlags |= MemoryProtectionFlags.ExecuteReadWrite;
                excludedFlags |= MemoryProtectionFlags.ExecuteWriteCopy;
            }

            if ((excludedProtection & MemoryProtectionEnum.CopyOnWrite) != 0)
            {
                excludedFlags |= MemoryProtectionFlags.WriteCopy;
                excludedFlags |= MemoryProtectionFlags.ExecuteWriteCopy;
            }

            IEnumerable <MemoryBasicInformation64> memoryInfo = WindowsMemoryQuery.VirtualPages(process == null ? IntPtr.Zero : process.Handle, startAddress, endAddress, requiredFlags, excludedFlags, allowedTypes);

            IList <NormalizedRegion> regions = new List <NormalizedRegion>();

            foreach (MemoryBasicInformation64 next in memoryInfo)
            {
                if (next.RegionSize < ChunkSize)
                {
                    regions.Add(new NormalizedRegion(next.BaseAddress.ToUInt64(), next.RegionSize.ToInt32()));
                }
                else
                {
                    // This region requires chunking
                    Int64  remaining          = next.RegionSize;
                    UInt64 currentBaseAddress = next.BaseAddress.ToUInt64();

                    while (remaining >= ChunkSize)
                    {
                        regions.Add(new NormalizedRegion(currentBaseAddress, ChunkSize));

                        remaining         -= ChunkSize;
                        currentBaseAddress = currentBaseAddress.Add(ChunkSize, wrapAround: false);
                    }

                    if (remaining > 0)
                    {
                        regions.Add(new NormalizedRegion(currentBaseAddress, remaining.ToInt32()));
                    }
                }
            }

            return(regions);
        }
Exemple #37
0
        /// <summary>
        /// Changes the protection on a region of committed pages in the virtual address space of a specified process.
        /// </summary>
        /// <param name="processHandle">A handle to the process whose memory protection is to be changed.</param>
        /// <param name="address">A pointer to the base address of the region of pages whose access protection attributes are to be changed.</param>
        /// <param name="size">The size of the region whose access protection attributes are changed, in bytes.</param>
        /// <param name="protection">The memory protection option.</param>
        /// <returns>The old protection of the region in a <see cref="MemoryBasicInformation32"/> structure.</returns>
        public static MemoryProtectionFlags ChangeProtection(IntPtr processHandle, IntPtr address, Int32 size, MemoryProtectionFlags protection)
        {
            // Create the variable storing the old protection of the memory page
            MemoryProtectionFlags oldProtection;

            // Change the protection in the target process
            NativeMethods.VirtualProtectEx(processHandle, address, size, protection, out oldProtection);

            return(oldProtection);
        }
Exemple #38
0
 public static extern IntPtr VirtualAllocEx(SafeMemoryHandle hProcess, IntPtr lpAddress, int dwSize,
                                            MemoryAllocationFlags flAllocationType, MemoryProtectionFlags flProtect);
 internal RemoteAllocation(RemoteProcess process, int size, MemoryProtectionFlags protect, bool mustBeDisposed) :
     base(process, MemoryManager.Allocate(process.Handle, size, protect))
 {
     MustBeDisposed = mustBeDisposed;
 }
Exemple #40
0
 public static extern bool VirtualProtectEx(SafeMemoryHandle hProcess, IntPtr lpAddress, int dwSize,
                                            MemoryProtectionFlags flNewProtect, out MemoryProtectionFlags lpflOldProtect);