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






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM