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

Posted FLATCC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了零基础逆向工程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结构的主要内容,如果未能解决你的问题,请参考以下文章

零基础逆向工程36_Win32_10_互斥体_ForSingleObject_WaitForMultipleObjects

零基础逆向工程40_Win32_14_枚举窗口_模拟鼠标键盘

零基础逆向工程39_Win32_13_进程创建_句柄表_挂起方式创建进程

C零基础课程-03-VS的入门使用及设置

win32 基础数据发送与接收

win32 基础数据发送与接收