/// <summary>
        /// Writes your own memory bytes into process' memory and gives you the address
        /// for the memory location of the written bytes.
        /// </summary>
        /// <param name="bytesToWrite">Individual bytes to be written onto the buffer.</param>
        /// <returns>Pointer to the passed in bytes written to memory. Null pointer, if it cannot fit into the buffer.</returns>
        public IntPtr Add(byte[] bytesToWrite)
        {
            // Read the buffer contents back from memory.
            BufferHeader = Bindings.TargetProcess.ReadMemoryExternal <MemoryBufferHeader>(BaseBufferAddress);

            // Do not add beyond buffer size.
            if (!CheckItemSize(bytesToWrite.Length))
            {
                return(IntPtr.Zero);
            }

            // If the buffer is invalid, do not add either.
            if (BaseBufferAddress == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }

            // Do the append operation.
            IntPtr appendAddress = (IntPtr)((ulong)BaseBufferAddress + BufferHeader.BufferOffset);

            Bindings.TargetProcess.WriteMemoryExternal(appendAddress, ref bytesToWrite);

            // Set current offset.
            BufferHeader.BufferOffset += (uint)bytesToWrite.Length;

            // Write the new buffer contents back to memory.
            Bindings.TargetProcess.WriteMemoryExternal(BaseBufferAddress, ref BufferHeader);

            return(appendAddress);
        }
        /// <summary>
        /// Creates a new buffer in a specified location in memory with a specified size.
        /// This constructor is not intended to be used directly, consider using <see cref="MemoryBufferManager"/> instead.
        /// While you can use this constructor if you're sure the memory pages to be allocated are free, it is not recommended.
        /// MemoryBuffer creates a buffer if it doesn't exist, if the supplied address is already allocated and is not a buffer, sets the Base Address to 0.
        /// </summary>
        /// <param name="bufferAddress">Specifies the base address of the new buffer to be created.</param>
        /// <param name="bufferSize">The size of the buffer to be created. Note that the buffer size includes the buffer header!</param>
        public unsafe MemoryBuffer(IntPtr bufferAddress, uint bufferSize)
        {
            // Set the base address for the buffer.
            this.BaseBufferAddress = bufferAddress;

            // Get our info on desired page from VirtualQueryEx.
            MEMORY_BASIC_INFORMATION memoryInformation = new MEMORY_BASIC_INFORMATION();

            VirtualQueryEx(Bindings.TargetProcess.ProcessHandle, bufferAddress, out memoryInformation, (uint)sizeof(MEMORY_BASIC_INFORMATION));

            // If the page is already occupied, check and assign the buffer header.
            if (memoryInformation.State != PageState.Free)
            {
                // Check if buffer already exists by reading an existing or nonexisting header.
                MemoryBufferHeader bufferHeader = Bindings.TargetProcess.ReadMemoryExternal <MemoryBufferHeader>(BaseBufferAddress);

                // If buffer already exists, set buffer's header.
                if (bufferHeader.ReloadedMagic == MemoryBufferHeader.RELOADED_MAGIC)
                {
                    BufferHeader = bufferHeader;
                }
                else
                {
                    BaseBufferAddress = IntPtr.Zero;
                }
            }

            // Else if the pages are free.
            else
            {
                // Commit the pages.
                IntPtr virtualAllocAddress = VirtualAllocEx
                                             (
                    Bindings.TargetProcess.ProcessHandle,
                    BaseBufferAddress,
                    bufferSize,
                    AllocationTypes.Reserve | AllocationTypes.Commit,
                    MemoryProtections.ExecuteReadWrite
                                             );

                // MemoryBuffer.
                if (virtualAllocAddress == IntPtr.Zero)
                {
                    Bindings.PrintError("[FATAL] Failed to allocate MemoryBuffer.");
                    throw new Exception("Failed to allocate MemoryBuffer.");
                }

                // Write a new Buffer
                BufferHeader = new MemoryBufferHeader()
                {
                    BufferOffset  = (uint)sizeof(MemoryBufferHeader),
                    BufferSize    = bufferSize,
                    ReloadedMagic = MemoryBufferHeader.RELOADED_MAGIC
                };

                Bindings.TargetProcess.WriteMemoryExternal(BaseBufferAddress, ref BufferHeader);
            }
        }
Example #3
0
        /// <summary>
        /// Returns true if the supplied memory address is the start of a Reloaded Buffer.
        /// Else false.
        /// </summary>
        /// <param name="address">Address to check if it contains the start of a buffer, a start of a region of pages obtained from GetPages().</param>
        private static bool IsBuffer(IntPtr address)
        {
            try
            {
                // Check if buffer already exists by reading an existing or nonexisting header.
                MemoryBufferHeader bufferHeader = Bindings.TargetProcess.ReadMemoryExternal <MemoryBufferHeader>(address);

                if (bufferHeader.ReloadedMagic == MemoryBufferHeader.RELOADED_MAGIC)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            catch (Exception)
            {
                return(false);
            }
        }