线程上下文数据结构
WINDOWS 中定义了一个CONTEXT 结构,该结构包含了特定处理器上的寄存器数据。系统使用CONTEXT 结构执行各种内部操作。目前,已经存在为Intel 、MIPS 、Alpha 和PowerPC 处理器定义的CONTEXT 结构。若要了解这些结构的定义,可以去看WinNT.h 。
该结构并没有说明结构体内的成员,也没有描述这些成员是谁,因为这些成员要取决于WINDOWS 运行在哪个平台上。在WINDOWS 定义的所有数据结构中,CONTEXT 结构是特定于CPU 的唯一结构。
在CONTEXT 结构中,它包含了主机CPU 上的每个寄存器的数据结构。在X86 计算机上,数据成员是EAX ,EBX ,ECX ,EDX 等等。如果是Alpha 处理器,那么数据成员包括IntV0,IntT0,IntT1,IntS0,IntRa 和IntZero 等等。下面的代码演示了X86 CPU 完整的CONTEXT 结构。
typedef struct _CONTEXT
{
DWORD ContextFlags;
// 调试寄存器
DWORD Dr0;
DWORD Dr1;
DWORD Dr2;
DWORD Dr3;
DWORD Dr6;
DWORD Dr7;
// 浮点寄存器
FLOATING_SAVE_AREA FloatSave;
// 栈寄存器
DWORD SegGs;
DWORD SegFs;
DWROD SegEs;
DWORD SegDs;
// 整型寄存器
DWORD Edi;
DWORD Esi;
DWORD Ebx;
DWORD Edx;
DWORD Ecx;
DWORD Eax;
// 控制寄存器
DWORD Ebp;
DWORD Eip;
DWORD SegCs;
DWORD EFlags;
DWORD Esp;
DWORD SegSs;
// 扩展寄存器
BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
}CONTEXT;
可以使用 BOOL GetThreadContext(HANDLE,PCONTEXT); 函数来取得一个线程的上下文。
ContextFlags 用于指定你关注此数据结构中哪些寄存器值。可以是如下定义
CONTEXT_CONTROL
CONTEXT_INTEGER
CONTEXT_SEGMENTS
CONTEXT_FLOATING_POINT
CONTEXT_DEBUG_REGISTERS
CONTEXT_EXTENDED_REGISTERS;
另外,在WinNT.h 中还定义了一个CONTEXT_FULL 定义如下
#ifdefine _X86
#define CONTEXT_FULL \
CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS
#endif
#ifdefine _ALPHA
#define CONTEXT_FULL \ CONTEXT_CONTROL|CONTEXT_FLOATING_POINT|CONTEXT_INTEGER
#endif
同样我们可以通过SetThreadContext(HANDLE,PCONTEXT); 来修改一个线程的寄存器值。步骤如下。
1、 将要操作的线程挂起。
2、 定义一个CONTEXT 结构变量,将其ContextFlags 初始化,标记你关注哪些值。
3、 使用GetThreadContext 取得上下文。
4、 修改你想修改的寄存器值。
5、 用SetThreadContext 更新系统中线程的上下文。
6、 唤醒线程
另外,对于指令指针和堆栈指针寄存器X86 和ALPHA 机器上是不一样的。
X86 是EIP 和ESP ,而ALPHA 中是Fir 和IntSp 。在使用的时候,应该根据具体情况分析。。当然,上面的操作在一般的应用程序中不会使用。若你想编写调试程序,调试器等才有可能用到。