Esempio n. 1
0
 private void CallTlsCallbacks(InjectionProperties injectionProperties, IntPtr remoteDllAddress)
 {
     foreach (var tlsCallback in injectionProperties.PeParser.GetTlsCallbacks())
     {
         CallEntryPoint(injectionProperties, remoteDllAddress, remoteDllAddress.AddOffset(tlsCallback.Offset));
     }
 }
Esempio n. 2
0
        public bool Call(InjectionProperties injectionProperties)
        {
            // Get the address of the LoadLibraryW function in the target process

            var loadLibraryAddress = injectionProperties.RemoteProcess.GetFunctionAddress("kernel32.dll", "LoadLibraryW");

            // Write the DLL path into the target process

            var dllPathBuffer = injectionProperties.MemoryManager.AllocateVirtualMemory(IntPtr.Zero, injectionProperties.DllPath.Length, Enumerations.MemoryProtectionType.ExecuteReadWrite);

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

            injectionProperties.MemoryManager.WriteVirtualMemory(dllPathBuffer, dllPathBytes);

            // Create a thread to call LoadLibraryW in the target process

            var ntStatus = PInvoke.RtlCreateUserThread(injectionProperties.RemoteProcess.Handle, IntPtr.Zero, false, 0, IntPtr.Zero, IntPtr.Zero, loadLibraryAddress, dllPathBuffer, out var remoteThreadHandle, IntPtr.Zero);

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

            PInvoke.WaitForSingleObject(remoteThreadHandle, uint.MaxValue);

            injectionProperties.MemoryManager.FreeVirtualMemory(dllPathBuffer);

            remoteThreadHandle.Dispose();

            return(true);
        }
Esempio n. 3
0
        public bool Call(InjectionProperties injectionProperties)
        {
            // Get the address of FreeLibraryAndExitThread function in the target process

            var freeLibraryAndExitThreadAddress = injectionProperties.RemoteProcess.GetFunctionAddress("kernel32.dll", "FreeLibraryAndExitThread");

            // Look for the DLL in the module list of the target process

            var dllName = Path.GetFileName(injectionProperties.DllPath);

            var module = injectionProperties.RemoteProcess.Modules.Find(m => m.Name == dllName);

            if (module.Equals(default(ModuleInstance)))
            {
                throw new ArgumentException($"No DLL with the name {dllName} was found in the target processes module list");
            }

            // Create a thread to call FreeLibraryAndExitThread in the target process

            var remoteThreadHandle = (SafeThreadHandle)injectionProperties.SyscallManager.InvokeSyscall <NtCreateThreadEx>(injectionProperties.RemoteProcess.Handle, freeLibraryAndExitThreadAddress, module.BaseAddress);

            PInvoke.WaitForSingleObject(remoteThreadHandle, uint.MaxValue);

            remoteThreadHandle.Dispose();

            return(true);
        }
Esempio n. 4
0
        public bool Call(InjectionProperties injectionProperties)
        {
            // Look for the DLL in the module list of the target process

            var dllName = Path.GetFileName(injectionProperties.DllPath);

            var module = injectionProperties.RemoteProcess.Modules.Find(m => m.Name == dllName);

            if (module.Equals(default(ModuleInstance)))
            {
                throw new ArgumentException($"No DLL with the name {dllName} was found in the target processes module list");
            }

            // Query the header region of the DLL in the target process

            var memoryInformationBuffer = (IntPtr)injectionProperties.SyscallManager.InvokeSyscall <NtQueryVirtualMemory>(injectionProperties.RemoteProcess.Handle, module.BaseAddress);

            var memoryInformation = Marshal.PtrToStructure <Structures.MemoryBasicInformation>(memoryInformationBuffer);

            // Write over the header region with random bytes

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

            new Random().NextBytes(randomBuffer);

            injectionProperties.MemoryManager.WriteVirtualMemory(module.BaseAddress, randomBuffer);

            return(true);
        }
Esempio n. 5
0
        private void MapSections(InjectionProperties injectionProperties, IntPtr localDllAddress, IntPtr remoteDllAddress)
        {
            foreach (var section in injectionProperties.PeParser.GetHeaders().SectionHeaders)
            {
                // Get the data of the section

                var sectionDataAddress = localDllAddress.AddOffset(section.PointerToRawData);

                var sectionData = new byte[section.SizeOfRawData];

                Marshal.Copy(sectionDataAddress, sectionData, 0, (int)section.SizeOfRawData);

                // Write the section into the target process

                var sectionAddress = remoteDllAddress.AddOffset(section.VirtualAddress);

                injectionProperties.MemoryManager.WriteVirtualMemory(sectionAddress, sectionData);

                // Adjust the protection of the section

                var sectionProtection = GetSectionProtection(section.Characteristics);

                injectionProperties.MemoryManager.ProtectVirtualMemory(sectionAddress, (int)section.SizeOfRawData, sectionProtection);
            }
        }
Esempio n. 6
0
        public bool Call(InjectionProperties injectionProperties)
        {
            // Get the address of the LoadLibraryW function in the target process

            var loadLibraryAddress = injectionProperties.RemoteProcess.GetFunctionAddress("kernel32.dll", "LoadLibraryW");

            // Write the DLL path into the target process

            var dllPathBuffer = injectionProperties.MemoryManager.AllocateVirtualMemory(IntPtr.Zero, injectionProperties.DllPath.Length, Native.Enumerations.MemoryProtectionType.ExecuteReadWrite);

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

            injectionProperties.MemoryManager.WriteVirtualMemory(dllPathBuffer, dllPathBytes);

            foreach (var thread in injectionProperties.RemoteProcess.TargetProcess.Threads.Cast <ProcessThread>())
            {
                using (var threadHandle = (SafeThreadHandle)injectionProperties.SyscallManager.InvokeSyscall <NtOpenThread>(thread.Id))
                {
                    // Add an APC to call LoadLibraryW to the APC queue of the thread

                    injectionProperties.SyscallManager.InvokeSyscall <NtQueueApcThread>(threadHandle, loadLibraryAddress, dllPathBuffer);
                }
            }

            injectionProperties.MemoryManager.FreeVirtualMemory(dllPathBuffer);

            return(true);
        }
Esempio n. 7
0
        public bool Call(InjectionProperties injectionProperties)
        {
            // Get the address of the LoadLibraryW function in the target process

            var loadLibraryAddress = injectionProperties.RemoteProcess.GetFunctionAddress("kernel32.dll", "LoadLibraryW");

            // Write the DLL path into the target process

            var dllPathBuffer = injectionProperties.MemoryManager.AllocateVirtualMemory(IntPtr.Zero, injectionProperties.DllPath.Length, Enumerations.MemoryProtectionType.ExecuteReadWrite);

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

            injectionProperties.MemoryManager.WriteVirtualMemory(dllPathBuffer, dllPathBytes);

            // Create a thread to call LoadLibraryW in the target process

            var remoteThreadHandle = (SafeThreadHandle)injectionProperties.SyscallManager.InvokeSyscall <NtCreateThreadEx>(injectionProperties.RemoteProcess.Handle, loadLibraryAddress, dllPathBuffer);

            PInvoke.WaitForSingleObject(remoteThreadHandle, uint.MaxValue);

            injectionProperties.MemoryManager.FreeVirtualMemory(dllPathBuffer);

            remoteThreadHandle.Dispose();

            return(true);
        }
Esempio n. 8
0
        internal InjectionManager(int targetProcessId, string dllPath, bool isExtension, bool randomiseDllName)
        {
            // Ensure the users operating system is valid

            ValidationHandler.ValidateOperatingSystem();

            // Ensure the arguments passed in are valid

            if (targetProcessId <= 0 || string.IsNullOrWhiteSpace(dllPath))
            {
                throw new ArgumentException("One or more of the arguments provided were invalid");
            }

            // Ensure a valid DLL exists at the provided path

            if (!File.Exists(dllPath) || Path.GetExtension(dllPath) != ".dll")
            {
                throw new ArgumentException("No DLL file exists at the provided path");
            }

            if (randomiseDllName && isExtension)
            {
                // Assume the DLL is the newest file in the directory

                var directoryInfo = new DirectoryInfo(Path.Combine(Path.GetTempPath(), "Bleak"));

                var newestFile = directoryInfo.GetFiles().OrderByDescending(file => file.LastWriteTime).First();

                _injectionProperties = new InjectionProperties(targetProcessId, newestFile.FullName);
            }

            else if (randomiseDllName)
            {
                // Create a temporary DLL on disk

                var temporaryDllPath = DllTools.CreateTemporaryDll(DllTools.GenerateRandomDllName(), File.ReadAllBytes(dllPath));

                _injectionProperties = new InjectionProperties(targetProcessId, temporaryDllPath);
            }

            else
            {
                _injectionProperties = new InjectionProperties(targetProcessId, dllPath);
            }

            // Ensure the architecture of the DLL is valid

            ValidationHandler.ValidateDllArchitecture(_injectionProperties);
        }
Esempio n. 9
0
        internal static void ValidateDllArchitecture(InjectionProperties injectionProperties)
        {
            // Ensure the architecture of the target process matches the architecture of the DLL

            if (injectionProperties.RemoteProcess.IsWow64 != (injectionProperties.PeParser.GetArchitecture() == Enumerations.MachineType.X86))
            {
                throw new ApplicationException("The architecture of the target process did not match the architecture of the DLL");
            }

            // Ensure that x64 injection is not being attempted from an x86 build

            if (!Environment.Is64BitProcess && !injectionProperties.RemoteProcess.IsWow64)
            {
                throw new ApplicationException("x64 injection is not supported when compiled under x86");
            }
        }
Esempio n. 10
0
        internal InjectionManager(int targetProcessId, byte[] dllBytes, bool manualMap, bool isExtension, bool randomiseDllName)
        {
            // Ensure the users operating system is valid

            ValidationHandler.ValidateOperatingSystem();

            // Ensure the arguments passed in are valid

            if (targetProcessId <= 0 || dllBytes is null || dllBytes.Length == 0)
            {
                throw new ArgumentException("One or more of the arguments provided were invalid");
            }

            if (manualMap)
            {
                _injectionProperties = new InjectionProperties(targetProcessId, dllBytes);
            }

            else if (randomiseDllName && isExtension)
            {
                // Assume the DLL is the newest file in the directory

                var directoryInfo = new DirectoryInfo(Path.Combine(Path.GetTempPath(), "Bleak"));

                var newestFile = directoryInfo.GetFiles().OrderByDescending(file => file.LastWriteTime).First();

                _injectionProperties = new InjectionProperties(targetProcessId, newestFile.FullName);
            }

            else
            {
                // Create a temporary DLL on disk

                var temporaryDllName = randomiseDllName ? DllTools.GenerateRandomDllName() : DllTools.GenerateDllName(dllBytes);

                _injectionProperties = new InjectionProperties(targetProcessId, DllTools.CreateTemporaryDll(temporaryDllName, dllBytes));
            }

            // Ensure the architecture of the DLL is valid

            ValidationHandler.ValidateDllArchitecture(_injectionProperties);
        }
Esempio n. 11
0
        private void MapHeaders(InjectionProperties injectionProperties, IntPtr remoteDllAddress)
        {
            // Determine the size of the PE headers of the DLL

            var headerSize = injectionProperties.RemoteProcess.IsWow64
                           ? injectionProperties.PeParser.GetHeaders().NtHeaders32.OptionalHeader.SizeOfHeaders
                           : injectionProperties.PeParser.GetHeaders().NtHeaders64.OptionalHeader.SizeOfHeaders;

            var headerBytes = new byte[headerSize];

            // Fill the header bytes with random bytes

            new Random().NextBytes(headerBytes);

            // Write the PE headers into the target process

            injectionProperties.MemoryManager.WriteVirtualMemory(remoteDllAddress, headerBytes);

            // Adjust the protection of the PE header region

            injectionProperties.MemoryManager.ProtectVirtualMemory(remoteDllAddress, (int)headerSize, Enumerations.MemoryProtectionType.ReadOnly);
        }
Esempio n. 12
0
        private void RemoveDoublyLinkedListEntry(InjectionProperties injectionProperties, Structures.ListEntry64 entry)
        {
            // Read the previous entry from the doubly linked list

            var previousEntry = injectionProperties.MemoryManager.ReadVirtualMemory <Structures.ListEntry64>((IntPtr)entry.Blink);

            // Change the front link of the previous entry to the front link of the entry

            previousEntry.Flink = entry.Flink;

            injectionProperties.MemoryManager.WriteVirtualMemory((IntPtr)entry.Blink, previousEntry);

            // Read the next entry from the doubly linked list

            var nextEntry = injectionProperties.MemoryManager.ReadVirtualMemory <Structures.ListEntry64>((IntPtr)entry.Flink);

            // Change the back link of the next entry to the back link of the entry

            nextEntry.Blink = entry.Blink;

            injectionProperties.MemoryManager.WriteVirtualMemory((IntPtr)entry.Flink, nextEntry);
        }
Esempio n. 13
0
        private void CallEntryPoint(InjectionProperties injectionProperties, IntPtr remoteDllAddress, IntPtr entryPointAddress)
        {
            // Write the shellcode used to call the entry point of the DLL or TLS callback in the target process

            var shellcode = injectionProperties.RemoteProcess.IsWow64
                          ? CallDllMainX86.GetShellcode(remoteDllAddress, entryPointAddress)
                          : CallDllMainX64.GetShellcode(remoteDllAddress, entryPointAddress);

            var shellcodeBuffer = injectionProperties.MemoryManager.AllocateVirtualMemory(IntPtr.Zero, shellcode.Length, Enumerations.MemoryProtectionType.ExecuteReadWrite);

            injectionProperties.MemoryManager.WriteVirtualMemory(shellcodeBuffer, shellcode);

            // Create a thread to call the shellcode in the target process

            var remoteThreadHandle = (SafeThreadHandle)injectionProperties.SyscallManager.InvokeSyscall <NtCreateThreadEx>(injectionProperties.RemoteProcess.Handle, shellcodeBuffer, IntPtr.Zero);

            PInvoke.WaitForSingleObject(remoteThreadHandle, uint.MaxValue);

            injectionProperties.MemoryManager.FreeVirtualMemory(shellcodeBuffer);

            remoteThreadHandle.Dispose();
        }
Esempio n. 14
0
        private void BuildImportTable(InjectionProperties injectionProperties, IntPtr localDllAddress)
        {
            var importedFunctions = injectionProperties.PeParser.GetImportedFunctions();

            if (importedFunctions.Count == 0)
            {
                // The DLL has no imported functions

                return;
            }

            // Group the imported functions by the DLL they reside in

            var groupedFunctions = importedFunctions.GroupBy(importedFunction => importedFunction.DllName).ToList();

            // Get the API set mappings

            List <ApiSetMapping> apiSetMappings;

            using (var peParser = new PeParser(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "apisetschema.dll")))
            {
                apiSetMappings = peParser.GetApiSetMappings();
            }

            var systemFolderPath = injectionProperties.RemoteProcess.IsWow64
                                 ? Environment.GetFolderPath(Environment.SpecialFolder.SystemX86)
                                 : Environment.GetFolderPath(Environment.SpecialFolder.System);

            foreach (var dll in groupedFunctions)
            {
                var dllName = dll.Key;

                if (dllName.StartsWith("api-ms"))
                {
                    dllName = apiSetMappings.Find(apiSetMapping => apiSetMapping.VirtualDll.Equals(dllName, StringComparison.OrdinalIgnoreCase)).MappedToDll;
                }

                // Ensure the DLL is loaded in the target process

                if (!injectionProperties.RemoteProcess.Modules.Any(module => module.Name.Equals(dllName, StringComparison.OrdinalIgnoreCase)))
                {
                    // Load the DLL into the target process

                    new Injector().CreateRemoteThread(injectionProperties.RemoteProcess.TargetProcess.Id, Path.Combine(systemFolderPath, dllName));
                }
            }

            injectionProperties.RemoteProcess.Refresh();

            foreach (var importedFunction in groupedFunctions.SelectMany(dll => dll.Select(importedFunction => importedFunction)))
            {
                var dllName = importedFunction.DllName;

                if (dllName.StartsWith("api-ms"))
                {
                    dllName = apiSetMappings.Find(apiSetMapping => apiSetMapping.VirtualDll.Equals(dllName, StringComparison.OrdinalIgnoreCase)).MappedToDll;
                }

                // Get the address of the imported function

                var importedFunctionAddress = injectionProperties.RemoteProcess.GetFunctionAddress(dllName, importedFunction.Name);

                // Write the imported function into the local process

                Marshal.WriteInt64(localDllAddress.AddOffset(importedFunction.Offset), (long)importedFunctionAddress);
            }
        }
Esempio n. 15
0
        private void PerformRelocations(InjectionProperties injectionProperties, IntPtr localDllAddress, IntPtr remoteDllAddress)
        {
            var baseRelocations = injectionProperties.PeParser.GetBaseRelocations();

            if (baseRelocations.Count == 0)
            {
                // No relocations need to be applied

                return;
            }

            var peHeaders = injectionProperties.PeParser.GetHeaders();

            var baseAddress = injectionProperties.RemoteProcess.IsWow64
                            ? peHeaders.NtHeaders32.OptionalHeader.ImageBase
                            : peHeaders.NtHeaders64.OptionalHeader.ImageBase;

            // Calculate the base address delta

            var delta = (long)remoteDllAddress - (long)baseAddress;

            if (delta == 0)
            {
                // The DLL is loaded at its default base address and no relocations need to be applied

                return;
            }

            foreach (var baseRelocation in baseRelocations)
            {
                // Calculate the base address of the relocation block

                var relocationBlockAddress = localDllAddress.AddOffset(baseRelocation.Offset);

                foreach (var relocation in baseRelocation.Relocations)
                {
                    // Calculate the address of the relocation

                    var relocationAddress = relocationBlockAddress.AddOffset(relocation.Offset);

                    switch (relocation.Type)
                    {
                    case Enumerations.RelocationType.HighLow:
                    {
                        // Perform the relocation

                        var relocationValue = Marshal.ReadInt32(relocationAddress) + (int)delta;

                        Marshal.WriteInt32(relocationAddress, relocationValue);

                        break;
                    }

                    case Enumerations.RelocationType.Dir64:
                    {
                        // Perform the relocation

                        var relocationValue = Marshal.ReadInt64(relocationAddress) + delta;

                        Marshal.WriteInt64(relocationAddress, relocationValue);

                        break;
                    }
                    }
                }
            }
        }
Esempio n. 16
0
        public bool Call(InjectionProperties injectionProperties)
        {
            var localDllAddress = injectionProperties.DllPath is null
                                ? LocalMemoryTools.StoreBytesInBuffer(injectionProperties.DllBytes)
                                : LocalMemoryTools.StoreBytesInBuffer(File.ReadAllBytes(injectionProperties.DllPath));

            // Build the import table of the DLL

            BuildImportTable(injectionProperties, localDllAddress);

            var peHeaders = injectionProperties.PeParser.GetHeaders();

            // Allocate memory for the DLL in the target process

            var allocationBaseAddress = injectionProperties.RemoteProcess.IsWow64
                                      ? peHeaders.NtHeaders32.OptionalHeader.ImageBase
                                      : peHeaders.NtHeaders64.OptionalHeader.ImageBase;

            var dllSize = injectionProperties.RemoteProcess.IsWow64
                        ? peHeaders.NtHeaders32.OptionalHeader.SizeOfImage
                        : peHeaders.NtHeaders64.OptionalHeader.SizeOfImage;

            IntPtr remoteDllAddress;

            try
            {
                remoteDllAddress = injectionProperties.MemoryManager.AllocateVirtualMemory((IntPtr)allocationBaseAddress, (int)dllSize, Enumerations.MemoryProtectionType.ExecuteReadWrite);
            }

            catch (Win32Exception)
            {
                remoteDllAddress = injectionProperties.MemoryManager.AllocateVirtualMemory(IntPtr.Zero, (int)dllSize, Enumerations.MemoryProtectionType.ExecuteReadWrite);
            }

            // Perform any needed relocations

            PerformRelocations(injectionProperties, localDllAddress, remoteDllAddress);

            // Map the sections of the DLL

            MapSections(injectionProperties, localDllAddress, remoteDllAddress);

            // Map randomised PE headers

            MapHeaders(injectionProperties, remoteDllAddress);

            // Call any TLS callbacks

            CallTlsCallbacks(injectionProperties, remoteDllAddress);

            // Call the entry point of the DLL

            var dllEntryPointAddress = injectionProperties.RemoteProcess.IsWow64
                                     ? remoteDllAddress.AddOffset(peHeaders.NtHeaders32.OptionalHeader.AddressOfEntryPoint)
                                     : remoteDllAddress.AddOffset(peHeaders.NtHeaders64.OptionalHeader.AddressOfEntryPoint);

            if (dllEntryPointAddress != remoteDllAddress)
            {
                CallEntryPoint(injectionProperties, remoteDllAddress, dllEntryPointAddress);
            }

            LocalMemoryTools.FreeMemoryForBuffer(localDllAddress);

            return(true);
        }
Esempio n. 17
0
        public bool Call(InjectionProperties injectionProperties)
        {
            // Get the address of the LoadLibraryW function in the target process

            var loadLibraryAddress = injectionProperties.RemoteProcess.GetFunctionAddress("kernel32.dll", "LoadLibraryW");

            // Write the DLL path into the target process

            var dllPathBuffer = injectionProperties.MemoryManager.AllocateVirtualMemory(IntPtr.Zero, injectionProperties.DllPath.Length, Enumerations.MemoryProtectionType.ExecuteReadWrite);

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

            injectionProperties.MemoryManager.WriteVirtualMemory(dllPathBuffer, dllPathBytes);

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

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

            if (injectionProperties.RemoteProcess.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 = LocalMemoryTools.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);

                LocalMemoryTools.FreeMemoryForBuffer(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 = injectionProperties.MemoryManager.AllocateVirtualMemory(IntPtr.Zero, shellcode.Length, Enumerations.MemoryProtectionType.ExecuteReadWrite);

                injectionProperties.MemoryManager.WriteVirtualMemory(shellcodeBuffer, shellcode);

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

                threadContext.Eip = (uint)shellcodeBuffer;

                threadContextBuffer = LocalMemoryTools.StoreStructureInBuffer(threadContext);

                // Update the context of the thread

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

                LocalMemoryTools.FreeMemoryForBuffer(threadContextBuffer);
            }

            else
            {
                // Suspend the thread

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

                // Get the context of the thread

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

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

                LocalMemoryTools.FreeMemoryForBuffer(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 = injectionProperties.MemoryManager.AllocateVirtualMemory(IntPtr.Zero, shellcode.Length, Enumerations.MemoryProtectionType.ExecuteReadWrite);

                injectionProperties.MemoryManager.WriteVirtualMemory(shellcodeBuffer, shellcode);

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

                threadContext.Rip = (ulong)shellcodeBuffer;

                threadContextBuffer = LocalMemoryTools.StoreStructureInBuffer(threadContext);

                // Update the context of the thread

                injectionProperties.SyscallManager.InvokeSyscall <NtSetContextThread>(threadHandle, threadContextBuffer);

                LocalMemoryTools.FreeMemoryForBuffer(threadContextBuffer);
            }

            // Resume the thread

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

            PInvoke.SwitchToThisWindow(injectionProperties.RemoteProcess.TargetProcess.MainWindowHandle, true);

            threadHandle.Dispose();

            return(true);
        }
Esempio n. 18
0
        public bool Call(InjectionProperties injectionProperties)
        {
            var dllUnlinked = false;

            if (injectionProperties.RemoteProcess.IsWow64)
            {
                var entryFilePathRegex = new Regex("System32", RegexOptions.IgnoreCase);

                foreach (var entry in injectionProperties.RemoteProcess.GetWow64PebEntries())
                {
                    // Read the file path of the entry

                    var entryFilePathBytes = injectionProperties.MemoryManager.ReadVirtualMemory((IntPtr)entry.FullDllName.Buffer, entry.FullDllName.Length);

                    var entryFilePath = entryFilePathRegex.Replace(Encoding.Unicode.GetString(entryFilePathBytes), "SysWOW64");

                    if (entryFilePath.Equals(injectionProperties.DllPath, StringComparison.OrdinalIgnoreCase))
                    {
                        // Remove the entry from the doubly linked lists

                        RemoveDoublyLinkedListEntry(injectionProperties, entry.InLoadOrderLinks);

                        RemoveDoublyLinkedListEntry(injectionProperties, entry.InMemoryOrderLinks);

                        RemoveDoublyLinkedListEntry(injectionProperties, entry.InInitializationOrderLinks);

                        // Remove the entry from the LdrpHashTable

                        RemoveDoublyLinkedListEntry(injectionProperties, entry.HashLinks);

                        // Write over the entry strings with zeroes

                        injectionProperties.MemoryManager.WriteVirtualMemory((IntPtr)entry.BaseDllName.Buffer, new byte[entry.BaseDllName.MaximumLength]);

                        injectionProperties.MemoryManager.WriteVirtualMemory((IntPtr)entry.FullDllName.Buffer, new byte[entry.FullDllName.MaximumLength]);

                        dllUnlinked = true;

                        break;
                    }
                }
            }

            else
            {
                foreach (var entry in injectionProperties.RemoteProcess.GetPebEntries())
                {
                    // Read the file path of the entry

                    var entryFilePathBytes = injectionProperties.MemoryManager.ReadVirtualMemory((IntPtr)entry.FullDllName.Buffer, entry.FullDllName.Length);

                    var entryFilePath = Encoding.Unicode.GetString(entryFilePathBytes);

                    if (entryFilePath.Equals(injectionProperties.DllPath, StringComparison.OrdinalIgnoreCase))
                    {
                        // Remove the entry from the doubly linked lists

                        RemoveDoublyLinkedListEntry(injectionProperties, entry.InLoadOrderLinks);

                        RemoveDoublyLinkedListEntry(injectionProperties, entry.InMemoryOrderLinks);

                        RemoveDoublyLinkedListEntry(injectionProperties, entry.InInitializationOrderLinks);

                        // Remove the entry from the LdrpHashTable

                        RemoveDoublyLinkedListEntry(injectionProperties, entry.HashLinks);

                        // Write over the entry strings with zeroes

                        injectionProperties.MemoryManager.WriteVirtualMemory((IntPtr)entry.BaseDllName.Buffer, new byte[entry.BaseDllName.MaximumLength]);

                        injectionProperties.MemoryManager.WriteVirtualMemory((IntPtr)entry.FullDllName.Buffer, new byte[entry.FullDllName.MaximumLength]);

                        dllUnlinked = true;

                        break;
                    }
                }
            }

            if (!dllUnlinked)
            {
                throw new ArgumentException($"No DLL with the name {Path.GetFileName(injectionProperties.DllPath)} was found in the target processes module list");
            }

            return(true);
        }