GetThreadContext (kernel32)
Last changed: -186.136.223.176

.
Summary

C# Signature:

[DllImport("kernel32.dll")]
static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT lpContext);

User-Defined Types:

Here are the structures and enums used by GetThreadContext:

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 FLOATING_SAVE_AREA

{

    public uint ControlWord;
    public uint StatusWord;
    public uint TagWord;
    public uint ErrorOffset;
    public uint ErrorSelector;
    public uint DataOffset;
    public uint DataSelector;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)]
    public byte[] RegisterArea;
    public uint Cr0NpxState;

}

[StructLayout(LayoutKind.Sequential)]

public struct CONTEXT

{

    public uint ContextFlags; //set this to an appropriate value
    // Retrieved by CONTEXT_DEBUG_REGISTERS
    public uint Dr0;  
    public uint Dr1;
    public uint Dr2;
    public uint Dr3;
    public uint Dr6;
    public uint Dr7;
    // Retrieved by CONTEXT_FLOATING_POINT
    public FLOATING_SAVE_AREA FloatSave;
    // Retrieved by CONTEXT_SEGMENTS
    public uint SegGs;
    public uint SegFs;
    public uint SegEs;
    public uint SegDs;
    // Retrieved by CONTEXT_INTEGER
    public uint Edi;
    public uint Esi;
    public uint Ebx;
    public uint Edx;
    public uint Ecx;
    public uint Eax;
    // Retrieved by CONTEXT_CONTROL
    public uint Ebp;
    public uint Eip;
    public uint SegCs;
    public uint EFlags;
    public uint Esp;
    public uint SegSs;
    // Retrieved by CONTEXT_EXTENDED_REGISTERS
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
    public byte[] ExtendedRegisters;

}

Notes:

None.

Tips & Tricks:

Please add some!

Sample Code:

class Program

{

     [DllImport("kernel32.dll", SetLastError = true)]
     static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle,
     uint dwThreadId);

     [DllImport("kernel32.dll", SetLastError=true)]
     static extern bool GetThreadContext (IntPtr hThread, ref CONTEXT lpContext);

     [DllImport("kernel32.dll", SetLastError=true)]
     static extern bool CloseHandle(IntPtr hObject);

     const uint GET_CONTEXT = 0x08;

     static uint threadId;

     static void Main()
     {
     CONTEXT context = new CONTEXT();
     context.ContextFlags = (uint)CONTEXT_FLAGS.CONTEXT_CONTROL;
     Thread t = new Thread(new ThreadStart(MyMethod));
     t.Start();
     t.Suspend();
     IntPtr hThread = OpenThread(GET_CONTEXT, false, threadId);
     if (GetThreadContext(hThread, ref context))
     {
        Console.WriteLine("Ebp    : {0}", context.Ebp);
        Console.WriteLine("Eip    : {0}", context.Eip);
        Console.WriteLine("SegCs  : {0}", context.SegCs);
        Console.WriteLine("EFlags : {0}", context.EFlags);
        Console.WriteLine("Esp    : {0}", context.Esp);
        Console.WriteLine("SegSs  : {0}", context.SegSs);
     }
     else
     {
        Console.WriteLine("A problem occurred");
     }
     CloseHandle(hThread);
     t.Resume();
     Console.WriteLine("\nPress any key to end program\n");
     Console.ReadKey();
     }

     static void MyMethod()  
     {
     threadId = (uint)AppDomain.GetCurrentThreadId();
     Thread.Sleep(1000);
     }

}

Alternative Managed API:

Do you know one? Please contribute it!

Documentation