Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }