internal Enumerations.MemoryProtectionType Invoke(SafeProcessHandle processHandle, IntPtr baseAddress, int protectionSize, Enumerations.MemoryProtectionType newProtectionType)
        {
            // Store the base address of the memory region to protect in a buffer

            var baseAddressBuffer = MemoryTools.StoreStructureInBuffer(baseAddress);

            // Store the protection size in a buffer

            var protectionSizeBuffer = MemoryTools.StoreStructureInBuffer(protectionSize);

            // Initialise a buffer to store the returned old protection of the memory region

            var oldProtectionBuffer = MemoryTools.AllocateMemoryForBuffer(sizeof(ulong));

            // Perform the syscall

            var syscallResult = _ntProtectVirtualMemoryDelegate(processHandle, baseAddressBuffer, protectionSizeBuffer, newProtectionType, oldProtectionBuffer);

            if (syscallResult != Enumerations.NtStatus.Success)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to protect memory in the target process", syscallResult);
            }

            // Marshal the returned old protection of the memory region from the buffer

            var oldProtection = (Enumerations.MemoryProtectionType)Marshal.PtrToStructure <ulong>(oldProtectionBuffer);

            MemoryTools.FreeMemoryForBuffer(baseAddressBuffer);

            MemoryTools.FreeMemoryForBuffer(protectionSizeBuffer);

            MemoryTools.FreeMemoryForBuffer(oldProtectionBuffer);

            return(oldProtection);
        }
Esempio n. 2
0
        internal IntPtr Invoke(SafeProcessHandle processHandle, int allocationSize, Enumerations.MemoryProtectionType protectionType)
        {
            // Initialise a buffer to store the returned address of the allocated memory region

            var memoryRegionAddressBuffer = MemoryTools.AllocateMemoryForBuffer(IntPtr.Size);

            // Store the size of the allocation in a buffer

            var allocationSizeBuffer = MemoryTools.StoreStructureInBuffer(allocationSize);

            // Perform the syscall

            const Enumerations.MemoryAllocationType allocationType = Enumerations.MemoryAllocationType.Commit | Enumerations.MemoryAllocationType.Reserve;

            var syscallResult = _ntAllocateVirtualMemoryDelegate(processHandle, memoryRegionAddressBuffer, 0, allocationSizeBuffer, allocationType, protectionType);

            if (syscallResult != Enumerations.NtStatus.Success)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to allocate memory in the target process", syscallResult);
            }

            // Marshal the returned address of the memory region from the buffer

            var memoryRegionAddress = Marshal.PtrToStructure <IntPtr>(memoryRegionAddressBuffer);

            MemoryTools.FreeMemoryForBuffer(memoryRegionAddressBuffer);

            MemoryTools.FreeMemoryForBuffer(allocationSizeBuffer);

            return(memoryRegionAddress);
        }
Esempio n. 3
0
        internal void WriteVirtualMemory <TStructure>(IntPtr baseAddress, TStructure structureToWrite) where TStructure : struct
        {
            // Store the structure in a buffer

            var structureBuffer = MemoryTools.StoreStructureInBuffer(structureToWrite);

            // Convert the structure into bytes

            var structureSize = Marshal.SizeOf <TStructure>();

            var structureBytes = new byte[structureSize];

            Marshal.Copy(structureBuffer, structureBytes, 0, structureSize);

            // Write the bytes of the structure into the target process

            WriteVirtualMemory(baseAddress, structureBytes);
        }
Esempio n. 4
0
        internal IntPtr Invoke(SafeThreadHandle threadHandle)
        {
            // Store a context structure in a buffer

            var context = new Structures.Context {
                ContextFlags = Enumerations.ContextFlags.Control
            };

            var contextBuffer = MemoryTools.StoreStructureInBuffer(context);

            // Perform the syscall

            var syscallResult = _ntGetContextThreadDelegate(threadHandle, contextBuffer);

            if (syscallResult != Enumerations.NtStatus.Success)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to get the context of a thread in the target process", syscallResult);
            }

            return(contextBuffer);
        }
Esempio n. 5
0
        internal SafeProcessHandle Invoke(int processId)
        {
            // Initialise a buffer to store the returned process handle

            var processHandleBuffer = MemoryTools.AllocateMemoryForBuffer(IntPtr.Size);

            // Store an empty object attributes structure in a buffer

            var objectAttributesBuffer = MemoryTools.StoreStructureInBuffer(new Structures.ObjectAttributes());

            // Store a client id structure in a buffer

            var clientId = new Structures.ClientId {
                UniqueProcess = new IntPtr(processId), UniqueThread = IntPtr.Zero
            };

            var clientIdBuffer = MemoryTools.StoreStructureInBuffer(clientId);

            // Perform the syscall

            var syscallResult = _ntOpenProcessDelegate(processHandleBuffer, Enumerations.ProcessAccessMask.AllAccess, objectAttributesBuffer, clientIdBuffer);

            if (syscallResult != Enumerations.NtStatus.Success)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to open a handle to the target process", syscallResult);
            }

            // Marshal the returned process handle from the buffer

            var processHandle = new SafeProcessHandle(Marshal.PtrToStructure <IntPtr>(processHandleBuffer), true);

            MemoryTools.FreeMemoryForBuffer(processHandleBuffer);

            MemoryTools.FreeMemoryForBuffer(objectAttributesBuffer);

            MemoryTools.FreeMemoryForBuffer(clientIdBuffer);

            return(processHandle);
        }
Esempio n. 6
0
        internal void Invoke(SafeProcessHandle processHandle, IntPtr baseAddress)
        {
            // Store the base address of memory region to free in a buffer

            var baseAddressBuffer = MemoryTools.StoreStructureInBuffer(baseAddress);

            // Store the free size in a buffer

            var freeSizeBuffer = MemoryTools.StoreStructureInBuffer(0);

            // Perform the syscall

            var syscallResult = _ntFreeVirtualMemoryDelegate(processHandle, baseAddressBuffer, freeSizeBuffer, Enumerations.MemoryFreeType.Release);

            if (syscallResult != Enumerations.NtStatus.Success)
            {
                ExceptionHandler.ThrowWin32Exception("Failed to free memory in the target process", syscallResult);
            }

            MemoryTools.FreeMemoryForBuffer(baseAddressBuffer);

            MemoryTools.FreeMemoryForBuffer(freeSizeBuffer);
        }
Esempio n. 7
0
        internal bool Call()
        {
            // Get the address of the LoadLibraryW function

            var loadLibraryAddress = _propertyWrapper.TargetProcess.GetFunctionAddress("kernel32.dll", "LoadLibraryW");

            // Write the DLL path into the target process

            var dllPathBuffer = _propertyWrapper.MemoryManager.AllocateVirtualMemory(_propertyWrapper.DllPath.Length, Enumerations.MemoryProtectionType.ExecuteReadWrite);

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

            _propertyWrapper.MemoryManager.WriteVirtualMemory(dllPathBuffer, dllPathBytes);

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

            var threadHandle = (SafeThreadHandle)_propertyWrapper.SyscallManager.InvokeSyscall <NtOpenThread>(_propertyWrapper.TargetProcess.Process.Threads[0].Id);

            if (_propertyWrapper.TargetProcess.IsWow64)
            {
                // Suspend the thread

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

                // Get the context of the thread

                var threadContextBuffer = MemoryTools.StoreStructureInBuffer(new Structures.Wow64Context {
                    ContextFlags = Enumerations.ContextFlags.Control
                });

                if (PInvoke.Wow64GetThreadContext(threadHandle, threadContextBuffer) == 0)
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to get the context of a thread in the target process");
                }

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

                // Write the shellcode used to call LoadLibraryW from the thread into the target process

                var shellcode = ThreadHijackX86.GetShellcode((IntPtr)threadContext.Eip, dllPathBuffer, loadLibraryAddress);

                var shellcodeBuffer = _propertyWrapper.MemoryManager.AllocateVirtualMemory(shellcode.Length, Enumerations.MemoryProtectionType.ExecuteReadWrite);

                _propertyWrapper.MemoryManager.WriteVirtualMemory(shellcodeBuffer, shellcode);

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

                threadContext.Eip = (uint)shellcodeBuffer;

                // Set the context of the thread

                threadContextBuffer = MemoryTools.StoreStructureInBuffer(threadContext);

                if (PInvoke.Wow64SetThreadContext(threadHandle, threadContextBuffer) == 0)
                {
                    ExceptionHandler.ThrowWin32Exception("Failed to set the context of a thread in the target process");
                }

                MemoryTools.FreeMemoryForBuffer(threadContextBuffer);
            }

            else
            {
                // Suspend the thread

                _propertyWrapper.SyscallManager.InvokeSyscall <NtSuspendThread>(threadHandle);

                // Get the context of the thread

                var threadContextBuffer = (IntPtr)_propertyWrapper.SyscallManager.InvokeSyscall <NtGetContextThread>(threadHandle);

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

                // Write the shellcode used to call LoadLibraryW from the thread into the target process

                var shellcode = ThreadHijackX64.GetShellcode((IntPtr)threadContext.Rip, dllPathBuffer, loadLibraryAddress);

                var shellcodeBuffer = _propertyWrapper.MemoryManager.AllocateVirtualMemory(shellcode.Length, Enumerations.MemoryProtectionType.ExecuteReadWrite);

                _propertyWrapper.MemoryManager.WriteVirtualMemory(shellcodeBuffer, shellcode);

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

                threadContext.Rip = (ulong)shellcodeBuffer;

                // Set the context of the thread

                threadContextBuffer = MemoryTools.StoreStructureInBuffer(threadContext);

                _propertyWrapper.SyscallManager.InvokeSyscall <NtSetThreadContext>(threadHandle, threadContextBuffer);

                MemoryTools.FreeMemoryForBuffer(threadContextBuffer);
            }

            // Resume the thread

            _propertyWrapper.SyscallManager.InvokeSyscall <NtResumeThread>(threadHandle);

            PInvoke.SwitchToThisWindow(_propertyWrapper.TargetProcess.Process.MainWindowHandle, true);

            threadHandle.Dispose();

            return(true);
        }