零基础逆向工程34_Win32_08_线程控制_CONTEXT结构
线程控制
实验

挂起线程
::SuspendThread(hThread);
恢复线程
::ResumeThread(hThread);
终止线程 (这里讲了同步调用与异步调用)
方式一:	此方法结束线程会自动清理堆栈	
::ExitThread(DWORD dwExitCode);		
方式二:		
线程函数返回		
方式三:	而此方法结束线程不会自动清理堆栈	
::TerminateThread(hThread,2);
::WaitForSingleObject(hThread,INFINITE);		
判断线程是否结束
BOOL GetExitCodeThread(
  HANDLE hThread,
  LPDWORD lpExitCode
);
STILL_ACTIVE 正在运行
参数:
hThread: 要结束的线程句柄
dwExitCode: 指定线程的退出代码。可以通过GetExitCodeThread来查看一个线程的退出代码
线程:CONTEXT结构
起因
每个线程在执行的时候,都会独自占用一个CPU,当系统中的线程数量 > CPU的数量时,就会存在多个线程共用一个CPU的情况。但CPU每次只能运行一个线程,Windows每隔20毫秒会进行线程的切换,那比如线程A执行到地址:0x2345678eax:1 ecx:2 edx:3 ebx:4...还有eflag标志寄存器中的值等等。此时,线程执行时间到了,被切换到了线程B。当线程B的时间片也到了,再切换会线程A时,系统是如何知道该从哪个地址开始执行呢?被切换前用到的各种寄存器的值该如何恢复呢?
那么就用到了CONTEXT结构
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);	
这段代码有什么安全隐患?什么原因导致的?
HWND hEdit ;
DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
	TCHAR szBuffer[10];
	DWORD dwIndex = 0;
	DWORD dwCount;
	while(dwIndex<10)
	{
		GetWindowText(hEdit,szBuffer,10);
		sscanf( szBuffer, "%d", &dwCount );
		dwCount++;
		memset(szBuffer,0,10);
		sprintf(szBuffer,"%d",dwCount);
		SetWindowText(hEdit,szBuffer);
		dwIndex++;
	}
	return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
	TCHAR szBuffer[10];
	DWORD dwIndex = 0;
	DWORD dwCount;
	while(dwIndex<10)
	{
		GetWindowText(hEdit,szBuffer,10);
		sscanf( szBuffer, "%d", &dwCount );
		dwCount++;
		memset(szBuffer,0,10);
		sprintf(szBuffer,"%d",dwCount);
		SetWindowText(hEdit,szBuffer);
		dwIndex++;
	}
	return 0;
}
BOOL CALLBACK MainDlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	BOOL bRet = FALSE;
	switch(uMsg)
	{
	case WM_CLOSE:
		{
			EndDialog(hDlg,0);
			break;
		}
	case WM_INITDIALOG:
		{
			hEdit = GetDlgItem(hDlg,IDC_EDIT1);
			SetWindowText(hEdit,"0");
			break;
		}
	case WM_COMMAND:
		switch (LOWORD (wParam))
		{
		case IDC_BUTTON_T1:
			{
				HANDLE hThread1 = ::CreateThread(NULL, 0, ThreadProc1,
					NULL, 0, NULL);
				::CloseHandle(hThread1);
				return TRUE;
			}
		case IDC_BUTTON_T2:
			{
				HANDLE hThread2 = ::CreateThread(NULL, 0, ThreadProc2,
					NULL, 0, NULL);
				::CloseHandle(hThread2);
				return TRUE;
			}
		}
		break ;
	}
	return bRet;
}
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	// TODO: Place code here.
	DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG_MAIN),NULL,MainDlgProc);
	return 0;
}
零基础逆向工程34_Win32_08_线程控制_CONTEXT结构的更多相关文章
- 零基础逆向工程20_PE结构04_任意节空白区_新增节_扩大节添加代码
		向代码节添加代码实现 作者经过一周不断的失败,再思考以及无数次调试终于实现. 思路:八个步骤 1. 文件拷到文件缓冲区(FileBuffer) //图示见(零基础逆向工程18之PE加载过程) 2. 文 ... 
- 零基础逆向工程38_Win32_12_信号量_线程控制小结
		1 信号量 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用.[百度百科] 1.1 创建信号量 HANDLE Create ... 
- 零基础逆向工程37_Win32_11_事件_线程同步
		1 内核对象 前面已经学过线程和互斥体两个内核对象.此节讲了事件这个内核对象.前面提出了内核对象这个概念,可能不太清晰,简单来说内核对象就是系统层的东西. 1.1 小结内核对象: 进程.线程.事件.互 ... 
- 零基础逆向工程36_Win32_10_互斥体_互斥体与临界区的区别
		1 引言 讲了第二个内核对象,互斥体.前面已经学过一个内核对象,线程.这节讲两个函数,WaitForSingleObject()和WaitForMultipleObjects().因此这两个函数是根据 ... 
- 零基础逆向工程35_Win32_09_临界区_CRITICAL_SECTION结构
		1 引入 为什么会存在临界区这中机制呢?是为多线程同时访问全局变量而引入的.也就是上一篇帖子的末尾流出的问题程序的解决办法. 看懂了上面的,那么我们再罗嗦总结一下: 1.多线程访问全局变量时,存在线程 ... 
- 零基础逆向工程33_Win32_07_创建线程
		1 什么是线程(Threads)? 什么是多线程? 怎么在windows中观察多线程? 线程可以简单理解为主程序为解决一个问题而选择的其中一条路线. 同理,多线程就是同时选择不同的路线来解决此问题. ... 
- 零基础逆向工程22_PE结构06_导入表
		导入表结构 typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { DWORD Characteristics; DWORD OriginalFirstTh ... 
- 零基础逆向工程11_C语言05_结构体
		结构体小结 结构体是按照分配的大小,局部变量会自动数据对齐 1字节对齐,省空间,但cpu查找效率低 4字节对齐,不省空间,但cpu查找效率高 VC6默认的结构对齐大小 项目右键-> settin ... 
- 零基础逆向工程23_PE结构07_重定位表_IAT表(待补充)
		重定位表 待补充 IAT表 待补充 
随机推荐
- 《图解HTTP》阅读笔记-第五章-web服务器
			第五章.与HTTP协助的web服务器单台虚拟主机实现多个域名可以用单台物理主机运行多台虚拟主机,这些虚拟主机的IP相同,而虚拟主机有可以寄存多个不同主机名和域名的web网站,所以要保证发送HTTP ... 
- linux文件系统总结
			apue中:其中进程表项内部的数组又称为 进程打开文件表 另外一个角度: 从linux内核角度开: task_struct是进程描述符对应上面的进程表项,在task_struct描述符中有str ... 
- [HNOI2004]宠物收养场 BZOJ1208 splay tree
			题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ... 
- Qt 学习之路 2(6):Qt 模块简介
			Home / Qt 学习之路 2 / Qt 学习之路 2(6):Qt 模块简介 豆子 2012年8月26日 Qt 学习之路 2 20条评论 Qt 5 与 Qt 4 最大的一个区别之一是底层架构 ... 
- [Android UI]View滑动方式总结
			一.前言 在上一篇文章,介绍了View的坐标等基础知识,有了基础知识后,对下面内容的理解也将会容易很多.那么本文介绍的是View滑动的几种方式,这对于View来说,也是需要重要掌握的内容,因为用户无时 ... 
- CSS+jQuery实现轮播
			CSS+jQuery实现轮播 CSS jQuery 前端 实现功能: 自动轮播: 鼠标放在上面停止轮播: 鼠标放在上面显示左右切换的按钮: 鼠标放在小圆圈上显示对应的图片: 轮播效果图 style. ... 
- Experimental Educational Round: VolBIT Formulas Blitz F
			Description One company of IT City decided to create a group of innovative developments consisting f ... 
- Go语言基础练习题系列2
			1.练习1 生成一个随机数,让一个用户去猜这个数是多少? 代码示例如下: package main import ( "fmt" "math/rand" //m ... 
- connecting-to-github-with-ssh
			https://help.github.com/articles/connecting-to-github-with-ssh/ 创建ssh密钥后,从github clone仓库到本地出现permiss ... 
- getResourceAsStream properties
			try (InputStream is = getClass().getResourceAsStream("/test.properties")) { Properties pro ... 
