internal IntPtr Invoke(SafeProcessHandle processHandle, IntPtr baseAddress, int size, Enumerations.MemoryProtectionType protectionType) { // Store the base address of the allocation in a buffer var baseAddressBuffer = LocalMemoryTools.StoreStructureInBuffer(baseAddress); // Store the size of the allocation in a buffer var sizeBuffer = LocalMemoryTools.StoreStructureInBuffer(size); // Perform the syscall const Enumerations.MemoryAllocationType allocationType = Enumerations.MemoryAllocationType.Commit | Enumerations.MemoryAllocationType.Reserve; var syscallResult = _ntAllocateVirtualMemoryDelegate(processHandle, baseAddressBuffer, 0, sizeBuffer, allocationType, protectionType); if (syscallResult != Enumerations.NtStatus.Success) { ExceptionHandler.ThrowWin32Exception("Failed to allocate memory in the target process", syscallResult); } try { return(Marshal.PtrToStructure <IntPtr>(baseAddressBuffer)); } finally { LocalMemoryTools.FreeMemoryForBuffer(baseAddressBuffer); LocalMemoryTools.FreeMemoryForBuffer(sizeBuffer); } }
internal SafeThreadHandle Invoke(SafeProcessHandle processHandle, IntPtr startAddress, IntPtr parameter) { // Initialise a buffer to store the returned thread handle var threadHandleBuffer = LocalMemoryTools.AllocateMemoryForBuffer(IntPtr.Size); // Perform the syscall const Enumerations.ThreadAccessMask desiredAccess = Enumerations.ThreadAccessMask.SpecificRightsAll | Enumerations.ThreadAccessMask.StandardRightsAll; var syscallResult = _ntCreateThreadExDelegate(threadHandleBuffer, desiredAccess, IntPtr.Zero, processHandle, startAddress, parameter, Enumerations.ThreadCreationType.HideFromDebugger, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); if (syscallResult != Enumerations.NtStatus.Success) { ExceptionHandler.ThrowWin32Exception("Failed to create a thread in the target process", syscallResult); } try { return(new SafeThreadHandle(Marshal.PtrToStructure <IntPtr>(threadHandleBuffer), true)); } finally { LocalMemoryTools.FreeMemoryForBuffer(threadHandleBuffer); } }
internal SafeProcessHandle Invoke(int processId) { // Initialise a buffer to store the returned process handle var processHandleBuffer = LocalMemoryTools.AllocateMemoryForBuffer(IntPtr.Size); // Store an empty object attributes structure in a buffer var objectAttributesBuffer = LocalMemoryTools.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 = LocalMemoryTools.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); } try { return(new SafeProcessHandle(Marshal.PtrToStructure <IntPtr>(processHandleBuffer), true)); } finally { LocalMemoryTools.FreeMemoryForBuffer(processHandleBuffer); LocalMemoryTools.FreeMemoryForBuffer(objectAttributesBuffer); LocalMemoryTools.FreeMemoryForBuffer(clientIdBuffer); } }
internal void Invoke(SafeProcessHandle processHandle, IntPtr baseAddress) { // Store the base address of memory region to free in a buffer var baseAddressBuffer = LocalMemoryTools.StoreStructureInBuffer(baseAddress); // Store the free size in a buffer var sizeBuffer = LocalMemoryTools.StoreStructureInBuffer(0); // Perform the syscall var syscallResult = _ntFreeVirtualMemoryDelegate(processHandle, baseAddressBuffer, sizeBuffer, Enumerations.MemoryFreeType.Release); if (syscallResult != Enumerations.NtStatus.Success) { ExceptionHandler.ThrowWin32Exception("Failed to free memory in the target process", syscallResult); } LocalMemoryTools.FreeMemoryForBuffer(baseAddressBuffer); LocalMemoryTools.FreeMemoryForBuffer(sizeBuffer); }
internal Enumerations.MemoryProtectionType Invoke(SafeProcessHandle processHandle, IntPtr baseAddress, int size, Enumerations.MemoryProtectionType protectionType) { // Store the base address of the memory region to protect in a buffer var baseAddressBuffer = LocalMemoryTools.StoreStructureInBuffer(baseAddress); // Store the protection size in a buffer var sizeBuffer = LocalMemoryTools.StoreStructureInBuffer(size); // Initialise a buffer to store the returned old protection of the memory region var oldProtectionBuffer = LocalMemoryTools.AllocateMemoryForBuffer(sizeof(ulong)); // Perform the syscall var syscallResult = _ntProtectVirtualMemoryDelegate(processHandle, baseAddressBuffer, sizeBuffer, protectionType, oldProtectionBuffer); if (syscallResult != Enumerations.NtStatus.Success) { ExceptionHandler.ThrowWin32Exception("Failed to protect memory in the target process", syscallResult); } try { return((Enumerations.MemoryProtectionType)Marshal.PtrToStructure <ulong>(oldProtectionBuffer)); } finally { LocalMemoryTools.FreeMemoryForBuffer(baseAddressBuffer); LocalMemoryTools.FreeMemoryForBuffer(sizeBuffer); LocalMemoryTools.FreeMemoryForBuffer(oldProtectionBuffer); } }
public void Dispose() { LocalMemoryTools.FreeMemoryForBuffer(ShellcodeAddress); }
public void Dispose() { LocalMemoryTools.FreeMemoryForBuffer(_dllBuffer); }
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); }
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); }