C++线程CONTEXT 笔记

今天看到了 线程的上下文 context  就觉得一件很有意思的事情 ,破解外挂的时候会遇到一件神奇的事情当外挂发现调试器 这个程序自己不知怎么了自己崩溃(通常说EIP 寻址错误啥额 或者内存不能读写 .......)

这个C++线程上下文 就是当你线程 挂起的时候 系统肯定要记录这些寄存器以及eip的值  此时你可以读取里面的值并且修改 当线程再次得到处理机 里面的值被随便改了 肯定 会出错 ....当然这里也可以hook    自己没学到以后说

自己写了一个简单的异常函数

VOID SetiExcepTion()
{
   //#define random(a,b) (rand()%(b-a)+a) 要定义它
	CONTEXT cont;
	cont.ContextFlags = CONTEXT_CONTROL;
	HANDLE pseudoHandle = GetCurrentThread();
	::SuspendThread(pseudoHandle);
	BOOL ok = ::GetThreadContext(pseudoHandle, &cont);
	if (ok)
	{
		
		cont.Ebp = random(10000, 99999);
		cont.Esp = random(10000, 99999);
		cont.Eip = random(10000, 99999);
		SetThreadContext(pseudoHandle, &cont);
		::ResumeThread(pseudoHandle);
CloseHandle(pseudoHandle); } }

 或者直接内联汇编

  

_asm
{
mov eax, 0
mov [eax], 1
}

程序也就崩溃了方式很多种

以下 来自滴水中级课件 总结不错   作为本人笔记 


每个线程在执行的时候,都会独自占用一个CPU,当系统中的线程数量 > CPU的数量时,就会存在多个线程共用一个CPU
的情况。但CPU每次只能运行一个线程,Windows每隔20毫秒会进行线程的切换,那比如线程A执行到地址:0x2345678
eax:1 ecx:2 edx:3 ebx:4...还有eflag标志寄存器中的值等等。。。
此时,线程执行时间到了,被切换到了线程B。。。。当线程B的时间片也到了,再切换会线程A时,系统是如何知道该
从哪个地址开始执行呢?被切换前用到的各种寄存器的值该如何恢复呢?


CONTEXT:

该结构包含了特定处理器的寄存器数据。


typedef struct _CONTEXT {

//
// The flags values within this flag control the contents of
// a CONTEXT record.
//
// If the context record is used as an input parameter, then
// for each portion of the context record controlled by a flag
// whose value is set, it is assumed that that portion of the
// context record contains valid context. If the context record
// is being used to modify a threads context, then only that
// portion of the threads context will be modified.
//
// If the context record is used as an IN OUT parameter to capture
// the context of a thread, then only those portions of the thread's
// context corresponding to set flags will be returned.
//
// The context record is never used as an OUT only parameter.
//

DWORD ContextFlags;

//
// This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
// set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT
// included in CONTEXT_FULL.
//

DWORD Dr0;
DWORD Dr1;
DWORD Dr2;
DWORD Dr3;
DWORD Dr6;
DWORD Dr7;

//
// This section is specified/returned if the
// ContextFlags word contians the flag CONTEXT_FLOATING_POINT.
//

FLOATING_SAVE_AREA FloatSave;

//
// This section is specified/returned if the
// ContextFlags word contians the flag CONTEXT_SEGMENTS.
//

DWORD SegGs;
DWORD SegFs;
DWORD SegEs;
DWORD SegDs;

//
// This section is specified/returned if the
// ContextFlags word contians the flag CONTEXT_INTEGER.
//

DWORD Edi;
DWORD Esi;
DWORD Ebx;
DWORD Edx;
DWORD Ecx;
DWORD Eax;

//
// This section is specified/returned if the
// ContextFlags word contians the flag CONTEXT_CONTROL.
//

DWORD Ebp;
DWORD Eip;
DWORD SegCs; // MUST BE SANITIZED
DWORD EFlags; // MUST BE SANITIZED
DWORD Esp;
DWORD SegSs;

//
// This section is specified/returned if the ContextFlags word
// contains the flag CONTEXT_EXTENDED_REGISTERS.
// The format and contexts are processor specific
//

BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];

} CONTEXT;


获取线程CONTEXT结构:

//挂起线程
SuspendThread(线程句柄);

CONTEXT context

//设置要获取的类型

context.ContextFlags = CONTEXT_CONTROL;

//获取

BOOL ok = ::GetThreadContext(hThread,&context);

//设置

context.Eip = 0x401000;

SetThreadContext(hThread,&context);





原文地址:https://www.cnblogs.com/xuexidememeda/p/12587368.html