线程的创建和控制
进程和线程的关系:进程提供资源,线程使用资源完成工作
创建线程函数
HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD /安全属性 DWORD dwStackSize, // initial stack size //线程栈大小- LPTHREAD_START_ROUTINE lpStartAddress, // thread function //线程代码 LPVOID lpParameter, // thread argument //线程参数 DWORD dwCreationFlags, // creation option //创建标识 LPDWORD lpThreadId // thread identifier //线程id );
线程的控制
//线程等待 //等待一个 DWORD WaitForSingleObject( HANDLE hHandle, // handle to object,监视对象的句柄 DWORD dwMilliseconds // time-out interval 指定超时等待时间 毫秒为单位 ); //等待多个 DWORD WaitForMultipleObjects( DWORD nCount, // number of handles in array,句柄数量 CONST HANDLE *lpHandles, // object-handle array 句柄数组 BOOL fWaitAll, // wait option 是否全等待/TRUE 全部结束才返回/False 一个结束就返回 DWORD dwMilliseconds // time-out interval,超时时间 ); //获取线程的退出代码 BOOL GetExitCodeThread( HANDLE hThread, // handle to the thread LPDWORD lpExitCode // termination status );
更多的API
HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD /安全属性 DWORD dwStackSize, // initial stack size //线程栈大小- LPTHREAD_START_ROUTINE lpStartAddress, // thread function //线程代码 LPVOID lpParameter, // thread argument //线程参数 DWORD dwCreationFlags, // creation option //创建标识 LPDWORD lpThreadId // thread identifier //线程id );
创建标志位:
指定一个标志来控制线程的创建,如果指定了 CREATE_SUSPENDED
标志,则线程是在一个挂起状态
下创建的,并且在调用了ResumeThread ()
函数之前不会运行,如果这个值为零,那么线程在创建之后立即运行
//线程回复 DWORD ResumeThread( HANDLE hThread // handle to thread 目标线程的句柄 ); //让自己停下来 VOID Sleep( DWORD dwMilliseconds // sleep time 暂停时间 ); //让目标停下来 DWORD SuspendThread( HANDLE hThread // handle to thread 挂起目标的句柄 );
挂起计数:
API ResumeThread
提到了挂起计数
线程在系统中通过线程内核对象管理,线程内核对象有一个 挂起计数器
用于统计当前线程被挂起的次数
当调用SuspendThread
挂起计数就会+1
调用ResumeThread
挂起计数就会-1
当挂起计数为0时,线程将会正常执行
线程的本质
-
一个单核CPU 一瞬间只能做一件事,那如何实现多线程在一个进程内“同时”干不同的工作
>操作系统会给每一个线程都分配一定的时间,在一点时间内CPU加载对应的线程上下文执行线程对应代码和EIP所指向的位置、堆栈等,时间过后就保存当前执行的环境,然后更换线程上下文,来回调度。对于CPU来说 一瞬间就做了一件事,但是CPU速度非常快。在我们看起来就是一起做很多事情
-
什么是线程?
一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成 线程是WINDOWS中最基本的调度单位 线程调度 理论上A、B、C、D 进程 轮流调度执行 但是实际上 windows系统是以线程为单位轮流调度执行的。原因很复杂,有一套复杂的逻辑 根据一些条件灵活调度,比如线程优先级、饥饿度等
-
获取线程的上下文CONTEXT结构体
BOOL GetThreadContext( HANDLE hThread, // handle to thread with context 目标线程句柄 LPCONTEXT lpContext // context structure 结构体缓存 );
练习:
通过创建快照CreateToolhelp32Snapshot
的方式,遍历所有线程
每个进程有一个PID,线程也有TID,找到目标进程中所有线程,然后全部挂起。实现一个线程挂起功能
坑
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论