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注入博客.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏walterlv - 吕毅的博客

使用 PInvoke.net Visual Studio Extension 辅助编写 Win32 函数签名

2018-07-21 14:35

15110
来自专栏自由而无用的灵魂的碎碎念

介绍CodeRush Xpress for C#

用过Eclipse编写java代码,感觉它的某些功能在visual studio 中是没有的,比如Toggle Mark Occurrences:

11420
来自专栏张善友的专栏

LINQ TO XML

在.NET3.5中,框架对XML的操作进行了扩展,这个扩展就是LINQ to XML。在名称空间System.Xml.LINQ下。LINQ to XML 类型继...

19980
来自专栏MelonTeam专栏

一个创建自定义事件源的例子

上一篇文章我们介绍了RunLoop的相关知识,但是毕竟我们实际开发中很少应用,今天我们就通过介绍RunLoop在iOS系统中的应用,来实现一个小小的demo,启...

417100
来自专栏me的随笔

.NET Core类库中读取配置文件

最近在开发基于.NET Core的NuGet包,遇到一个问题: .NET Core中已经没有ConfigurationManager类,在类库中无法像.NET ...

16430
来自专栏Python小屋

Python查杀Windows系统中指定进程

下面的代码需要Windows API和Python标准库ctypes的相关知识。 from ctypes.wintypes import * from cty...

29150
来自专栏BY的专栏

Objective-C RunLoop 详解

40580
来自专栏.NET开发者社区

(码友推荐)2018-07-19 .NET及相关开发资讯速递

1.【ASp.Net Mvc Core 2 + angular6实战】 - 1. 环境搭建

13830
来自专栏张善友的专栏

ASP.NET MVC 2示例Tailspin Travel UI层分析

Tailspin Travel 是一个旅游预订的应用程序示例,最新版本采用ASP.NET MVC 2技术构建,主要使用 DataAnnotations 验证, ...

22390
来自专栏令仔很忙

VB 子窗体被PictureBox控件挡住无法显示

   VB做机房收费系统的时候,用的MDI主窗体,在主窗体上加了一个Picturebox控件,运行的时候,点了子窗体,但是却没有出现,后来才发现,子窗体被Pic...

8420

扫码关注云+社区

领取腾讯云代金券