/// <summary>
        /// Creates a <see cref="MemoryBuffer"/> and attempts to retrieve it by searching for it in memory.
        /// </summary>
        private void GetBuffers(MemoryBufferHelper bufferHelper)
        {
            // Options
            int size        = 4096;
            int repetitions = 128;
            int increment   = 2048;

            // Setup
            MemoryBuffer[] memoryBuffers = new MemoryBuffer[repetitions];

            for (int x = 0; x < repetitions; x++)
            {
                int newSize = size + (x * increment);
                memoryBuffers[x] = bufferHelper.CreateMemoryBuffer(newSize);
            }

            // Search for our buffers with exact originally given buffer sizes and try find the exact buffer.
            for (int x = 0; x < repetitions; x++)
            {
                int newSize = size + (x * increment);
                var buffers = bufferHelper.FindBuffers(newSize);

                if (!buffers.Contains(memoryBuffers[x]))
                {
                    Assert.True(false, $"Failed to find existing buffer in memory of minimum size {newSize} bytes.");
                }
            }

            // Cleanup.
            for (int x = 0; x < repetitions; x++)
            {
                Internal.Testing.Buffers.FreeBuffer(memoryBuffers[x]);
            }
        }
        /// <summary>
        /// [Testing Purposes]
        /// Creates a buffer, then frees the memory belonging to the buffer.
        /// </summary>
        private void CreatePrivateBufferBase(MemoryBufferHelper bufferHelper)
        {
            var buffer = bufferHelper.CreatePrivateMemoryBuffer(4096);

            // Cleanup
            buffer.Dispose();
        }
        /*
         * ----------
         * Core Tests
         * ----------
         */


        /// <summary>
        /// [Testing Purposes]
        /// Creates a buffer, then frees the memory belonging to the buffer.
        /// </summary>
        private void CreateBufferBase(MemoryBufferHelper bufferHelper)
        {
            var buffer = bufferHelper.CreateMemoryBuffer(4096);

            // Cleanup
            Internal.Testing.Buffers.FreeBuffer(buffer);
        }
        /// <summary>
        /// Attempts to create a set of <see cref="MemoryBuffer"/>s at the beginning and end of the
        /// address space, and then find the given buffers.
        /// </summary>
        private unsafe void GetBuffersInRange(MemoryBufferHelper bufferHelper, UIntPtr maxApplicationAddress)
        {
            /* The reason that testing the upper half is sufficient is because the buffer allocation
             * functions work in such a manner that they allocate from the lowest address.
             * As such, normally the only allocated addresses would be in the lower half... until enough memory is allocated to cross the upper half.
             */

            // Minimum address is start of upper half of 32/64 bit address range.
            // Maximum is the maximum address in 32/64 bit address range.
            long minAddress = (long)maxApplicationAddress - ((long)maxApplicationAddress / 2);
            long maxAddress = (long)maxApplicationAddress;

            GetBuffersInRange(bufferHelper, (nuint)minAddress, (nuint)maxAddress);
        }
        /// <summary>
        /// Same as <see cref="GetBuffersInRange"/>, except disables the caching when acquiring <see cref="MemoryBuffer"/>s.
        /// </summary>
        private unsafe void GetBuffersInRangeNoCache(MemoryBufferHelper bufferHelper, IntPtr maxApplicationAddress)
        {
            /* The reason that testing the upper half is sufficient is because the buffer allocation
             * functions work in such a manner that they allocate from the lowest address.
             * As such, normally the only allocated addresses would be in the lower half... until enough memory is allocated to cross the upper half.
             */

            // Options
            int sizeStart   = 0;    // Default page size for x86 and x64.
            int repetitions = 128;
            int increment   = 4096; // Equal to allocation granularity.

            // Minimum address is start of upper half of 32/64 bit address range.
            // Maximum is the maximum address in 32/64 bit address range.
            long minAddress = (long)maxApplicationAddress - ((long)maxApplicationAddress / 2);
            long maxAddress = (long)maxApplicationAddress;

            MemoryBuffer[] buffers = new MemoryBuffer[repetitions];

            // Allocate <repetitions> buffers, and try to find them all.
            for (int x = 0; x < repetitions; x++)
            {
                int newSize = sizeStart + (x * increment);
                buffers[x] = bufferHelper.CreateMemoryBuffer(newSize, (long)minAddress, (long)maxAddress);
            }

            // Validate whether each buffer is present and in range.
            for (int x = 0; x < repetitions; x++)
            {
                int newSize      = sizeStart + (x * increment);
                var foundBuffers = bufferHelper.FindBuffers(newSize, (IntPtr)minAddress, (IntPtr)maxAddress, false);

                if (!foundBuffers.Contains(buffers[x]))
                {
                    Assert.True(false, $"Failed to find existing buffer in memory of minimum size {newSize} bytes.");
                }

                foreach (var buffer in foundBuffers)
                {
                    AssertBufferInRange(buffer, (IntPtr)minAddress, (IntPtr)maxAddress);
                }
            }

            // Cleanup
            for (int x = 0; x < buffers.Length; x++)
            {
                Internal.Testing.Buffers.FreeBuffer(buffers[x]);
            }
        }
        /// <summary>
        /// Returns the max addressable address of the process sitting behind the <see cref="MemoryBufferHelper"/>.
        /// </summary>
        private IntPtr GetMaxAddress(MemoryBufferHelper helper)
        {
            // Is this Windows on Windows 64? (x86 app running on x64 Windows)
            IsWow64Process(helper.Process.Handle, out bool isWow64);
            GetSystemInfo(out SYSTEM_INFO systemInfo);
            long maxAddress = 0x7FFFFFFF;

            // Check if 64bit.
            if (systemInfo.wProcessorArchitecture == ProcessorArchitecture.PROCESSOR_ARCHITECTURE_AMD64 && !isWow64)
            {
                maxAddress = (long)systemInfo.lpMaximumApplicationAddress;
            }

            return((IntPtr)maxAddress);
        }
예제 #7
0
        /// <summary>
        /// Attempts to allocate the memory to store the result received from FASM assembler.
        /// </summary>
        private void AllocateResult(int resultSize, int retryCount, MemoryBufferHelper bufferHelper)
        {
            // Attempt to allocate memory retryCount times.
            for (int x = 0; x < retryCount; x++)
            {
                var bufferLocation = bufferHelper.FindBufferLocation(resultSize, 1, Int32.MaxValue);
                _resultAddress = VirtualAlloc(bufferLocation.MemoryAddress, (UIntPtr)bufferLocation.Size, MEM_ALLOCATION_TYPE.MEM_COMMIT | MEM_ALLOCATION_TYPE.MEM_RESERVE, MEM_PROTECTION.PAGE_EXECUTE_READWRITE);

                if (_resultAddress != IntPtr.Zero)
                {
                    _resultSize = bufferLocation.Size;
                    break;
                }
            }

            if (_resultAddress == IntPtr.Zero)
            {
                throw new FasmWrapperException("Failed to allocate result memory for Assembler.");
            }
        }
예제 #8
0
        private static void Inject(Process process, DalamudStartInfo startInfo)
        {
            var nethostName = "nethost.dll";
            var bootName    = "Dalamud.Boot.dll";

            var nethostPath = Path.GetFullPath(nethostName);
            var bootPath    = Path.GetFullPath(bootName);

            // ======================================================

            using var injector = new Injector(process);

            injector.LoadLibrary(nethostPath, out _);
            injector.LoadLibrary(bootPath, out var bootModule);

            // ======================================================

            var startInfoJson  = JsonConvert.SerializeObject(startInfo);
            var startInfoBytes = Encoding.UTF8.GetBytes(startInfoJson);

            using var startInfoBuffer = new MemoryBufferHelper(process).CreatePrivateMemoryBuffer(startInfoBytes.Length + 0x8);
            var startInfoAddress = startInfoBuffer.Add(startInfoBytes);

            if (startInfoAddress == IntPtr.Zero)
            {
                throw new Exception("Unable to allocate start info JSON");
            }

            injector.GetFunctionAddress(bootModule, "Initialize", out var initAddress);
            injector.CallRemoteFunction(initAddress, startInfoAddress, out var exitCode);

            // ======================================================

            if (exitCode > 0)
            {
                Log.Error($"Dalamud.Boot::Initialize returned {exitCode}");
                return;
            }

            Log.Information("Done");
        }
        /// <summary>
        /// Returns the max addressable address of the process sitting behind the <see cref="MemoryBufferHelper"/>.
        /// </summary>
        private UIntPtr GetMaxAddress(MemoryBufferHelper helper, bool largeAddressAware = false)
        {
            // Is this Windows on Windows 64? (x86 app running on x64 Windows)
            IsWow64Process(helper.Process.Handle, out bool isWow64);
            GetSystemInfo(out SYSTEM_INFO systemInfo);
            long maxAddress = 0x7FFFFFFF;

            // Check for large address aware
            if (largeAddressAware && IntPtr.Size == 4 && (uint)systemInfo.lpMaximumApplicationAddress > maxAddress)
            {
                maxAddress = (uint)systemInfo.lpMaximumApplicationAddress;
            }

            // Check if 64bit.
            if (systemInfo.wProcessorArchitecture == ProcessorArchitecture.PROCESSOR_ARCHITECTURE_AMD64 && !isWow64)
            {
                maxAddress = (long)systemInfo.lpMaximumApplicationAddress;
            }

            return((UIntPtr)maxAddress);
        }
예제 #10
0
 static Utilities()
 {
     Assembler     = new Assembler.Assembler();
     _bufferHelper = new MemoryBufferHelper(Process.GetCurrentProcess());
 }
 /* Create the common static members. */
 static Assembler()
 {
     _processMemory = new Memory.Sources.Memory();
     _bufferHelper  = new MemoryBufferHelper(Process.GetCurrentProcess());
 }
 private MemoryBuffer CreatePrivateMemoryBuffer(MemoryBufferHelper helper)
 {
     return(helper.CreatePrivateMemoryBuffer(4096));
 }
 public MemoryBufferTests()
 {
     _bufferHelper         = new MemoryBufferHelper(Process.GetCurrentProcess());
     _externalBufferHelper = new MemoryBufferHelper(Process.Start("HelloWorld.exe"));
 }