public void TestReadMemory() { // Allocate memory in the host process const int testRegionSize = 32; var testRegionAddress = _memoryModule.AllocateMemory(_hostProcessName, testRegionSize); // Write a test array of bytes into memory var testArray = new byte[] { 0xFF, 0x01, 0x5A, 0xFF, 0x22, 0x00 }; _memoryModule.WriteMemory(_hostProcessName, testRegionAddress, testArray); // Read the test array of bytes from memory var readTestArray = _memoryModule.ReadMemory(_hostProcessName, testRegionAddress, testArray.Length); Assert.True(testArray.SequenceEqual(readTestArray)); // Free the memory that was allocated _memoryModule.FreeMemory(_hostProcessName, testRegionAddress); }
internal bool Unlink(Process process, string dllPath) { // Get the id of the process var processId = process.Id; // Get the size of the process basic information structure var pbiSize = Marshal.SizeOf(typeof(Native.ProcessBasicInformation)); // Allocate memory for a buffer to store the process basic information var pbiBuffer = Marshal.AllocHGlobal(pbiSize); // Open a handle to the process var processHandle = process.SafeHandle; // Query the process and store the process basic information in the buffer Native.NtQueryInformationProcess(processHandle, 0, pbiBuffer, pbiSize, 0); // Read the process basic information from the buffer var pbi = Tools.PointerToStructure <Native.ProcessBasicInformation>(pbiBuffer); if (pbi.Equals(default(Native.ProcessBasicInformation))) { ExceptionHandler.ThrowWin32Exception("Failed to query the memory of the process"); } // Read the process environment block from the process var peb = default(Native.Peb); try { peb = _memoryModule.ReadMemory <Native.Peb>(processId, pbi.PebBaseAddress); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to read the process environment block of the process"); } // Read the process environment block loader data from the process var pebLoaderData = default(Native.PebLdrData); try { pebLoaderData = _memoryModule.ReadMemory <Native.PebLdrData>(processId, peb.Ldr); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to read the process environment block loader data of the process"); } // Get the address of the first dll entry in the processes module list var currentEntry = pebLoaderData.InLoadOrderModuleList.Flink; // Get the address of the last dll entry in the processes module list var lastEntry = pebLoaderData.InLoadOrderModuleList.Blink; while (true) { // Read the information about the current dll entry var dllEntry = default(Native.LdrDataTableEntry); try { dllEntry = _memoryModule.ReadMemory <Native.LdrDataTableEntry>(processId, currentEntry); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to read the information of a dll entry"); } // Read the full dll name of the current dll entry var dllEntryNameBytes = new byte[0]; try { dllEntryNameBytes = _memoryModule.ReadMemory(processId, dllEntry.FullDllName.Buffer, dllEntry.FullDllName.Length); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to read the dll path of a dll entry"); } var ldrEntryName = Encoding.UTF8.GetString(dllEntryNameBytes).Replace("\0", ""); if (string.Equals(dllPath, ldrEntryName, StringComparison.OrdinalIgnoreCase)) { // Unlink the dll from the necessary links UnlinkModule(processId, dllEntry.InLoadOrderLinks); UnlinkModule(processId, dllEntry.InMemoryOrderLinks); UnlinkModule(processId, dllEntry.InInitOrderLinks); // Create a buffer to write over the base dll name buffer with var baseDllNameBuffer = new byte[dllEntry.BaseDllName.MaxLength]; // Create a buffer to write over the full dll name buffer with var fullDllNameBuffer = new byte[dllEntry.FullDllName.MaxLength]; // Create a buffer to write over the entry with var ldrDataTableEntrySize = Marshal.SizeOf(typeof(Native.LdrDataTableEntry)); var currentEntryBuffer = new byte[ldrDataTableEntrySize]; // Write over the base dll name buffer with the new buffer try { _memoryModule.WriteMemory(processId, dllEntry.BaseDllName.Buffer, baseDllNameBuffer); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write over the dll name buffer"); } // Write over the full dll name buffer with the new buffer try { _memoryModule.WriteMemory(processId, dllEntry.FullDllName.Buffer, fullDllNameBuffer); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write over the dll path buffer"); } // Write over the dll entry with the new buffer try { _memoryModule.WriteMemory(processId, currentEntry, currentEntryBuffer); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write over the dll entry"); } break; } if (currentEntry == lastEntry) { // The dll wasn't found in the process environment block var dllName = Path.GetFileName(dllPath); throw new ArgumentException($"No entry with the name {dllName} was found in the process environment block"); } // Jump to the next entry currentEntry = dllEntry.InLoadOrderLinks.Flink; } // Free the memory previously allocated for the buffer Marshal.FreeHGlobal(pbiBuffer); // Close the handle opened to the process processHandle?.Close(); return(true); }