示例#1
0
        internal IntPtr InitialiseDllPath()
        {
            // Write the DLL path into the remote process

            var dllPathAddress = MemoryManager.AllocateVirtualMemory(ProcessManager.Process.SafeHandle, IntPtr.Zero, DllPath.Length, MemoryProtectionType.ReadWrite);

            MemoryManager.WriteVirtualMemory(ProcessManager.Process.SafeHandle, dllPathAddress, Encoding.Unicode.GetBytes(DllPath));

            // Write a UnicodeString representing the DLL path into the remote process

            IntPtr dllPathUnicodeStringAddress;

            if (ProcessManager.IsWow64)
            {
                var dllPathUnicodeString = new UnicodeString32(DllPath, dllPathAddress);

                dllPathUnicodeStringAddress = MemoryManager.AllocateVirtualMemory(ProcessManager.Process.SafeHandle, IntPtr.Zero, Marshal.SizeOf <UnicodeString32>(), MemoryProtectionType.ReadWrite);

                MemoryManager.WriteVirtualMemory(ProcessManager.Process.SafeHandle, dllPathUnicodeStringAddress, dllPathUnicodeString);
            }

            else
            {
                var dllPathUnicodeString = new UnicodeString64(DllPath, dllPathAddress);

                dllPathUnicodeStringAddress = MemoryManager.AllocateVirtualMemory(ProcessManager.Process.SafeHandle, IntPtr.Zero, Marshal.SizeOf <UnicodeString64>(), MemoryProtectionType.ReadWrite);

                MemoryManager.WriteVirtualMemory(ProcessManager.Process.SafeHandle, dllPathUnicodeStringAddress, dllPathUnicodeString);
            }

            return(dllPathUnicodeStringAddress);
        }
示例#2
0
        public IntPtr Call()
        {
            // Write the DLL path into the remote process

            var dllPathBuffer = _injectionWrapper.MemoryManager.AllocateVirtualMemory(_injectionWrapper.DllPath.Length);

            var dllPathBytes = Encoding.Unicode.GetBytes(_injectionWrapper.DllPath);

            _injectionWrapper.MemoryManager.WriteVirtualMemory(dllPathBuffer, dllPathBytes);

            // Write a UnicodeString representing the DLL path into the remote process

            IntPtr unicodeStringBuffer;

            if (_injectionWrapper.ProcessManager.IsWow64)
            {
                var unicodeString = new UnicodeString32(_injectionWrapper.DllPath)
                {
                    Buffer = (uint)dllPathBuffer
                };

                unicodeStringBuffer = _injectionWrapper.MemoryManager.AllocateVirtualMemory(Marshal.SizeOf <UnicodeString32>());

                _injectionWrapper.MemoryManager.WriteVirtualMemory(unicodeStringBuffer, unicodeString);
            }

            else
            {
                var unicodeString = new UnicodeString64(_injectionWrapper.DllPath)
                {
                    Buffer = (ulong)dllPathBuffer
                };

                unicodeStringBuffer = _injectionWrapper.MemoryManager.AllocateVirtualMemory(Marshal.SizeOf <UnicodeString64>());

                _injectionWrapper.MemoryManager.WriteVirtualMemory(unicodeStringBuffer, unicodeString);
            }

            var moduleHandleBuffer = _injectionWrapper.MemoryManager.AllocateVirtualMemory(IntPtr.Size);

            // Flush the instruction cache of the remote process to ensure all memory operations have been completed

            if (!FlushInstructionCache(Process.GetCurrentProcess().SafeHandle, IntPtr.Zero, 0))
            {
                ExceptionHandler.ThrowWin32Exception("Failed to flush the instruction cache of the remote process");
            }

            // Call LdrLoadDll in the remote process

            var ldrLoadDllAddress = _injectionWrapper.ProcessManager.GetFunctionAddress("ntdll.dll", "LdrLoadDll");

            var ntStatus = _injectionWrapper.ProcessManager.CallFunction <uint>(CallingConvention.StdCall, ldrLoadDllAddress, 0, 0, (ulong)unicodeStringBuffer, (ulong)moduleHandleBuffer);

            if ((NtStatus)ntStatus != NtStatus.Success)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to call LdrLoadDll in the remote process", (NtStatus)ntStatus);
            }

            while (_injectionWrapper.ProcessManager.Modules.All(module => module.FilePath != _injectionWrapper.DllPath))
            {
                _injectionWrapper.ProcessManager.Refresh();
            }

            _injectionWrapper.MemoryManager.FreeVirtualMemory(dllPathBuffer);

            _injectionWrapper.MemoryManager.FreeVirtualMemory(unicodeStringBuffer);

            try
            {
                // Read the base address of the DLL that was loaded in the remote process

                return(_injectionWrapper.MemoryManager.ReadVirtualMemory <IntPtr>(moduleHandleBuffer));
            }

            finally
            {
                _injectionWrapper.MemoryManager.FreeVirtualMemory(moduleHandleBuffer);
            }
        }
示例#3
0
        public IntPtr Call()
        {
            // Write the DLL path into the remote process

            var dllPathBuffer = _injectionWrapper.MemoryManager.AllocateVirtualMemory(_injectionWrapper.DllPath.Length);

            var dllPathBytes = Encoding.Unicode.GetBytes(_injectionWrapper.DllPath);

            _injectionWrapper.MemoryManager.WriteVirtualMemory(dllPathBuffer, dllPathBytes);

            // Write a UnicodeString representing the DLL path into the remote process

            IntPtr unicodeStringBuffer;

            if (_injectionWrapper.ProcessManager.IsWow64)
            {
                var unicodeString = new UnicodeString32(_injectionWrapper.DllPath)
                {
                    Buffer = (uint)dllPathBuffer
                };

                unicodeStringBuffer = _injectionWrapper.MemoryManager.AllocateVirtualMemory(Marshal.SizeOf <UnicodeString32>());

                _injectionWrapper.MemoryManager.WriteVirtualMemory(unicodeStringBuffer, unicodeString);
            }

            else
            {
                var unicodeString = new UnicodeString64(_injectionWrapper.DllPath)
                {
                    Buffer = (ulong)dllPathBuffer
                };

                unicodeStringBuffer = _injectionWrapper.MemoryManager.AllocateVirtualMemory(Marshal.SizeOf <UnicodeString64>());

                _injectionWrapper.MemoryManager.WriteVirtualMemory(unicodeStringBuffer, unicodeString);
            }

            // Get the address of the LdrLoadDll function in the remote process

            var ldrLoadDllAddress = _injectionWrapper.ProcessManager.GetFunctionAddress("ntdll.dll", "LdrLoadDll");

            var returnBuffer = _injectionWrapper.MemoryManager.AllocateVirtualMemory(sizeof(uint));

            var moduleHandleBuffer = _injectionWrapper.MemoryManager.AllocateVirtualMemory(IntPtr.Size);

            // Write the shellcode used to call LdrLoadDll from a thread into the remote process

            var shellcode = _injectionWrapper.Assembler.AssembleThreadFunctionCall(CallingConvention.StdCall, ldrLoadDllAddress, returnBuffer, 0, 0, (ulong)unicodeStringBuffer, (ulong)moduleHandleBuffer);

            var shellcodeBuffer = _injectionWrapper.MemoryManager.AllocateVirtualMemory(shellcode.Length);

            _injectionWrapper.MemoryManager.WriteVirtualMemory(shellcodeBuffer, shellcode);

            // Open a handle to the first thread in the remote process

            var firstThreadHandle = OpenThread(ThreadAccessMask.AllAccess, false, _injectionWrapper.ProcessManager.Process.Threads[0].Id);

            if (_injectionWrapper.ProcessManager.IsWow64)
            {
                // Suspend the thread

                if (Wow64SuspendThread(firstThreadHandle) == -1)
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to suspend a thread in the remote process");
                }

                var threadContextBuffer = Marshal.AllocHGlobal(Marshal.SizeOf <Wow64Context>());

                Marshal.StructureToPtr(new Wow64Context {
                    ContextFlags = ContextFlags.Control
                }, threadContextBuffer, false);

                // Get the context of the thread

                if (!Wow64GetThreadContext(firstThreadHandle, threadContextBuffer))
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to get the context of a thread in the remote process");
                }

                var threadContext = Marshal.PtrToStructure <Wow64Context>(threadContextBuffer);

                // Write the original instruction pointer of the thread into the top of its stack

                threadContext.Esp -= sizeof(uint);

                _injectionWrapper.MemoryManager.WriteVirtualMemory((IntPtr)threadContext.Esp, threadContext.Eip);

                // Overwrite the instruction pointer of the thread with the address of the shellcode buffer

                threadContext.Eip = (uint)shellcodeBuffer;

                Marshal.StructureToPtr(threadContext, threadContextBuffer, true);

                // Update the context of the thread

                if (!Wow64SetThreadContext(firstThreadHandle, threadContextBuffer))
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to set the context of a thread in the remote process");
                }
            }

            else
            {
                // Suspend the thread

                if (SuspendThread(firstThreadHandle) == -1)
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to suspend a thread in the remote process");
                }

                var threadContextBuffer = Marshal.AllocHGlobal(Marshal.SizeOf <Context>());

                Marshal.StructureToPtr(new Context {
                    ContextFlags = ContextFlags.Control
                }, threadContextBuffer, false);

                // Get the context of the thread

                if (!GetThreadContext(firstThreadHandle, threadContextBuffer))
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to get the context of a thread in the remote process");
                }

                var threadContext = Marshal.PtrToStructure <Context>(threadContextBuffer);

                // Write the original instruction pointer of the thread into the top of its stack

                threadContext.Rsp -= sizeof(ulong);

                _injectionWrapper.MemoryManager.WriteVirtualMemory((IntPtr)threadContext.Rsp, threadContext.Rip);

                // Overwrite the instruction pointer of the thread with the address of the shellcode buffer

                threadContext.Rip = (ulong)shellcodeBuffer;

                Marshal.StructureToPtr(threadContext, threadContextBuffer, true);

                // Update the context of the thread

                if (!SetThreadContext(firstThreadHandle, threadContextBuffer))
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to set the context of a thread in the remote process");
                }
            }

            // Flush the instruction cache of the remote process to ensure all memory operations have been completed

            if (!FlushInstructionCache(Process.GetCurrentProcess().SafeHandle, IntPtr.Zero, 0))
            {
                ExceptionHandler.ThrowWin32Exception("Failed to flush the instruction cache of the remote process");
            }

            // Resume the thread

            if (ResumeThread(firstThreadHandle) == -1)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to resume a thread in the remote process");
            }

            firstThreadHandle.Dispose();

            // Send a message to the thread to ensure it resumes

            PostThreadMessage(_injectionWrapper.ProcessManager.Process.Threads[0].Id, WindowsMessage.Keydown, VirtualKey.LeftButton, IntPtr.Zero);

            // Read the returned value of LdrLoadDll from the buffer

            var ntStatus = _injectionWrapper.MemoryManager.ReadVirtualMemory <uint>(returnBuffer);

            if ((NtStatus)ntStatus != NtStatus.Success)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to call LdrLoadDll in the remote process", (NtStatus)ntStatus);
            }

            while (_injectionWrapper.ProcessManager.Modules.All(module => module.FilePath != _injectionWrapper.DllPath))
            {
                _injectionWrapper.ProcessManager.Refresh();
            }

            _injectionWrapper.MemoryManager.FreeVirtualMemory(dllPathBuffer);

            _injectionWrapper.MemoryManager.FreeVirtualMemory(unicodeStringBuffer);

            try
            {
                // Read the base address of the DLL that was loaded in the remote process

                return(_injectionWrapper.MemoryManager.ReadVirtualMemory <IntPtr>(moduleHandleBuffer));
            }

            finally
            {
                _injectionWrapper.MemoryManager.FreeVirtualMemory(moduleHandleBuffer);
            }
        }
示例#4
0
        public IntPtr Inject()
        {
            // Write the DLL path into the remote process

            var dllPathAddress = _process.MemoryManager.AllocateVirtualMemory(_dllPath.Length, MemoryProtectionType.ReadWrite);

            _process.MemoryManager.WriteVirtualMemory(dllPathAddress, Encoding.Unicode.GetBytes(_dllPath));

            // Write a UnicodeString representing the DLL path into the remote process

            IntPtr dllPathUnicodeStringAddress;

            if (_process.IsWow64)
            {
                var dllPathUnicodeString = new UnicodeString32(_dllPath, dllPathAddress);

                dllPathUnicodeStringAddress = _process.MemoryManager.AllocateVirtualMemory(Marshal.SizeOf <UnicodeString32>(), MemoryProtectionType.ReadWrite);

                _process.MemoryManager.WriteVirtualMemory(dllPathUnicodeStringAddress, dllPathUnicodeString);
            }

            else
            {
                var dllPathUnicodeString = new UnicodeString64(_dllPath, dllPathAddress);

                dllPathUnicodeStringAddress = _process.MemoryManager.AllocateVirtualMemory(Marshal.SizeOf <UnicodeString64>(), MemoryProtectionType.ReadWrite);

                _process.MemoryManager.WriteVirtualMemory(dllPathUnicodeStringAddress, dllPathUnicodeString);
            }

            // Write the shellcode used to call LdrLoadDll into the remote process

            var ldrLoadDllAddress = _process.GetFunctionAddress("ntdll.dll", "LdrLoadDll");

            var moduleHandleAddress = _process.MemoryManager.AllocateVirtualMemory(IntPtr.Size, MemoryProtectionType.ReadWrite);

            var shellcodeReturnAddress = _process.MemoryManager.AllocateVirtualMemory(sizeof(int), MemoryProtectionType.ReadWrite);

            var shellcode = _process.Assembler.AssembleThreadFunctionCall(new FunctionCall(ldrLoadDllAddress, CallingConvention.StdCall, new[] { 0, 0, (long)dllPathUnicodeStringAddress, (long)moduleHandleAddress }, shellcodeReturnAddress));

            var shellcodeAddress = _process.MemoryManager.AllocateVirtualMemory(shellcode.Length, MemoryProtectionType.ReadWrite);

            _process.MemoryManager.WriteVirtualMemory(shellcodeAddress, shellcode);

            _process.MemoryManager.ProtectVirtualMemory(shellcodeAddress, shellcode.Length, MemoryProtectionType.ExecuteRead);

            // Open a handle to the first thread in the remote process

            var firstThreadHandle = Kernel32.OpenThread(Constants.ThreadAllAccess, false, _process.Process.Threads[0].Id);

            if (firstThreadHandle is null)
            {
                throw new PInvokeException("Failed to call OpenThread");
            }

            if (_process.IsWow64)
            {
                // Suspend the thread

                if (Kernel32.Wow64SuspendThread(firstThreadHandle) == -1)
                {
                    throw new PInvokeException("Failed to call Wow64SuspendThread");
                }

                // Get the context of the thread

                var threadContext = new Context32 {
                    ContextFlags = ContextFlags.Control
                };

                var threadContextBuffer = Marshal.AllocHGlobal(Marshal.SizeOf <Context32>());

                Marshal.StructureToPtr(threadContext, threadContextBuffer, false);

                if (!Kernel32.Wow64GetThreadContext(firstThreadHandle, threadContextBuffer))
                {
                    throw new PInvokeException("Failed to call Wow64GetThreadContext");
                }

                threadContext = Marshal.PtrToStructure <Context32>(threadContextBuffer);

                // Write the original instruction pointer of the thread into the top of its stack

                threadContext.Esp -= sizeof(int);

                _process.MemoryManager.WriteVirtualMemory((IntPtr)threadContext.Esp, threadContext.Eip);

                // Overwrite the instruction pointer of the thread with the address of the shellcode

                threadContext.Eip = (int)shellcodeAddress;

                Marshal.StructureToPtr(threadContext, threadContextBuffer, false);

                // Update the context of the thread

                if (!Kernel32.Wow64SetThreadContext(firstThreadHandle, threadContextBuffer))
                {
                    throw new PInvokeException("Failed to call Wow64SetThreadContext");
                }

                Marshal.FreeHGlobal(threadContextBuffer);
            }

            else
            {
                // Suspend the thread

                if (Kernel32.SuspendThread(firstThreadHandle) == -1)
                {
                    throw new PInvokeException("Failed to call SuspendThread");
                }

                // Get the context of the thread

                var threadContext = new Context64 {
                    ContextFlags = ContextFlags.Control
                };

                var threadContextBuffer = Marshal.AllocHGlobal(Marshal.SizeOf <Context64>());

                Marshal.StructureToPtr(threadContext, threadContextBuffer, false);

                if (!Kernel32.GetThreadContext(firstThreadHandle, threadContextBuffer))
                {
                    throw new PInvokeException("Failed to call GetThreadContext");
                }

                threadContext = Marshal.PtrToStructure <Context64>(threadContextBuffer);

                // Write the original instruction pointer of the thread into the top of its stack

                threadContext.Rsp -= sizeof(long);

                _process.MemoryManager.WriteVirtualMemory((IntPtr)threadContext.Rsp, threadContext.Rip);

                // Overwrite the instruction pointer of the thread with the address of the shellcode

                threadContext.Rip = (long)shellcodeAddress;

                Marshal.StructureToPtr(threadContext, threadContextBuffer, false);

                // Update the context of the thread

                if (!Kernel32.SetThreadContext(firstThreadHandle, threadContextBuffer))
                {
                    throw new PInvokeException("Failed to call SetThreadContext");
                }

                Marshal.FreeHGlobal(threadContextBuffer);
            }

            // Send a message to the thread to ensure it executes the shellcode

            User32.PostThreadMessage(_process.Process.Threads[0].Id, MessageType.Null, IntPtr.Zero, IntPtr.Zero);

            // Resume the thread

            if (Kernel32.ResumeThread(firstThreadHandle) == -1)
            {
                throw new PInvokeException("Failed to call ResumeThread");
            }

            firstThreadHandle.Dispose();

            var shellcodeReturn = _process.MemoryManager.ReadVirtualMemory <int>(shellcodeReturnAddress);

            if ((NtStatus)shellcodeReturn != NtStatus.Success)
            {
                throw new RemoteFunctionCallException("Failed to call LdrLoadDll", (NtStatus)shellcodeReturn);
            }

            // Ensure the DLL is loaded before freeing any memory

            while (_process.Modules.TrueForAll(module => module.FilePath != _dllPath))
            {
                _process.Refresh();
            }

            _process.MemoryManager.FreeVirtualMemory(dllPathAddress);

            _process.MemoryManager.FreeVirtualMemory(dllPathUnicodeStringAddress);

            _process.MemoryManager.FreeVirtualMemory(shellcodeReturnAddress);

            // Read the address of the DLL that was loaded in the remote process

            var remoteDllAddress = _process.MemoryManager.ReadVirtualMemory <IntPtr>(moduleHandleAddress);

            _process.MemoryManager.FreeVirtualMemory(moduleHandleAddress);

            if (!_injectionFlags.HasFlag(InjectionFlags.RandomiseDllHeaders))
            {
                return(remoteDllAddress);
            }

            // Write over the header region of the DLL with random bytes

            var randomBuffer = new byte[_peImage.PeHeaders.PEHeader.SizeOfHeaders];

            new Random().NextBytes(randomBuffer);

            _process.MemoryManager.WriteVirtualMemory(remoteDllAddress, randomBuffer);

            return(remoteDllAddress);
        }
示例#5
0
        public IntPtr Call()
        {
            // Write the DLL path into the remote process

            var dllPathAddress = _process.MemoryManager.AllocateVirtualMemory(_dllPath.Length, MemoryProtectionType.ReadWrite);

            _process.MemoryManager.WriteVirtualMemory(dllPathAddress, Encoding.Unicode.GetBytes(_dllPath));

            // Write a UnicodeString representing the DLL path into the remote process

            IntPtr dllPathUnicodeStringAddress;

            if (_process.IsWow64)
            {
                var dllPathUnicodeString = new UnicodeString32(_dllPath, dllPathAddress);

                dllPathUnicodeStringAddress = _process.MemoryManager.AllocateVirtualMemory(Marshal.SizeOf <UnicodeString32>(), MemoryProtectionType.ReadWrite);

                _process.MemoryManager.WriteVirtualMemory(dllPathUnicodeStringAddress, dllPathUnicodeString);
            }

            else
            {
                var dllPathUnicodeString = new UnicodeString64(_dllPath, dllPathAddress);

                dllPathUnicodeStringAddress = _process.MemoryManager.AllocateVirtualMemory(Marshal.SizeOf <UnicodeString64>(), MemoryProtectionType.ReadWrite);

                _process.MemoryManager.WriteVirtualMemory(dllPathUnicodeStringAddress, dllPathUnicodeString);
            }

            // Create a thread to call LdrLoadDll in the remote process

            var ldrLoadDllAddress = _process.GetFunctionAddress("ntdll.dll", "LdrLoadDll");

            var moduleHandleAddress = _process.MemoryManager.AllocateVirtualMemory(IntPtr.Size, MemoryProtectionType.ReadWrite);

            var ntStatus = _process.CallFunction <int>(CallingConvention.StdCall, ldrLoadDllAddress, 0, 0, (long)dllPathUnicodeStringAddress, (long)moduleHandleAddress);

            if ((NtStatus)ntStatus != NtStatus.Success)
            {
                throw new RemoteFunctionCallException("Failed to call LdrLoadDll", (NtStatus)ntStatus);
            }

            // Ensure the DLL is loaded before freeing any memory

            while (_process.Modules.TrueForAll(module => module.FilePath != _dllPath))
            {
                _process.Refresh();
            }

            _process.MemoryManager.FreeVirtualMemory(dllPathAddress);

            _process.MemoryManager.FreeVirtualMemory(dllPathUnicodeStringAddress);

            // Read the address of the DLL that was loaded in the remote process

            var remoteDllAddress = _process.MemoryManager.ReadVirtualMemory <IntPtr>(moduleHandleAddress);

            _process.MemoryManager.FreeVirtualMemory(moduleHandleAddress);

            if (!_injectionFlags.HasFlag(InjectionFlags.RandomiseDllHeaders))
            {
                return(remoteDllAddress);
            }

            // Write over the header region of the DLL with random bytes

            var randomBuffer = new byte[_peImage.PeHeaders.PEHeader.SizeOfHeaders];

            new Random().NextBytes(randomBuffer);

            _process.MemoryManager.WriteVirtualMemory(remoteDllAddress, randomBuffer);

            return(remoteDllAddress);
        }