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

线程控制

实验

零基础逆向工程34_Win32_08_线程控制_CONTEXT结构_第1张图片

挂起线程

::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结构)