win32线程
Posted ibinary
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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注入博客.
以上是关于win32线程的主要内容,如果未能解决你的问题,请参考以下文章