zoukankan      html  css  js  c++  java
  • win32线程

              win32线程

    一丶什么是线程

    在windows中常听到的就是线程.多线程.啊什么的. 这里介绍一下什么是线程.

    1.线程是附属在进程中的一个执行实体.简而言之就是执行代码的.

    2.每个进程至少有一个线程.可以有多个线程. 一对多的关系.

    3.单核CPU可以实现多线程. 几秒钟换一次线程执行不同进程的代码.就实现了多线程.

    PS: 在切换的过程中会保存线程的信息. 堆栈寄存器等信息.

    二丶线程常见操作API

    1.CreateThread 创建线程

    HANDLE CreateThread(
      LPSECURITY_ATTRIBUTES   lpThreadAttributes,     SD安全属性
      SIZE_T                  dwStackSize,                          创建线程的堆栈大小.为0则默认
      LPTHREAD_START_ROUTINE  lpStartAddress,        创建线程执行代码的地址.
      __drv_aliasesMem LPVOID lpParameter,                创建线程需要的参数
      DWORD                   dwCreationFlags,                   创建标志.挂起创建还是普通创建
      LPDWORD                 lpThreadId                           返回创建的线程ID
    ); 
     返回值: 返回创建的线程句柄.

    2. Sleep(毫秒);  延时命令. 可以让当前线程等待指定时间.然后继续执行代码.

    3. SuspendThread 挂起线程.如果挂起则线程不能执行

    DWORD SuspendThread(
      HANDLE hThread              需要线程句柄
    );

    64位下

    DWORD Wow64SuspendThread(    64位调用的API
      HANDLE hThread
    );

    4.ResumeThread 恢复线程执行

    DWORD ResumeThread(
      HANDLE hThread          传入要恢复线程执行的线程句柄
    );

    5.获取线程句柄 OpenThread

    HANDLE OpenThread(
      DWORD dwDesiredAccess,       访问权限
      BOOL  bInheritHandle,        是否可以继承
      DWORD dwThreadId             线程ID
    ); 
    返回线程句柄

    6.WaitForsingleObjec  等待单个内核对象返回

    DWORD WaitForSingleObject(
    HANDLE hObject,         //指明一个内核对象的句柄 注意可以等待的是内核对象不一定是线程.
    DWORD dwMilliseconds   //等待时间
    );     

    7.WaitForMultObjects 等待多个内核对象返回

    DWORD WaitForSingleObject(
    DWORD count;            //指明的个数
    HANDLE *hObject,         //指明一个内核对象的数组指针
    DWORD  dwflages          //等待模式. 如果TURE则数组里面的句柄都等待.false相反.有一个返回就返回
    DWORD dwMilliseconds   //等待时间
    );    

    8.CONTEXT结构体.

    我们知道线程切换的过程中.操作系统会保存线程当前寄存器的值.以及EIP.所以会有一个结构体来保存.这个结构体就是CONTEXT.称作线程上下文.

    PS: 这个结构未公开 需要在WinNT.h 中查看.

    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需要使用API获取和设置. 但是在获取的前提下.我们需要对CONTEXT的一个重要成员赋值.

    这个成员是   ContextFlags 成员.我们需要指明我们要获取那个寄存器的值. 比如通用寄存器. 调试寄存器. 等等..

    而设置的值在这个结构中的注释也说了. CONTEXT_INTEGER 可以给定这个.也可以自己定义.具体查看注释说明.

    9.获取线程设备上下文.  

    BOOL GetThreadContext(
      HANDLE    hThread,           线程句柄
      LPCONTEXT lpContext          传入Context结构.操作系统写入.给我们传出
    ); 

    如果是64位下.则使用API 

    BOOL Wow64GetThreadContext(
      HANDLE         hThread,
      PWOW64_CONTEXT lpContext
    );

    10.设置线程设备上下文. SetThreadContext

    BOOL SetThreadContext(
      HANDLE        hThread,      线程句柄
      CONST CONTEXT *lpContext    CONTEXT结构
    );

    64位下

    BOOL Wow64SetThreadContext(
      HANDLE              hThread,
      CONST WOW64_CONTEXT *lpContext
    );

    上面的关于线程切换的CONTEXT. 我们可以利用它做一个EIP注入. 详情请看注入分类中的 EIP注入博客.

  • 相关阅读:
    SCCM 补丁更新 失误排错一例
    Oracle 远程连接 DB配置 连接命令
    反向代理服务器
    用JMF播放音频 例子
    HTML css兼容
    Java国际化
    JBPM 之介绍,使用
    Nginx内核优化引用
    Nginx 学习
    局域网访问VMware虚拟机中的Ubuntu
  • 原文地址:https://www.cnblogs.com/iBinary/p/9572121.html
Copyright © 2011-2022 走看看