2016-06-06 12 views
1

Ich versuche CONTEXT von x64 Process mit IDebugAdvanced ClrMd-Schnittstelle zu erhalten. Aber ich bekomme ein paar Kauderwelsch-Werte drin. Beispiel:Deklarieren von CONTEXT struct für PInvoke (Windows x64)

{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} 

Kann jemand bitte sagen Sie mir, wenn meine C# Erklärung richtig ist?

C++ winnt.h Erklärung:

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; 

Meine Managed Struktur:

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; 
    }; 

Dank im Voraus:

+1

Debuggen. Beginnen Sie mit dem Vergleich der Größe der Strukturen (die native Version mit der verwalteten Version). Dann gräbt man tiefer, indem man Offsets vergleicht. Das ist Interop 101. –

+2

WORD ist ein 16-Bit-Wert, also brauchen Sie 'mit WORD = System.UInt16;' –

+0

Danke, ich werde es versuchen. –

Antwort

5

First off, WORD ist ein 16-Bit-Typ (unsigned short), kein unsigned char.

Zweitens, ein wenig C++ Scratch-Konsole-Anwendung kann Ihnen das gesamte Strukturlayout geben, mit den Größen aller Datentypen verwendet.

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 

Die oben wurde in der main() Funktion mit einer einfachen C++ Konsolenanwendung mit dem folgenden generiert:

#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 

Aus diesen Informationen haben Sie keine Probleme haben, sollten eine Struktur in verwaltetem Code erstellt, die kompatibel ist.

+0

Vielen Dank! –

+0

Kein Problem. Für das Marshallen von Strukturen ist es fast immer am einfachsten, eine schnelle C++ - Konsolenanwendung auszugeben, die die Felder und Offsets ausgibt. Und Sie brauchen wirklich nicht mehr C++ zu wissen als das, was oben steht. (ie- 'sizeof',' offsetof', und das 'iostream'-Zeug, um es auf die Konsole zu drucken) Das Makro speichert nur die Komplexität beim Kopieren/Einfügen. – theB

+0

Das ist wirklich hilfreicher Tipp :)! Danke noch einmal –

0

Ich habe kürzlich entdeckt, dass Sie WinDbg dt Befehl, zum Beispiel verwenden, wenn Sie _RTL_CRITICAL_SECTION Struktur Layout erhalten möchten, können Sie einfach eingeben:

0:000> dt ntdll!_RTL_CRITICAL_SECTION 

Ausgang:

+0x000 DebugInfo  : Ptr32 _RTL_CRITICAL_SECTION_DEBUG 
    +0x004 LockCount  : Int4B 
    +0x008 RecursionCount : Int4B 
    +0x00c OwningThread  : Ptr32 Void 
    +0x010 LockSemaphore : Ptr32 Void 
    +0x014 SpinCount  : Uint4B