所有线程上下文结构的正确实现是什么?
What is the proper implementation of all the thread context structs?
很抱歉发布这个,但是,我正在努力实施 GetThreadContext
和 SetThreadContext
因为结构是错误的,它们还导致库抛出 ReflectionTypeLoadException
.
这是我对结构的实现:
[StructLayout(LayoutKind.Sequential)]
public struct THREAD_CONTEXT_IA32
{
public THREAD_CONTEXT_IA32(IA32_CONTEXT_FLAG flags) : this()
{
cFlags = flags;
}
private IA32_CONTEXT_FLAG cFlags;
public int dr0;
public int dr1;
public int dr2;
public int dr3;
public int dr6;
public int dr7;
public FLOATING_SAVE_AREA floatSave;
public int segGs;
public int segFs;
public int segEs;
public int segDs;
public int edi;
public int esi;
public int ebx;
public int edx;
public int ecx;
public int eax;
public int ebp;
public int eip;
public int segCs;
public int eFlags;
public int esp;
public int segSs;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXIMUM_SUPPORTED_EXTENSION)]
public byte[] extendedRegisters;
}
[StructLayout(LayoutKind.Explicit, Pack = 16)]
public struct THREAD_CONTEXT_AMD64
{
public THREAD_CONTEXT_AMD64(AMD64_CONTEXT_FLAG flags) : this()
{
cFlags = flags;
}
[FieldOffset(0)]
public long p1Home;
[FieldOffset(8)]
public long p2Home;
[FieldOffset(16)]
public long p3Home;
[FieldOffset(24)]
public long p4Home;
[FieldOffset(32)]
public long p5Home;
[FieldOffset(40)]
public long p6Home;
[FieldOffset(48)]
private AMD64_CONTEXT_FLAG cFlags;
[FieldOffset(50)]
public int mxCsr;
[FieldOffset(54)]
public short segCs;
[FieldOffset(56)]
public short segDs;
[FieldOffset(58)]
public short segEs;
[FieldOffset(60)]
public short segFs;
[FieldOffset(62)]
public short segGs;
[FieldOffset(64)]
public short segSs;
[FieldOffset(66)]
public int eFlags;
[FieldOffset(70)]
public long dr0;
[FieldOffset(78)]
public long dr1;
[FieldOffset(86)]
public long dr2;
[FieldOffset(94)]
public long dr3;
[FieldOffset(102)]
public long dr6;
[FieldOffset(110)]
public long dr7;
[FieldOffset(118)]
public long rax;
[FieldOffset(126)]
public long rcx;
[FieldOffset(132)]
public long rdx;
[FieldOffset(140)]
public long rbx;
[FieldOffset(148)]
public long rsp;
[FieldOffset(156)]
public long rbp;
[FieldOffset(174)]
public long rsi;
[FieldOffset(182)]
public long rdi;
[FieldOffset(190)]
public long r8;
[FieldOffset(198)]
public long r9;
[FieldOffset(206)]
public long r10;
[FieldOffset(214)]
public long r11;
[FieldOffset(222)]
public long r12;
[FieldOffset(230)]
public long r13;
[FieldOffset(238)]
public long r14;
[FieldOffset(246)]
public long r15;
[FieldOffset(252)]
public long rip;
[FieldOffset(260)]
public XSAVE_FORMAT fltSave;
[FieldOffset(772)]
public M128A header0;
[FieldOffset(788)]
public M128A header1;
[FieldOffset(804)]
public M128A legacy0;
[FieldOffset(820)]
public M128A legacy1;
[FieldOffset(836)]
public M128A legacy2;
[FieldOffset(852)]
public M128A legacy3;
[FieldOffset(868)]
public M128A legacy4;
[FieldOffset(884)]
public M128A legacy5;
[FieldOffset(900)]
public M128A legacy6;
[FieldOffset(916)]
public M128A legacy7;
[FieldOffset(932)]
public M128A xmm0;
[FieldOffset(948)]
public M128A xmm1;
[FieldOffset(964)]
public M128A xmm2;
[FieldOffset(980)]
public M128A xmm3;
[FieldOffset(996)]
public M128A xmm4;
[FieldOffset(1012)]
public M128A xmm5;
[FieldOffset(1028)]
public M128A xmm6;
[FieldOffset(1044)]
public M128A xmm7;
[FieldOffset(1060)]
public M128A xmm8;
[FieldOffset(1076)]
public M128A xmm9;
[FieldOffset(1092)]
public M128A xmm10;
[FieldOffset(1108)]
public M128A xmm11;
[FieldOffset(1124)]
public M128A xmm12;
[FieldOffset(1140)]
public M128A xmm13;
[FieldOffset(1156)]
public M128A xmm14;
[FieldOffset(1172)]
public M128A xmm15;
[FieldOffset(1188)]
public M128A vectorRegister0;
[FieldOffset(1204)]
public M128A vectorRegister1;
[FieldOffset(1220)]
public M128A vectorRegister2;
[FieldOffset(1236)]
public M128A vectorRegister3;
[FieldOffset(1252)]
public M128A vectorRegister4;
[FieldOffset(1268)]
public M128A vectorRegister5;
[FieldOffset(1284)]
public M128A vectorRegister6;
[FieldOffset(1300)]
public M128A vectorRegister7;
[FieldOffset(1316)]
public M128A vectorRegister8;
[FieldOffset(1332)]
public M128A vectorRegister9;
[FieldOffset(1348)]
public M128A vectorRegister10;
[FieldOffset(1364)]
public M128A vectorRegister11;
[FieldOffset(1380)]
public M128A vectorRegister12;
[FieldOffset(1396)]
public M128A vectorRegister13;
[FieldOffset(1412)]
public M128A vectorRegister14;
[FieldOffset(1428)]
public M128A vectorRegister15;
[FieldOffset(1444)]
public M128A vectorRegister16;
[FieldOffset(1460)]
public M128A vectorRegister17;
[FieldOffset(1476)]
public M128A vectorRegister18;
[FieldOffset(1492)]
public M128A vectorRegister19;
[FieldOffset(1508)]
public M128A vectorRegister20;
[FieldOffset(1524)]
public M128A vectorRegister21;
[FieldOffset(1540)]
public M128A vectorRegister22;
[FieldOffset(1556)]
public M128A vectorRegister23;
[FieldOffset(1572)]
public M128A vectorRegister24;
[FieldOffset(1588)]
public M128A vectorRegister25;
[FieldOffset(1604)]
public long vectorControl;
[FieldOffset(1612)]
public long debugControl;
[FieldOffset(1620)]
public long lastBranchToRip;
[FieldOffset(1628)]
public long lastBranchFromRip;
[FieldOffset(1636)]
public long lastExceptionToRip;
[FieldOffset(1644)]
public long lastExceptionFromRip;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct THREAD_CONTEXT_ARM
{
public THREAD_CONTEXT_ARM(ARM_CONTEXT_FLAG flags) : this()
{
cFlags = flags;
}
private ARM_CONTEXT_FLAG cFlags;
public int r0;
public int r1;
public int r2;
public int r3;
public int r4;
public int r5;
public int r6;
public int r7;
public int r8;
public int r9;
public int r10;
public int r11;
public int r12;
public int sp;
public int lr;
public int pc;
public int cpsr;
public int fpscr;
public int padding;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public NEON128[] neon;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM_MAX_BREAKPOINTS)]
public int[] bvr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM_MAX_BREAKPOINTS)]
public int[] bcr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM_MAX_WATCHPOINTS)]
public int[] wvr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM_MAX_WATCHPOINTS)]
public int[] wcr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public int[] padding2;
}
[StructLayout(LayoutKind.Sequential, Pack = 16)]
public struct THREAD_CONTEXT_ARM64
{
public THREAD_CONTEXT_ARM64(ARM64_CONTEXT_FLAG flags) : this()
{
cFlags = flags;
}
private ARM64_CONTEXT_FLAG cFlags;
public int cpsr;
public long x0;
public long x1;
public long x2;
public long x3;
public long x4;
public long x5;
public long x6;
public long x7;
public long x8;
public long x9;
public long x10;
public long x11;
public long x12;
public long x13;
public long x14;
public long x15;
public long x16;
public long x17;
public long x18;
public long x19;
public long x20;
public long x21;
public long x22;
public long x23;
public long x24;
public long x25;
public long x26;
public long x27;
public long x28;
public long fp;
public long lr;
public long sp;
public long pc;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public NEON128[] neon;
public int fpcr;
public int fpsr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM64_MAX_BREAKPOINTS)]
public int[] bcr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM64_MAX_BREAKPOINTS)]
public long[] bvr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM64_MAX_WATCHPOINTS)]
public int[] wcr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM64_MAX_WATCHPOINTS)]
public long[] wvr;
}
[StructLayout(LayoutKind.Sequential)]
public struct THREAD_CONTEXT_WOW64
{
public THREAD_CONTEXT_WOW64(WOW64_CONTEXT_FLAG flags) : this()
{
cFlags = flags;
}
private WOW64_CONTEXT_FLAG cFlags;
public int dr0;
public int dr1;
public int dr2;
public int dr3;
public int dr6;
public int dr7;
public FLOATING_SAVE_AREA floatSave;
public int segGs;
public int segFs;
public int segEs;
public int segDs;
public int edi;
public int esi;
public int ebx;
public int edx;
public int ecx;
public int eax;
public int ebp;
public int eip;
public int segCs;
public int eFlags;
public int esp;
public int segSs;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXIMUM_SUPPORTED_EXTENSION)]
public byte[] extendedRegisters;
}
[StructLayout(LayoutKind.Sequential)]
public struct FLOATING_SAVE_AREA
{
public int controlWord;
public int statusWord;
public int tagWord;
public int errorOffset;
public int errorSelector;
public int dataOffset;
public int dataSelector;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SIZE_OF_80387_REGISTERS)]
public byte[] registerArea;
public int spare0;
}
[StructLayout(LayoutKind.Sequential, Pack = 16)]
public struct M128A
{
public M128A(ulong _low, long _high)
{
low = _low;
high = _high;
}
public ulong low;
public long high;
}
[StructLayout(LayoutKind.Sequential)]
public struct NEON128
{
public NEON128(ulong _low, long _high)
{
low = _low;
high = _high;
}
public ulong low;
public long high;
}
[StructLayout(LayoutKind.Explicit, Pack = 16)]
public struct XSAVE_FORMAT
{
[FieldOffset(0)]
public short controlWord;
[FieldOffset(2)]
public short statusWord;
[FieldOffset(4)]
public byte tagWord;
[FieldOffset(5)]
private byte reserved0;
[FieldOffset(6)]
public short errorOpcode;
[FieldOffset(8)]
public int errorOffset;
[FieldOffset(12)]
public short errorSelector;
[FieldOffset(14)]
private ushort reserved1;
[FieldOffset(16)]
public int dataOffset;
[FieldOffset(20)]
public short dataSelector;
[FieldOffset(22)]
private ushort reserved2;
[FieldOffset(24)]
public int mxCsr;
[FieldOffset(28)]
public int mxCsrMask;
[FieldOffset(32)]
public M128A floatRegister0;
[FieldOffset(48)]
public M128A floatRegister1;
[FieldOffset(64)]
public M128A floatRegister2;
[FieldOffset(80)]
public M128A floatRegister3;
[FieldOffset(96)]
public M128A floatRegister4;
[FieldOffset(112)]
public M128A floatRegister5;
[FieldOffset(128)]
public M128A floatRegister6;
[FieldOffset(144)]
public M128A floatRegister7;
[FieldOffset(160)]
public M128A xmmRegister0;
[FieldOffset(176)]
public M128A xmmRegister1;
[FieldOffset(192)]
public M128A xmmRegister2;
[FieldOffset(208)]
public M128A xmmRegister3;
[FieldOffset(224)]
public M128A xmmRegister4;
[FieldOffset(240)]
public M128A xmmRegister5;
[FieldOffset(256)]
public M128A xmmRegister6;
[FieldOffset(272)]
public M128A xmmRegister7;
[FieldOffset(288)]
public M128A xmmRegister8;
[FieldOffset(304)]
public M128A xmmRegister9;
[FieldOffset(320)]
public M128A xmmRegister10;
[FieldOffset(336)]
public M128A xmmRegister11;
[FieldOffset(352)]
public M128A xmmRegister12;
[FieldOffset(368)]
public M128A xmmRegister13;
[FieldOffset(384)]
public M128A xmmRegister14;
[FieldOffset(400)]
public M128A xmmRegister15;
[FieldOffset(416)]
private M128A Reserved3_0;
[FieldOffset(432)]
private M128A Reserved3_1;
[FieldOffset(448)]
private M128A Reserved3_2;
[FieldOffset(464)]
private M128A Reserved3_3;
[FieldOffset(480)]
private M128A Reserved3_4;
[FieldOffset(496)]
private M128A Reserved3_5;
}
如有任何帮助,我们将不胜感激。请注意,所有标志枚举都是 uint。我很确定一个或多个偏移量是错误的但不确定在哪里(已经检查了它们 5 次)
这似乎对我有用(在 Windows 10 64 上的 x86 和 x64 中测试)=>
// Check sizes
// 716
int nSize = Marshal.SizeOf(typeof(CONTEXT));
// 1232
int nSize64 = Marshal.SizeOf(typeof(CONTEXT64));
CONTEXT ctx = new CONTEXT();
// CONTEXT64 ctx = new CONTEXT64();
ctx.ContextFlags = CONTEXT_ALL;
bool bRet = GetThreadContext(GetCurrentThread(), ref ctx);
与(来自 SDK headers 和 WinDbg):
[StructLayout(LayoutKind.Explicit, Pack = 16)]
public struct CONTEXT64
{
[FieldOffset(0x000)]
public ulong P1Home;
[FieldOffset(0x008)]
public ulong P2Home;
[FieldOffset(0x010)]
public ulong P3Home;
[FieldOffset(0x018)]
public ulong P4Home;
[FieldOffset(0x020)]
public ulong P5Home;
[FieldOffset(0x028)]
public ulong P6Home;
[FieldOffset(0x030)]
public int ContextFlags;
[FieldOffset(0x034)]
public int MxCsr;
[FieldOffset(0x038)]
public ushort SegCs;
[FieldOffset(0x03a)]
public ushort SegDs;
[FieldOffset(0x03c)]
public ushort SegEs;
[FieldOffset(0x03e)]
public ushort SegFs;
[FieldOffset(0x040)]
public ushort SegGs;
[FieldOffset(0x042)]
public ushort SegSs;
[FieldOffset(0x044)]
public int EFlags;
[FieldOffset(0x048)]
public ulong Dr0;
[FieldOffset(0x050)]
public ulong Dr1;
[FieldOffset(0x058)]
public ulong Dr2;
[FieldOffset(0x060)]
public ulong Dr3;
[FieldOffset(0x068)]
public ulong Dr6;
[FieldOffset(0x070)]
public ulong Dr7;
[FieldOffset(0x078)]
public ulong Rax;
[FieldOffset(0x080)]
public ulong Rcx;
[FieldOffset(0x088)]
public ulong Rdx;
[FieldOffset(0x090)]
public ulong Rbx;
[FieldOffset(0x098)]
public ulong Rsp;
[FieldOffset(0x0a0)]
public ulong Rbp;
[FieldOffset(0x0a8)]
public ulong Rsi;
[FieldOffset(0x0b0)]
public ulong Rdi;
[FieldOffset(0x0b8)]
public ulong R8;
[FieldOffset(0x0c0)]
public ulong R9;
[FieldOffset(0x0c8)]
public ulong R10;
[FieldOffset(0x0d0)]
public ulong R11;
[FieldOffset(0x0d8)]
public ulong R12;
[FieldOffset(0x0e0)]
public ulong R13;
[FieldOffset(0x0e8)]
public ulong R14;
[FieldOffset(0x0f0)]
public ulong R15;
[FieldOffset(0x0f8)]
public ulong Rip;
[FieldOffset(0x100)]
//[MarshalAs(UnmanagedType.Struct, SizeConst = 512)]
public XMM_SAVE_AREA32 FltSave;
[FieldOffset(0x300)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)]
public M128A[] VectorRegister;
[FieldOffset(0x4a0)]
public ulong VectorControl;
[FieldOffset(0x4a8)]
public ulong DebugControl;
[FieldOffset(0x4b0)]
public ulong LastBranchToRip;
[FieldOffset(0x4b8)]
public ulong LastBranchFromRip;
[FieldOffset(0x4c0)]
public ulong LastExceptionToRip;
[FieldOffset(0x4c8)]
public ulong LastExceptionFromRip;
}
[StructLayout(LayoutKind.Sequential, Pack = 16)]
public struct XMM_SAVE_AREA32
{
public ushort ControlWord;
public ushort StatusWord;
public char TagWord;
public char 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 MxCsrMask;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public M128A[] FloatRegisters;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public M128A[] XmmRegisters;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
public char[] Reserved4;
}
[StructLayout(LayoutKind.Sequential)]
public struct FLOATING_SAVE_AREA
{
public int ControlWord;
public int StatusWord;
public int TagWord;
public int ErrorOffset;
public int ErrorSelector;
public int DataOffset;
public int DataSelector;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SIZE_OF_80387_REGISTERS)]
public byte[] RegisterArea;
public int Spare0;
}
public const int MAXIMUM_SUPPORTED_EXTENSION = 512;
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct CONTEXT
{
public int ContextFlags;
public int Dr0;
public int Dr1;
public int Dr2;
public int Dr3;
public int Dr6;
public int Dr7;
public FLOATING_SAVE_AREA FloatSave;
public int SegGs;
public int SegFs;
public int SegEs;
public int SegDs;
public int Edi;
public int Esi;
public int Ebx;
public int Edx;
public int Ecx;
public int Eax;
public int Ebp;
public int Eip;
public int SegCs; // MUST BE SANITIZED
public int EFlags; // MUST BE SANITIZED
public int Esp;
public int SegSs;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXIMUM_SUPPORTED_EXTENSION)]
public byte[] ExtendedRegisters;
}
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr GetCurrentThread();
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT lpContext);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT64 lpContext);
public const int SIZE_OF_80387_REGISTERS = 80;
public const int CONTEXT_i386 = 0x00010000; // this assumes that i386 and
public const int CONTEXT_i486 = 0x00010000; // i486 have identical context records
public const int CONTEXT_CONTROL = (CONTEXT_i386 | 0x00000001); // SS:SP, CS:IP, FLAGS, BP
public const int CONTEXT_INTEGER = (CONTEXT_i386 | 0x00000002); // AX, BX, CX, DX, SI, DI
public const int CONTEXT_SEGMENTS = (CONTEXT_i386 | 0x00000004); // DS, ES, FS, GS
public const int CONTEXT_FLOATING_POINT = (CONTEXT_i386 | 0x00000008); // 387 state
public const int CONTEXT_DEBUG_REGISTERS = (CONTEXT_i386 | 0x00000010); // DB 0-3,6,7
public const int CONTEXT_EXTENDED_REGISTERS = (CONTEXT_i386 | 0x00000020); // cpu specific extensions
public const int CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS);
public const int CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS);
public const int CONTEXT_XSTATE = (CONTEXT_i386 | 0x00000040);
public const int CONTEXT_EXCEPTION_ACTIVE = 0x08000000;
public const int CONTEXT_SERVICE_ACTIVE = 0x10000000;
public const int CONTEXT_EXCEPTION_REQUEST = 0x40000000;
public const int CONTEXT_EXCEPTION_REPORTING = unchecked((int)0x80000000);
很抱歉发布这个,但是,我正在努力实施 GetThreadContext
和 SetThreadContext
因为结构是错误的,它们还导致库抛出 ReflectionTypeLoadException
.
这是我对结构的实现:
[StructLayout(LayoutKind.Sequential)]
public struct THREAD_CONTEXT_IA32
{
public THREAD_CONTEXT_IA32(IA32_CONTEXT_FLAG flags) : this()
{
cFlags = flags;
}
private IA32_CONTEXT_FLAG cFlags;
public int dr0;
public int dr1;
public int dr2;
public int dr3;
public int dr6;
public int dr7;
public FLOATING_SAVE_AREA floatSave;
public int segGs;
public int segFs;
public int segEs;
public int segDs;
public int edi;
public int esi;
public int ebx;
public int edx;
public int ecx;
public int eax;
public int ebp;
public int eip;
public int segCs;
public int eFlags;
public int esp;
public int segSs;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXIMUM_SUPPORTED_EXTENSION)]
public byte[] extendedRegisters;
}
[StructLayout(LayoutKind.Explicit, Pack = 16)]
public struct THREAD_CONTEXT_AMD64
{
public THREAD_CONTEXT_AMD64(AMD64_CONTEXT_FLAG flags) : this()
{
cFlags = flags;
}
[FieldOffset(0)]
public long p1Home;
[FieldOffset(8)]
public long p2Home;
[FieldOffset(16)]
public long p3Home;
[FieldOffset(24)]
public long p4Home;
[FieldOffset(32)]
public long p5Home;
[FieldOffset(40)]
public long p6Home;
[FieldOffset(48)]
private AMD64_CONTEXT_FLAG cFlags;
[FieldOffset(50)]
public int mxCsr;
[FieldOffset(54)]
public short segCs;
[FieldOffset(56)]
public short segDs;
[FieldOffset(58)]
public short segEs;
[FieldOffset(60)]
public short segFs;
[FieldOffset(62)]
public short segGs;
[FieldOffset(64)]
public short segSs;
[FieldOffset(66)]
public int eFlags;
[FieldOffset(70)]
public long dr0;
[FieldOffset(78)]
public long dr1;
[FieldOffset(86)]
public long dr2;
[FieldOffset(94)]
public long dr3;
[FieldOffset(102)]
public long dr6;
[FieldOffset(110)]
public long dr7;
[FieldOffset(118)]
public long rax;
[FieldOffset(126)]
public long rcx;
[FieldOffset(132)]
public long rdx;
[FieldOffset(140)]
public long rbx;
[FieldOffset(148)]
public long rsp;
[FieldOffset(156)]
public long rbp;
[FieldOffset(174)]
public long rsi;
[FieldOffset(182)]
public long rdi;
[FieldOffset(190)]
public long r8;
[FieldOffset(198)]
public long r9;
[FieldOffset(206)]
public long r10;
[FieldOffset(214)]
public long r11;
[FieldOffset(222)]
public long r12;
[FieldOffset(230)]
public long r13;
[FieldOffset(238)]
public long r14;
[FieldOffset(246)]
public long r15;
[FieldOffset(252)]
public long rip;
[FieldOffset(260)]
public XSAVE_FORMAT fltSave;
[FieldOffset(772)]
public M128A header0;
[FieldOffset(788)]
public M128A header1;
[FieldOffset(804)]
public M128A legacy0;
[FieldOffset(820)]
public M128A legacy1;
[FieldOffset(836)]
public M128A legacy2;
[FieldOffset(852)]
public M128A legacy3;
[FieldOffset(868)]
public M128A legacy4;
[FieldOffset(884)]
public M128A legacy5;
[FieldOffset(900)]
public M128A legacy6;
[FieldOffset(916)]
public M128A legacy7;
[FieldOffset(932)]
public M128A xmm0;
[FieldOffset(948)]
public M128A xmm1;
[FieldOffset(964)]
public M128A xmm2;
[FieldOffset(980)]
public M128A xmm3;
[FieldOffset(996)]
public M128A xmm4;
[FieldOffset(1012)]
public M128A xmm5;
[FieldOffset(1028)]
public M128A xmm6;
[FieldOffset(1044)]
public M128A xmm7;
[FieldOffset(1060)]
public M128A xmm8;
[FieldOffset(1076)]
public M128A xmm9;
[FieldOffset(1092)]
public M128A xmm10;
[FieldOffset(1108)]
public M128A xmm11;
[FieldOffset(1124)]
public M128A xmm12;
[FieldOffset(1140)]
public M128A xmm13;
[FieldOffset(1156)]
public M128A xmm14;
[FieldOffset(1172)]
public M128A xmm15;
[FieldOffset(1188)]
public M128A vectorRegister0;
[FieldOffset(1204)]
public M128A vectorRegister1;
[FieldOffset(1220)]
public M128A vectorRegister2;
[FieldOffset(1236)]
public M128A vectorRegister3;
[FieldOffset(1252)]
public M128A vectorRegister4;
[FieldOffset(1268)]
public M128A vectorRegister5;
[FieldOffset(1284)]
public M128A vectorRegister6;
[FieldOffset(1300)]
public M128A vectorRegister7;
[FieldOffset(1316)]
public M128A vectorRegister8;
[FieldOffset(1332)]
public M128A vectorRegister9;
[FieldOffset(1348)]
public M128A vectorRegister10;
[FieldOffset(1364)]
public M128A vectorRegister11;
[FieldOffset(1380)]
public M128A vectorRegister12;
[FieldOffset(1396)]
public M128A vectorRegister13;
[FieldOffset(1412)]
public M128A vectorRegister14;
[FieldOffset(1428)]
public M128A vectorRegister15;
[FieldOffset(1444)]
public M128A vectorRegister16;
[FieldOffset(1460)]
public M128A vectorRegister17;
[FieldOffset(1476)]
public M128A vectorRegister18;
[FieldOffset(1492)]
public M128A vectorRegister19;
[FieldOffset(1508)]
public M128A vectorRegister20;
[FieldOffset(1524)]
public M128A vectorRegister21;
[FieldOffset(1540)]
public M128A vectorRegister22;
[FieldOffset(1556)]
public M128A vectorRegister23;
[FieldOffset(1572)]
public M128A vectorRegister24;
[FieldOffset(1588)]
public M128A vectorRegister25;
[FieldOffset(1604)]
public long vectorControl;
[FieldOffset(1612)]
public long debugControl;
[FieldOffset(1620)]
public long lastBranchToRip;
[FieldOffset(1628)]
public long lastBranchFromRip;
[FieldOffset(1636)]
public long lastExceptionToRip;
[FieldOffset(1644)]
public long lastExceptionFromRip;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct THREAD_CONTEXT_ARM
{
public THREAD_CONTEXT_ARM(ARM_CONTEXT_FLAG flags) : this()
{
cFlags = flags;
}
private ARM_CONTEXT_FLAG cFlags;
public int r0;
public int r1;
public int r2;
public int r3;
public int r4;
public int r5;
public int r6;
public int r7;
public int r8;
public int r9;
public int r10;
public int r11;
public int r12;
public int sp;
public int lr;
public int pc;
public int cpsr;
public int fpscr;
public int padding;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public NEON128[] neon;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM_MAX_BREAKPOINTS)]
public int[] bvr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM_MAX_BREAKPOINTS)]
public int[] bcr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM_MAX_WATCHPOINTS)]
public int[] wvr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM_MAX_WATCHPOINTS)]
public int[] wcr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public int[] padding2;
}
[StructLayout(LayoutKind.Sequential, Pack = 16)]
public struct THREAD_CONTEXT_ARM64
{
public THREAD_CONTEXT_ARM64(ARM64_CONTEXT_FLAG flags) : this()
{
cFlags = flags;
}
private ARM64_CONTEXT_FLAG cFlags;
public int cpsr;
public long x0;
public long x1;
public long x2;
public long x3;
public long x4;
public long x5;
public long x6;
public long x7;
public long x8;
public long x9;
public long x10;
public long x11;
public long x12;
public long x13;
public long x14;
public long x15;
public long x16;
public long x17;
public long x18;
public long x19;
public long x20;
public long x21;
public long x22;
public long x23;
public long x24;
public long x25;
public long x26;
public long x27;
public long x28;
public long fp;
public long lr;
public long sp;
public long pc;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public NEON128[] neon;
public int fpcr;
public int fpsr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM64_MAX_BREAKPOINTS)]
public int[] bcr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM64_MAX_BREAKPOINTS)]
public long[] bvr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM64_MAX_WATCHPOINTS)]
public int[] wcr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ARM64_MAX_WATCHPOINTS)]
public long[] wvr;
}
[StructLayout(LayoutKind.Sequential)]
public struct THREAD_CONTEXT_WOW64
{
public THREAD_CONTEXT_WOW64(WOW64_CONTEXT_FLAG flags) : this()
{
cFlags = flags;
}
private WOW64_CONTEXT_FLAG cFlags;
public int dr0;
public int dr1;
public int dr2;
public int dr3;
public int dr6;
public int dr7;
public FLOATING_SAVE_AREA floatSave;
public int segGs;
public int segFs;
public int segEs;
public int segDs;
public int edi;
public int esi;
public int ebx;
public int edx;
public int ecx;
public int eax;
public int ebp;
public int eip;
public int segCs;
public int eFlags;
public int esp;
public int segSs;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXIMUM_SUPPORTED_EXTENSION)]
public byte[] extendedRegisters;
}
[StructLayout(LayoutKind.Sequential)]
public struct FLOATING_SAVE_AREA
{
public int controlWord;
public int statusWord;
public int tagWord;
public int errorOffset;
public int errorSelector;
public int dataOffset;
public int dataSelector;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SIZE_OF_80387_REGISTERS)]
public byte[] registerArea;
public int spare0;
}
[StructLayout(LayoutKind.Sequential, Pack = 16)]
public struct M128A
{
public M128A(ulong _low, long _high)
{
low = _low;
high = _high;
}
public ulong low;
public long high;
}
[StructLayout(LayoutKind.Sequential)]
public struct NEON128
{
public NEON128(ulong _low, long _high)
{
low = _low;
high = _high;
}
public ulong low;
public long high;
}
[StructLayout(LayoutKind.Explicit, Pack = 16)]
public struct XSAVE_FORMAT
{
[FieldOffset(0)]
public short controlWord;
[FieldOffset(2)]
public short statusWord;
[FieldOffset(4)]
public byte tagWord;
[FieldOffset(5)]
private byte reserved0;
[FieldOffset(6)]
public short errorOpcode;
[FieldOffset(8)]
public int errorOffset;
[FieldOffset(12)]
public short errorSelector;
[FieldOffset(14)]
private ushort reserved1;
[FieldOffset(16)]
public int dataOffset;
[FieldOffset(20)]
public short dataSelector;
[FieldOffset(22)]
private ushort reserved2;
[FieldOffset(24)]
public int mxCsr;
[FieldOffset(28)]
public int mxCsrMask;
[FieldOffset(32)]
public M128A floatRegister0;
[FieldOffset(48)]
public M128A floatRegister1;
[FieldOffset(64)]
public M128A floatRegister2;
[FieldOffset(80)]
public M128A floatRegister3;
[FieldOffset(96)]
public M128A floatRegister4;
[FieldOffset(112)]
public M128A floatRegister5;
[FieldOffset(128)]
public M128A floatRegister6;
[FieldOffset(144)]
public M128A floatRegister7;
[FieldOffset(160)]
public M128A xmmRegister0;
[FieldOffset(176)]
public M128A xmmRegister1;
[FieldOffset(192)]
public M128A xmmRegister2;
[FieldOffset(208)]
public M128A xmmRegister3;
[FieldOffset(224)]
public M128A xmmRegister4;
[FieldOffset(240)]
public M128A xmmRegister5;
[FieldOffset(256)]
public M128A xmmRegister6;
[FieldOffset(272)]
public M128A xmmRegister7;
[FieldOffset(288)]
public M128A xmmRegister8;
[FieldOffset(304)]
public M128A xmmRegister9;
[FieldOffset(320)]
public M128A xmmRegister10;
[FieldOffset(336)]
public M128A xmmRegister11;
[FieldOffset(352)]
public M128A xmmRegister12;
[FieldOffset(368)]
public M128A xmmRegister13;
[FieldOffset(384)]
public M128A xmmRegister14;
[FieldOffset(400)]
public M128A xmmRegister15;
[FieldOffset(416)]
private M128A Reserved3_0;
[FieldOffset(432)]
private M128A Reserved3_1;
[FieldOffset(448)]
private M128A Reserved3_2;
[FieldOffset(464)]
private M128A Reserved3_3;
[FieldOffset(480)]
private M128A Reserved3_4;
[FieldOffset(496)]
private M128A Reserved3_5;
}
如有任何帮助,我们将不胜感激。请注意,所有标志枚举都是 uint。我很确定一个或多个偏移量是错误的但不确定在哪里(已经检查了它们 5 次)
这似乎对我有用(在 Windows 10 64 上的 x86 和 x64 中测试)=>
// Check sizes
// 716
int nSize = Marshal.SizeOf(typeof(CONTEXT));
// 1232
int nSize64 = Marshal.SizeOf(typeof(CONTEXT64));
CONTEXT ctx = new CONTEXT();
// CONTEXT64 ctx = new CONTEXT64();
ctx.ContextFlags = CONTEXT_ALL;
bool bRet = GetThreadContext(GetCurrentThread(), ref ctx);
与(来自 SDK headers 和 WinDbg):
[StructLayout(LayoutKind.Explicit, Pack = 16)]
public struct CONTEXT64
{
[FieldOffset(0x000)]
public ulong P1Home;
[FieldOffset(0x008)]
public ulong P2Home;
[FieldOffset(0x010)]
public ulong P3Home;
[FieldOffset(0x018)]
public ulong P4Home;
[FieldOffset(0x020)]
public ulong P5Home;
[FieldOffset(0x028)]
public ulong P6Home;
[FieldOffset(0x030)]
public int ContextFlags;
[FieldOffset(0x034)]
public int MxCsr;
[FieldOffset(0x038)]
public ushort SegCs;
[FieldOffset(0x03a)]
public ushort SegDs;
[FieldOffset(0x03c)]
public ushort SegEs;
[FieldOffset(0x03e)]
public ushort SegFs;
[FieldOffset(0x040)]
public ushort SegGs;
[FieldOffset(0x042)]
public ushort SegSs;
[FieldOffset(0x044)]
public int EFlags;
[FieldOffset(0x048)]
public ulong Dr0;
[FieldOffset(0x050)]
public ulong Dr1;
[FieldOffset(0x058)]
public ulong Dr2;
[FieldOffset(0x060)]
public ulong Dr3;
[FieldOffset(0x068)]
public ulong Dr6;
[FieldOffset(0x070)]
public ulong Dr7;
[FieldOffset(0x078)]
public ulong Rax;
[FieldOffset(0x080)]
public ulong Rcx;
[FieldOffset(0x088)]
public ulong Rdx;
[FieldOffset(0x090)]
public ulong Rbx;
[FieldOffset(0x098)]
public ulong Rsp;
[FieldOffset(0x0a0)]
public ulong Rbp;
[FieldOffset(0x0a8)]
public ulong Rsi;
[FieldOffset(0x0b0)]
public ulong Rdi;
[FieldOffset(0x0b8)]
public ulong R8;
[FieldOffset(0x0c0)]
public ulong R9;
[FieldOffset(0x0c8)]
public ulong R10;
[FieldOffset(0x0d0)]
public ulong R11;
[FieldOffset(0x0d8)]
public ulong R12;
[FieldOffset(0x0e0)]
public ulong R13;
[FieldOffset(0x0e8)]
public ulong R14;
[FieldOffset(0x0f0)]
public ulong R15;
[FieldOffset(0x0f8)]
public ulong Rip;
[FieldOffset(0x100)]
//[MarshalAs(UnmanagedType.Struct, SizeConst = 512)]
public XMM_SAVE_AREA32 FltSave;
[FieldOffset(0x300)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)]
public M128A[] VectorRegister;
[FieldOffset(0x4a0)]
public ulong VectorControl;
[FieldOffset(0x4a8)]
public ulong DebugControl;
[FieldOffset(0x4b0)]
public ulong LastBranchToRip;
[FieldOffset(0x4b8)]
public ulong LastBranchFromRip;
[FieldOffset(0x4c0)]
public ulong LastExceptionToRip;
[FieldOffset(0x4c8)]
public ulong LastExceptionFromRip;
}
[StructLayout(LayoutKind.Sequential, Pack = 16)]
public struct XMM_SAVE_AREA32
{
public ushort ControlWord;
public ushort StatusWord;
public char TagWord;
public char 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 MxCsrMask;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public M128A[] FloatRegisters;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public M128A[] XmmRegisters;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
public char[] Reserved4;
}
[StructLayout(LayoutKind.Sequential)]
public struct FLOATING_SAVE_AREA
{
public int ControlWord;
public int StatusWord;
public int TagWord;
public int ErrorOffset;
public int ErrorSelector;
public int DataOffset;
public int DataSelector;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SIZE_OF_80387_REGISTERS)]
public byte[] RegisterArea;
public int Spare0;
}
public const int MAXIMUM_SUPPORTED_EXTENSION = 512;
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct CONTEXT
{
public int ContextFlags;
public int Dr0;
public int Dr1;
public int Dr2;
public int Dr3;
public int Dr6;
public int Dr7;
public FLOATING_SAVE_AREA FloatSave;
public int SegGs;
public int SegFs;
public int SegEs;
public int SegDs;
public int Edi;
public int Esi;
public int Ebx;
public int Edx;
public int Ecx;
public int Eax;
public int Ebp;
public int Eip;
public int SegCs; // MUST BE SANITIZED
public int EFlags; // MUST BE SANITIZED
public int Esp;
public int SegSs;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXIMUM_SUPPORTED_EXTENSION)]
public byte[] ExtendedRegisters;
}
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr GetCurrentThread();
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT lpContext);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT64 lpContext);
public const int SIZE_OF_80387_REGISTERS = 80;
public const int CONTEXT_i386 = 0x00010000; // this assumes that i386 and
public const int CONTEXT_i486 = 0x00010000; // i486 have identical context records
public const int CONTEXT_CONTROL = (CONTEXT_i386 | 0x00000001); // SS:SP, CS:IP, FLAGS, BP
public const int CONTEXT_INTEGER = (CONTEXT_i386 | 0x00000002); // AX, BX, CX, DX, SI, DI
public const int CONTEXT_SEGMENTS = (CONTEXT_i386 | 0x00000004); // DS, ES, FS, GS
public const int CONTEXT_FLOATING_POINT = (CONTEXT_i386 | 0x00000008); // 387 state
public const int CONTEXT_DEBUG_REGISTERS = (CONTEXT_i386 | 0x00000010); // DB 0-3,6,7
public const int CONTEXT_EXTENDED_REGISTERS = (CONTEXT_i386 | 0x00000020); // cpu specific extensions
public const int CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS);
public const int CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS);
public const int CONTEXT_XSTATE = (CONTEXT_i386 | 0x00000040);
public const int CONTEXT_EXCEPTION_ACTIVE = 0x08000000;
public const int CONTEXT_SERVICE_ACTIVE = 0x10000000;
public const int CONTEXT_EXCEPTION_REQUEST = 0x40000000;
public const int CONTEXT_EXCEPTION_REPORTING = unchecked((int)0x80000000);