无论可等待对象是何种类型,线程都是通过:

WaitForSingleObject
WaitForMultipleObjects

进入等待状态的,这两个函数是理解线程等待与唤醒进制的核心

WaitForSingleObject参数说明

WaitForSingleObject对应的内核函数:

NTSTATUS stdcall NtWaitForSingleObject
( HANDLE Handle,                    BOOLEAN Alertable,              PLARGE_INTEGER Timeout
)

Handle 用户层传递的等待对象的句柄 (具体细节参加句柄表专题)

Alertable 对应 KTHREAD 结构体的 Alertable 属性如果为1在插入用户APC时,该线程将被吵醒

Timeout 超时时间



NtWaitForSingleObject

  1. 调用ObReferenceObjectByHandle函数,通过对象句柄找到等待对象结构体地址。
  2. 调用KeWaitForSingleObject函数,进入关键循环。

KeWaitForSingleObject:上半部分

!process 89316020
dt _KTHREAD 892db020
dt _KWAIT_BLOCK 892db020+70

每个等待块大小为0x18。

如果等待3个对象的话它就会占用前3个等待块,最后一个是给定时器用的。
如果你有4个等待对象它就不会用这个位置了,它会一次性分配新的空间。

  1. 向KTHREAD(+70)位置的等待块赋值。
  2. 如果超时时间不为0, KTHREAD(+70)第四个等待块与第一个等待块关联起来:第一个等待块指向第四个等待块,第四个等待块指向第一个等待块。
  3. KTHREAD(+5C)指向第一个KWAIT_BLOCK
  4. 进入关键循环

KeWaitForSingleObject的关键循环

while(true)//每次线程被其他线程唤醒,都要进入这个循环{if(符合激活条件)//1超时 2等待对象SignalState > 0{//1修改SignalState //2退出循环}else//SignalState不大于0 也没超时{if(第一次执行){//将当前线程的等待块挂到等待对象的链表 (WaitListHead) 中;//将自己挂入等待队列(KiaitListHead)//切换线程...再次获得CPU时,从这里开始执行}}}
1)线程将自己+5c位置清0
2)释放_KWAIT_BLOCK所占内存

WaitForSingleObject参数说明

kd> dt _DISPATCHER_HEADER
nt!_DISPATCHER_HEADER+0x000 Type           //该对象类型+0x001 Absolute     +0x002 Size            +0x003 Inserted+0x004 SignalState //该分发器信号状态 (值大于0就是有信号 分发器对象也称为同步对象)+0x008 WaitListHead //双向链表头,链着所有等待块(此链表包含了所有正在等待该分发器对象的线程)

不同的等待对象,用不同的方法来修改_DISPATCHER_HEADER(SignalState)比如:如果可等待对象是EVENT,其他线程通常使用SetEvent来设置SignalState= 1并且,将正在等待该对象的其他线程唤醒,也就是从等待链表(KiWaitListHead)中摘出来。但是, SetEvent函数并不会将线程从等待网上摘下来,是否要下来,由当前线程自己来决定。

关于强制唤醒
在APC专题讲过,当我们插入一个用户APC时(Alertable=1),当前线程是可以被唤醒的,但并不是真正的唤醒。
因为,如果当前的线程在等待网上,执行完用户APC后,仍然要进入等待状态。

4.WaitForSingleObject函数分析相关推荐

  1. Windows事件等待学习笔记(三)—— WaitForSingleObject函数分析

    Windows事件等待学习笔记(三)-- WaitForSingleObject函数分析 要点回顾 WaitForSingleObject NtWaitForSingleObject KeWaitFo ...

  2. linux C函数之strdup函数分析【转】

    本文转载自:http://blog.csdn.net/tigerjibo/article/details/12784823 linux C函数之strdup函数分析 一.函数分析 1.函数原型: [c ...

  3. 【Android 逆向】Dalvik 函数抽取加壳 ( 类加载流程分析 | Class.cpp#findClassNoInit 函数 | DexFile.cpp#dexFindClass 函数分析 )

    文章目录 前言 一.Class.cpp#dvmDefineClass 函数分析 二.Class.cpp#findClassNoInit 函数分析 三.DexFile.cpp#dexFindClass ...

  4. 【Android 逆向】Dalvik 函数抽取加壳 ( 类加载流程分析 | DexPathList#findClass 函数分析 | DexFile#loadClassBinaryName 函数 )

    文章目录 前言 一.DexPathList.java#findClass 类加载函数源码分析 二.DexFile.java#loadClassBinaryName 函数源码分析 前言 上一篇博客 [A ...

  5. 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | DexPathList 构造函数分析 | makeDexElements 函数分析 )

    文章目录 前言 一.DexPathList 构造函数分析 二.DexPathList.makeDexElements 函数分析 三.Element 类分析 前言 上一篇博客 [Android 逆向]整 ...

  6. 【Android 逆向】Android 逆向通用工具开发 ( adb forward 网络端口重定向命令 | PC 端逆向程序主函数分析 )

    文章目录 前言 一.adb forward 网络端口重定向命令 二.PC 端逆向程序主函数分析 前言 本篇博客重点分析 PC 端 hacktool 模块 ; 一.adb forward 网络端口重定向 ...

  7. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 注入工具的 main 函数分析 )

    文章目录 一.注入流程 二.注入工具的 main 函数分析 一.注入流程 开始分析 [Android 逆向]Android 进程注入工具开发 ( 编译注入工具 | 编译结果文件说明 | 注入过程说明 ...

  8. 继承关系中的拷贝构造函数和赋值操作重载函数分析

    文章目录 1 继承关系中的拷贝构造函数和赋值操作重载函数分析 1 继承关系中的拷贝构造函数和赋值操作重载函数分析 在继承关系中,如果子类未实现拷贝构造函数,那么在子类进行拷贝构造操作时,会直接调用父类 ...

  9. fprintf/fscanf函数分析

    fprintf/fscanf函数分析 宗旨:技术的学习是有限的,分享的精神是无限的. fprintf/fscanf函数与printf/scanf区别:printf/scanf专门针对标准输入输出流,f ...

最新文章

  1. 通俗易懂的TCP里面的三次握手以及四次挥手
  2. 8g ubuntu 树莓派4b_3D 打印制造树莓派 4B 平板电脑
  3. Android中的坐标系以及获取坐标的方法
  4. zookeeper for mac安装
  5. [Objective-c 基础 - 2.1] 封装
  6. 技术分享连载(六十四)
  7. tar (child): .tgz\r:无法 open: 没有那个文件或目录
  8. navigator属性
  9. vue中$nextTick()作用
  10. NB-IOT物联网平台是如何工作的
  11. Javascript对象属性方法集锦
  12. css sgc加密,ASP+SGC实现柱状图
  13. 热评一箩筐——《******技术宝典》
  14. PreparedStatement的使用
  15. Java中frame和panel区别,JFrame 和JPanel 的关系-区别(学习笔记)
  16. 拥抱趋势,蓄能跃迁——2018慧点科技企业协同及治理创新论坛圆满举行
  17. 通过一道ARM PWN题引发的思考:jarvisOJ_typo
  18. 快速实现NBIOT UDP通信
  19. xshell用无线网远程连接linux失败_vnc远程控制软件怎么用,3个步骤教你vnc远程控制软件怎么用...
  20. LaTex(论文排版)的使用心得及入门教程

热门文章

  1. DL之CNN:基于CRNN_OCR算法(keras,CNN+RNN)利用数据集(torch,mdb格式)训练来实现新图片上不定长度字符串进行识别—预测过程
  2. TF之DD:利用Inception模型+GD算法生成更高质量的Deep Dream高质量图片
  3. 成功解决fp = builtins.open(filename, quot;rbquot;) OSError: [Errno 22] Invalid argument: 'F:\\File_Pyt
  4. (已解决) MySQL: ERROR 1045 (28000): Access denied for user 'xxxxx'@'localhost' (using password: NO)
  5. Pandas常用I/O(一)------read_csv(),read_table()
  6. 静态页转换平台(StaticPol)-静态页生成终极解决方案(转)
  7. hibernate映射简单实例
  8. scrapy爬虫,爬取图片
  9. 初识java-循环结构(二):6
  10. ASP.NET Core 1.1 Preview 1 简介(包含.NETCore 1.1升级公告)