我正在尝试使用 IDebugAdvanced ClrMd 接口(interface)从 x64 进程获取 CONTEXT。 但是我在其中得到了一些乱码。 示例:
{WinNativeApi.WinNT.CONTEXT_AMD64}
ContextFlags: 1048607
DebugControl: 0
Dr0: 0
Dr1: 0
Dr2: 0
Dr3: 0
Dr6: 0
Dr7: 0
EFlags: 2818091
LastBranchFromRip: 0
LastBranchToRip: 0
LastExceptionFromRip: 0
LastExceptionToRip: 0
MxCsr: 8096
P1Home: 1035103895583
P2Home: 2239468740072
P3Home: 2237682024510
P4Home: 1039055965440
P5Home: 24488718114619459
P6Home: 31244151918821481
R10: 2747550605264
R11: 2747522160368
R12: 1
R13: 512
R14: 922054817240
R15: 4294901760
R8: 0
R9: 2747522160368
Rax: 2747550600488
Rbp: 922054817584
Rbx: 0
Rcx: 2747550600488
Rdi: 696
Rdx: 2747550600488
Rip: 140706165903700
Rsi: 20000
Rsp: 922054817192
SegCs: 51
SegDs: 0
SegEs: 43
SegFs: 0
SegGs: 43
SegSs: 0
VectorControl: 0
VectorRegister: 0x0000000000000000
dummyUnion: {WinNativeApi.WinNT.DUMMYUNIONNAME}
谁能告诉我我的 C# 声明是否正确?
C++ WinNt.h 声明:
typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
//
// Register parameter home addresses.
//
// N.B. These fields are for convience - they could be used to extend the
// context record in the future.
//
DWORD64 P1Home;
DWORD64 P2Home;
DWORD64 P3Home;
DWORD64 P4Home;
DWORD64 P5Home;
DWORD64 P6Home;
//
// Control flags.
//
DWORD ContextFlags;
DWORD MxCsr;
//
// Segment Registers and processor flags.
//
WORD SegCs;
WORD SegDs;
WORD SegEs;
WORD SegFs;
WORD SegGs;
WORD SegSs;
DWORD EFlags;
//
// Debug registers
//
DWORD64 Dr0;
DWORD64 Dr1;
DWORD64 Dr2;
DWORD64 Dr3;
DWORD64 Dr6;
DWORD64 Dr7;
//
// Integer registers.
//
DWORD64 Rax;
DWORD64 Rcx;
DWORD64 Rdx;
DWORD64 Rbx;
DWORD64 Rsp;
DWORD64 Rbp;
DWORD64 Rsi;
DWORD64 Rdi;
DWORD64 R8;
DWORD64 R9;
DWORD64 R10;
DWORD64 R11;
DWORD64 R12;
DWORD64 R13;
DWORD64 R14;
DWORD64 R15;
//
// Program counter.
//
DWORD64 Rip;
//
// Floating point state.
//
union {
XMM_SAVE_AREA32 FltSave;
struct {
M128A Header[2];
M128A Legacy[8];
M128A Xmm0;
M128A Xmm1;
M128A Xmm2;
M128A Xmm3;
M128A Xmm4;
M128A Xmm5;
M128A Xmm6;
M128A Xmm7;
M128A Xmm8;
M128A Xmm9;
M128A Xmm10;
M128A Xmm11;
M128A Xmm12;
M128A Xmm13;
M128A Xmm14;
M128A Xmm15;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;
//
// Vector registers.
//
M128A VectorRegister[26];
DWORD64 VectorControl;
//
// Special debug control registers.
//
DWORD64 DebugControl;
DWORD64 LastBranchToRip;
DWORD64 LastBranchFromRip;
DWORD64 LastExceptionToRip;
DWORD64 LastExceptionFromRip;
} CONTEXT, *PCONTEXT;
我的托管结构:
using DWORD64 = System.UInt64;
using DWORD = System.Int32;
using WORD = System.SByte;
using ULONGLONG = System.UInt64;
using LONGLONG = System.Int64;
[StructLayout(LayoutKind.Sequential, Pack = 16)]
public unsafe struct CONTEXT_AMD64
{
//
// Register parameter home addresses.
//
// N.B. These fields are for convience - they could be used to extend the
// context record in the future.
//
public DWORD64 P1Home;
public DWORD64 P2Home;
public DWORD64 P3Home;
public DWORD64 P4Home;
public DWORD64 P5Home;
public DWORD64 P6Home;
//
// Control flags.
//
public DWORD ContextFlags;
public DWORD MxCsr;
//
// Segment Registers and processor flags.
//
public WORD SegCs;
public WORD SegDs;
public WORD SegEs;
public WORD SegFs;
public WORD SegGs;
public WORD SegSs;
public DWORD EFlags;
//
// Debug registers
//
public DWORD64 Dr0;
public DWORD64 Dr1;
public DWORD64 Dr2;
public DWORD64 Dr3;
public DWORD64 Dr6;
public DWORD64 Dr7;
//
// Integer registers.
//
public DWORD64 Rax;
public DWORD64 Rcx;
public DWORD64 Rdx;
public DWORD64 Rbx;
public DWORD64 Rsp;
public DWORD64 Rbp;
public DWORD64 Rsi;
public DWORD64 Rdi;
public DWORD64 R8;
public DWORD64 R9;
public DWORD64 R10;
public DWORD64 R11;
public DWORD64 R12;
public DWORD64 R13;
public DWORD64 R14;
public DWORD64 R15;
//
// Program counter.
//
public DWORD64 Rip;
//
// Floating point state.
//
public DUMMYUNIONNAME dummyUnion;
//
// Vector registers.
//
M128A* VectorRegister;
public DWORD64 VectorControl;
//
// Special debug control registers.
//
public DWORD64 DebugControl;
public DWORD64 LastBranchToRip;
public DWORD64 LastBranchFromRip;
public DWORD64 LastExceptionToRip;
public DWORD64 LastExceptionFromRip;
}
struct XMM_SAVE_AREA32
{
}
public unsafe struct DUMMY
{
M128A* Header;
M128A* Legacy;
M128A Xmm0;
M128A Xmm1;
M128A Xmm2;
M128A Xmm3;
M128A Xmm4;
M128A Xmm5;
M128A Xmm6;
M128A Xmm7;
M128A Xmm8;
M128A Xmm9;
M128A Xmm10;
M128A Xmm11;
M128A Xmm12;
M128A Xmm13;
M128A Xmm14;
M128A Xmm15;
}
[StructLayout(LayoutKind.Explicit)]
public struct DUMMYUNIONNAME
{
[FieldOffset(0)]
XMM_SAVE_AREA32 FltSave;
[FieldOffset(1)]
DUMMY Dummy;
}
struct M128A
{
ULONGLONG Low;
LONGLONG High;
};
提前致谢:
最佳答案
首先,WORD
是一个 16 位类型(unsigned short
),而不是 unsigned char
。
其次,一个小的 C++ 临时控制台应用程序可以为您提供整个结构布局,以及使用的所有数据类型的大小。
Struct CONTEXT Total Size: 1232
Data Types:
-----------
DWORD64: 8 bytes
DWORD: 4 bytes
WORD: 2 bytes
ULONGLONG: 8 bytes
LONGLONG: 8 bytes
M128A: 16 bytes
XMM_SAVE_AREA32: 512 bytes
Member Offsets:
---------------
P1Home: 0
P2Home: 8
P3Home: 16
P4Home: 24
P5Home: 32
P6Home: 40
ContextFlags: 48
MxCsr: 52
SegCs: 56
SegDs: 58
SegEs: 60
SegFs: 62
SegGs: 64
SegSs: 66
EFlags: 68
Dr0: 72
Dr1: 80
Dr2: 88
Dr3: 96
Dr6: 104
Dr7: 112
Rax: 120
Rcx: 128
Rdx: 136
Rbx: 144
Rsp: 152
Rbp: 160
Rsi: 168
Rdi: 176
R8: 184
R9: 192
R10: 200
R11: 208
R12: 216
R13: 224
R14: 232
R15: 240
Rip: 248
FltSave: 256
Header: 256
Legacy: 288
Xmm0: 416
Xmm1: 432
Xmm2: 448
Xmm3: 464
Xmm4: 480
Xmm5: 496
Xmm6: 512
Xmm7: 528
Xmm8: 544
Xmm9: 560
Xmm10: 576
Xmm11: 592
Xmm12: 608
Xmm13: 624
Xmm14: 640
Xmm15: 656
VectorRegister: 768
VectorControl: 1184
DebugControl: 1192
LastBranchToRip: 1200
LastBranchFromRip: 1208
LastExceptionToRip: 1216
LastExceptionFromRip: 1224
上面的内容是使用一个简单的 C++ 控制台应用程序生成的,在 main()
函数中包含以下内容:
#define PRINTMBR(m) cout << #m": " << offsetof(CONTEXT, m) << endl;
cout << "Struct CONTEXT Total Size: " << sizeof(CONTEXT) << endl << endl;
cout << "Data Types:" << endl;
cout << "-----------" << endl;
cout << "DWORD64: " << sizeof(DWORD64) << " bytes" << endl;
cout << "DWORD: " << sizeof(DWORD) << " bytes" << endl;
cout << "WORD: " << sizeof(WORD) << " bytes" << endl;
cout << "ULONGLONG: " << sizeof(ULONGLONG) << " bytes" << endl;
cout << "LONGLONG: " << sizeof(LONGLONG) << " bytes" << endl;
cout << "M128A: " << sizeof(M128A) << " bytes" << endl;
cout << "XMM_SAVE_AREA32: " << sizeof(XMM_SAVE_AREA32) << " bytes" << endl;
cout << endl;
cout << "Member Offsets:" << endl;
cout << "---------------" << endl;
PRINTMBR(P1Home);
PRINTMBR(P2Home);
PRINTMBR(P3Home);
PRINTMBR(P4Home);
PRINTMBR(P5Home);
PRINTMBR(P6Home);
PRINTMBR(ContextFlags);
// snipped the rest so this post isn't 50 pages long
根据这些信息,您应该可以毫无困难地在兼容的托管代码中构建结构。
关于c# - 为 PInvoke 声明 CONTEXT 结构 (Windows x64),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37656523/