• 零基础逆向工程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;
    }
    
    
  • 相关阅读:
    https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic net::ERR_CONNECTION_TIMED_OUT问题解决
    nginx 下使用 bootstrap 字体的问题
    php中函数preg_match或preg_match_all 第三个参数$match的解释
    thinkphp中 volist循环的 mod取值的问题
    mysql中sql注入的随笔
    修改mysql的字符集和默认存储引擎
    使用Marsedit在博客园写作
    Server Tomcat v7.0 Server at localhost failed to start.临时解决办法
    【转】Linux Mint 17.2 gedit中文乱码
    HashMap和HashSet
  • 原文地址:https://www.cnblogs.com/flatcc/p/7856782.html
Copyright © 2020-2023  润新知