/// <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); }
/// <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."); } }
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); }
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")); }