コード例 #1
0
        public void TestPatternScan()
        {
            // 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, 0x1A, 0xAA, 0xFF, 0xFF, 0xFF };

            _memoryModule.WriteMemory(_hostProcessName, testRegionAddress, testArray);

            // Scan the host process for test array pattern

            const string testArrayPattern = "FF 01 ?? FF 22 00 ?? AA FF ?? FF";

            var result = _memoryModule.PatternScan(_hostProcessName, IntPtr.Zero, testArrayPattern);

            Assert.Contains(testRegionAddress, result);

            // Free the memory that was allocated

            _memoryModule.FreeMemory(_hostProcessName, testRegionAddress);
        }
コード例 #2
0
        internal bool Erase(Process process, string dllPath)
        {
            // Get the id of the process

            var processId = process.Id;

            // Get the name of the dll

            var dllName = Path.GetFileName(dllPath);

            // Get an instance of the dll in the process

            var module = process.Modules.Cast <ProcessModule>().SingleOrDefault(m => string.Equals(m.ModuleName, dllName, StringComparison.OrdinalIgnoreCase));

            if (module is null)
            {
                throw new ArgumentException($"There is no module named {dllName} loaded in the process");
            }

            // Get the base address of the dll

            var dllBaseAddress = module.BaseAddress;

            // Open a handle to the process

            var processHandle = process.SafeHandle;

            // Get the information about the header region of the dll

            var memoryInformationSize = Marshal.SizeOf(typeof(Native.MemoryBasicInformation));

            if (!Native.VirtualQueryEx(processHandle, dllBaseAddress, out var memoryInformation, memoryInformationSize))
            {
                ExceptionHandler.ThrowWin32Exception("Failed to query the memory of the process");
            }

            // Create a buffer to write over the header region with

            var buffer = new byte[(int)memoryInformation.RegionSize];

            // Write over the header region with the buffer

            try
            {
                _memoryModule.WriteMemory(processId, dllBaseAddress, buffer);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to write over the header region");
            }

            // Close the handle opened to the process

            processHandle?.Close();

            return(true);
        }
コード例 #3
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);
        }
コード例 #4
0
        internal bool Inject(Process process, string dllPath)
        {
            // Ensure the process has kernel32.dll loaded

            if (Native.LoadLibrary("kernel32.dll") is null)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to load kernel32.dll into the process");
            }

            // Get the id of the process

            var processId = process.Id;

            // Get the address of the LoadLibraryW method from kernel32.dll

            var loadLibraryAddress = Native.GetProcAddress(Native.GetModuleHandle("kernel32.dll"), "LoadLibraryW");

            if (loadLibraryAddress == IntPtr.Zero)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to find the address of the LoadLibraryW method in kernel32.dll");
            }

            // Allocate memory for the dll path in the process

            var dllPathSize = dllPath.Length;

            var dllPathAddress = IntPtr.Zero;

            try
            {
                dllPathAddress = _memoryModule.AllocateMemory(processId, dllPathSize);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the dll path in the process");
            }

            // Write the dll path into the process

            var dllPathBytes = Encoding.Unicode.GetBytes(dllPath + "\0");

            try
            {
                _memoryModule.WriteMemory(processId, dllPathAddress, dllPathBytes);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to write the dll path into the memory of the process");
            }

            // Open a handle to the process

            var processHandle = process.SafeHandle;

            // Create a remote thread to call load library in the process

            Native.RtlCreateUserThread(processHandle, IntPtr.Zero, false, 0, IntPtr.Zero, IntPtr.Zero, loadLibraryAddress, dllPathAddress, out var remoteThreadHandle, 0);

            if (remoteThreadHandle is null)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to create a remote thread to call load library in the process");
            }

            // Wait for the remote thread to finish its task

            Native.WaitForSingleObject(remoteThreadHandle, int.MaxValue);

            // Free the memory previously allocated for the dll path

            try
            {
                _memoryModule.FreeMemory(processId, dllPathAddress);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the dll path in the process");
            }

            // Close the handle opened to the process

            processHandle.Close();

            // Close the handle opened to the remote thread

            remoteThreadHandle.Close();

            return(true);
        }
コード例 #5
0
ファイル: ManualMap.cs プロジェクト: TrungNguyen153/Bleak
        private void CallEntryPoint(IntPtr baseAddress, IntPtr entryPoint)
        {
            // Get the id of the process

            var processId = _process.Id;

            // Open a handle to the process

            var processHandle = _process.SafeHandle;

            // Determine if the process is running under WOW64

            Native.IsWow64Process(processHandle, out var isWow64);

            // Create shellcode to call the entry of the dll in the process

            var shellcodeBytes = isWow64 ? Shellcode.CallDllMainx86(baseAddress, entryPoint) : Shellcode.CallDllMainx64(baseAddress, entryPoint);

            // Allocate memory for the shellcode in the process

            var shellcodeSize = shellcodeBytes.Length;

            var shellcodeAddress = IntPtr.Zero;

            try
            {
                shellcodeAddress = _memoryModule.AllocateMemory(processId, shellcodeSize);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the shellcode in the process");
            }

            // Write the shellcode into the memory of the process

            try
            {
                _memoryModule.WriteMemory(processId, shellcodeAddress, shellcodeBytes);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to write the shellcode into the memory of the process");
            }

            // Create a remote thread to call the entry point in the process

            Native.RtlCreateUserThread(processHandle, IntPtr.Zero, false, 0, IntPtr.Zero, IntPtr.Zero, shellcodeAddress, IntPtr.Zero, out var remoteThreadHandle, 0);

            if (remoteThreadHandle is null)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to create a remote thread to call the entry point in the process");
            }

            // Wait for the remote thread to finish its task

            Native.WaitForSingleObject(remoteThreadHandle, int.MaxValue);

            // Free the memory previously allocated for the shellcode

            try
            {
                _memoryModule.FreeMemory(processId, shellcodeAddress);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the shellcode in the process");
            }

            // Close the handle opened to the process

            processHandle?.Close();

            // Close the handle opened to the remote thread

            remoteThreadHandle?.Close();
        }
コード例 #6
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);
        }
コード例 #7
0
        internal bool Inject(Process process, string dllPath)
        {
            // Ensure the process has kernel32.dll loaded

            if (Native.LoadLibrary("kernel32.dll") is null)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to load kernel32.dll into the process");
            }

            // Get the id of the process

            var processId = process.Id;

            // Get the address of the LoadLibraryW method from kernel32.dll

            var loadLibraryAddress = Native.GetProcAddress(Native.GetModuleHandle("kernel32.dll"), "LoadLibraryW");

            if (loadLibraryAddress == IntPtr.Zero)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to find the address of the LoadLibraryW method in kernel32.dll");
            }

            // Allocate memory for the dll path in the process

            var dllPathSize = dllPath.Length;

            var dllPathAddress = IntPtr.Zero;

            try
            {
                dllPathAddress = _memoryModule.AllocateMemory(processId, dllPathSize);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the dll path in the process");
            }

            // Write the dll path into the process

            var dllPathBytes = Encoding.Unicode.GetBytes(dllPath + "\0");

            try
            {
                _memoryModule.WriteMemory(processId, dllPathAddress, dllPathBytes);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to write the dll path into the memory of the process");
            }

            foreach (var thread in process.Threads.Cast <ProcessThread>())
            {
                // Open a handle to the thread

                var threadHandle = Native.OpenThread(Native.ThreadAccess.SetContext, false, thread.Id);

                if (threadHandle is null)
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to open a handle to a thread in the process");
                }

                // Add a user-mode APC to the APC queue of the thread

                if (!Native.QueueUserAPC(loadLibraryAddress, threadHandle, dllPathAddress))
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to queue a user-mode apc to the apc queue of a thread in the process");
                }

                // Close the handle opened to the thread

                threadHandle?.Close();
            }

            // Free the memory previously allocated for the dll path

            try
            {
                _memoryModule.FreeMemory(processId, dllPathAddress);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the dll path in the process");
            }

            return(true);
        }
コード例 #8
0
        internal bool Inject(Process process, string dllPath)
        {
            // Ensure the process has kernel32.dll loaded

            if (Native.LoadLibrary("kernel32.dll") is null)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to load kernel32.dll into the process");
            }

            // Get the id of the process

            var processId = process.Id;

            // Get the address of the LoadLibraryW method from kernel32.dll

            var loadLibraryAddress = Native.GetProcAddress(Native.GetModuleHandle("kernel32.dll"), "LoadLibraryW");

            if (loadLibraryAddress == IntPtr.Zero)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to find the address of the LoadLibraryW method in kernel32.dll");
            }

            // Allocate memory for the dll path in the process

            var dllPathSize = dllPath.Length;

            var dllPathAddress = IntPtr.Zero;

            try
            {
                dllPathAddress = _memoryModule.AllocateMemory(processId, dllPathSize);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the dll path in the process");
            }

            // Write the dll path into the process

            var dllPathBytes = Encoding.Unicode.GetBytes(dllPath + "\0");

            try
            {
                _memoryModule.WriteMemory(processId, dllPathAddress, dllPathBytes);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to write the dll path into the memory of the process");
            }

            // Open a handle to the process

            var processHandle = process.SafeHandle;

            // Determine if the process is running under WOW64

            Native.IsWow64Process(processHandle, out var isWow64);

            // Allocate memory for the shellcode in the process

            var shellcodeSize = isWow64 ? 22 : 87;

            var shellcodeAddress = IntPtr.Zero;

            try
            {
                shellcodeAddress = _memoryModule.AllocateMemory(processId, shellcodeSize);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the shellcode in the process");
            }

            // Get the id of the first thread in the process

            var threadId = process.Threads[0].Id;

            // Open a handle to the thread

            var threadHandle = Native.OpenThread(Native.ThreadAccess.AllAccess, false, threadId);

            if (threadHandle is null)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to open a handle to the first thread in the process");
            }

            // Suspend the thread

            if (Native.SuspendThread(threadHandle) == -1)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to suspend the first thread in the process");
            }

            // If the process is x86

            if (isWow64)
            {
                var threadContext = new Native.Context {
                    Flags = Native.ContextFlags.ContextControl
                };

                // Store the thread context structure in a buffer

                var threadContextBuffer = Tools.StructureToPointer(threadContext);

                // Get the context of the thread and save it in the buffer

                if (!Native.GetThreadContext(threadHandle, threadContextBuffer))
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to get the context of the first thread in the process");
                }

                // Read the new thread context structure from the buffer

                threadContext = Tools.PointerToStructure <Native.Context>(threadContextBuffer);

                // Save the instruction pointer

                var instructionPointer = threadContext.Eip;

                // Write the shellcode into the memory of the process

                var shellcodeBytes = Shellcode.CallLoadLibraryx86(instructionPointer, dllPathAddress, loadLibraryAddress);

                try
                {
                    _memoryModule.WriteMemory(processId, shellcodeAddress, shellcodeBytes);
                }

                catch (Win32Exception)
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to write the shellcode into the memory of the process");
                }

                // Change the instruction pointer to the shellcode address

                threadContext.Eip = shellcodeAddress;

                // Store the thread context structure in a buffer

                threadContextBuffer = Tools.StructureToPointer(threadContext);

                // Set the context of the thread with the new context

                if (!Native.SetThreadContext(threadHandle, threadContextBuffer))
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to set the context of the first thread in the process");
                }
            }

            // If the process is x64

            else
            {
                var threadContext = new Native.Context64 {
                    Flags = Native.ContextFlags.ContextControl
                };

                // Store the thread context structure in a buffer

                var threadContextBuffer = Tools.StructureToPointer(threadContext);

                // Get the context of the thread and save it in the buffer

                if (!Native.GetThreadContext(threadHandle, threadContextBuffer))
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to get the context of the first thread in the process");
                }

                // Read the new thread context structure from the buffer

                threadContext = Tools.PointerToStructure <Native.Context64>(threadContextBuffer);

                // Save the instruction pointer

                var instructionPointer = threadContext.Rip;

                // Write the shellcode into the memory of the process

                var shellcodeBytes = Shellcode.CallLoadLibraryx64(instructionPointer, dllPathAddress, loadLibraryAddress);

                try
                {
                    _memoryModule.WriteMemory(processId, shellcodeAddress, shellcodeBytes);
                }

                catch (Win32Exception)
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to write the shellcode into the memory of the process");
                }

                // Change the instruction pointer to the shellcode address

                threadContext.Rip = shellcodeAddress;

                // Store the thread context structure in a buffer

                threadContextBuffer = Tools.StructureToPointer(threadContext);

                // Set the context of the thread with the new context

                if (!Native.SetThreadContext(threadHandle, threadContextBuffer))
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to set the context of the first thread in the process");
                }
            }

            // Resume the suspended thread

            if (Native.ResumeThread(threadHandle) == -1)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to resume the first thread in the process");
            }

            // Open a handle to the main window of the process

            var windowHandle = new SafeWindowHandle(process.MainWindowHandle);

            // Switch to the process to load the dll

            Native.SwitchToThisWindow(windowHandle, true);

            // Buffer the execution by 10 milliseconds to avoid freeing memory before it has been referenced

            Tools.AsyncWait(10);

            // Free the memory previously allocated for the dll path

            try
            {
                _memoryModule.FreeMemory(processId, dllPathAddress);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the dll path in the process");
            }

            // Free the memory previously allocated for the shellcode

            try
            {
                _memoryModule.FreeMemory(processId, shellcodeAddress);
            }

            catch (Win32Exception)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the shellcode in the process");
            }

            // Close the handle opened to the process

            processHandle?.Close();

            // Close the handle opened to the thread

            threadHandle?.Close();

            return(true);
        }