Пример #1
0
        /// <summary>
        /// Allocates memory that satisfies a set size constraint and proximity to a set address.
        /// </summary>
        /// <param name="size">The minimum size of the memory to be allocated.</param>
        /// <param name="minimumAddress">The minimum absolute address to allocate in.</param>
        /// <param name="maximumAddress">The maximum absolute address to allocate in.</param>
        /// <param name="retryCount">In the case the memory allocation fails; the amount of times memory allocation is to be retried.</param>
        /// <exception cref="System.Exception">Memory allocation failure due to possible race condition with other process/process itself/Windows scheduling.</exception>
        /// <remarks>
        ///     This function is virtually the same to running <see cref="FindBufferLocation"/> and then running Windows'
        ///     VirtualAlloc yourself. Except for the extra added safety of mutual exclusion (Mutex).
        ///     The memory is allocated with the PAGE_EXECUTE_READWRITE permissions.
        /// </remarks>
        public BufferAllocationProperties Allocate(int size, int minimumAddress = 0x10000, int maximumAddress = 0x7FFFFFFF, int retryCount = 3)
        {
            if (minimumAddress <= 0)
            {
                throw new ArgumentException("Please do not set the minimum address to 0 or negative. It collides with the return values of Windows API functions" +
                                            "where e.g. 0 is returned on failure but you can also allocate successfully on 0.");
            }

            // Keep retrying memory allocation.
            _allocateMemoryMutex.WaitOne();

            try
            {
                return(Run(retryCount, () =>
                {
                    var memoryLocation = FindBufferLocation(size, minimumAddress, maximumAddress, true);
                    var virtualAllocFunction = VirtualAllocUtility.GetVirtualAllocFunction(Process);
                    var result = virtualAllocFunction(Process.Handle, memoryLocation.MemoryAddress, (ulong)memoryLocation.Size);

                    if (result == IntPtr.Zero)
                    {
                        throw new Exception("Failed to allocate memory using VirtualAlloc/VirtualAllocEx");
                    }

                    _allocateMemoryMutex.ReleaseMutex();
                    return memoryLocation;
                }));
            }
            catch (Exception)
            {
                _allocateMemoryMutex.ReleaseMutex();
                throw;
            }
        }
Пример #2
0
        /// <summary>
        /// Allocates memory to store a <see cref="MemoryBuffer"/>s inside the target process/
        /// </summary>
        internal static void AllocateBuffer(Process process, nuint bufferAddress, int bufferSize)
        {
            // Get the function, commit the pages and check.
            var virtualAllocFunction = VirtualAllocUtility.GetVirtualAllocFunction(process);
            var address = virtualAllocFunction(process.Handle, bufferAddress, (uint)bufferSize);

            if (address == UIntPtr.Zero)
            {
                throw new Exception($"Failed to allocate MemoryBuffer of size {bufferSize} at address {bufferAddress}. Last Win32 Error: {Marshal.GetLastWin32Error()}");
            }
        }