zoukankan      html  css  js  c++  java
  • 零基础逆向工程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;
    }
    
    
  • 相关阅读:
    【MySQL】若sql语句中order by指定了多个字段,则怎么排序?
    【golang】golang中结构体的初始化方法(new方法)
    【feign】拦截输出日志
    【Feign】Feign ,OpenFeign以及Ribbon之间的区别?
    没有安装插件:node-sass , sass-loader@6.0.7 导致在style标签中使用 lang="scss" 报错
    解决:'webpack-dev-server' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
    解决:flex弹性布局和溢出隐藏使用ellipsis省略号提示的冲突
    缺少标签template抱歉的包裹报错:[Vue warn]: Failed to mount component: template or render function not defined.
    两个(div)元素使用了display:inline-block后出现错位问题解决
    块级标签使用 display:inline-block;显示一行,存在多余的边距的bug解决办法
  • 原文地址:https://www.cnblogs.com/flatcc/p/7856782.html
Copyright © 2011-2022 走看看