本文介绍使用Windbg去验证《DllMain中不当操作导致死锁问题的分析--导致DllMain中死锁的关键隐藏因子》中的结论,调试对象是文中刚开始那个例子。(转载请指明出于breaksoftware的csdn博客)

1 g 让程序运行起来

2 ctrl+break 中断程序

3 ~ 查看线程数

其实该程序自己运行起来的线程只有ID为0、TID为afc的线程。18c4线程是我们在windbg中输入ctrl+break,导致windbg在我们调试的进程中插入的一个中断线程。以后我们看到是这个线程的操作,就可以忽略。

4 dd fs:[0] 寻找主线程TEB起始地址(7ffde000)

5 dt _TEB 7ffde000 查看主线程中PEB结构指针(0x7ffdc000)

6 dt _PEB 0x7ffdc000 寻找LoaderLock的指针(0x7c99e0174)

7  dt_RTL_CRITICAL_SECTION 0x7c99e174 查看临界区状态,我们看到看到LockCount值为-1,那么我们通过给它设置“写”断点,从而在每次“关键”时刻予以监控。

8 baw2 0x7c99e178 对LockCount设置写断点

9 g

10kb 我们看到线程号是1,即Windbg插入的线程导致的断点,我们忽略之(我们看到关闭线程时也会进入临界区)

11 g

12 kb 同上,忽略之

13 g

14 kb 这次是主线程(0)触发了断点,断点原因是LdrLoadDll中要加锁。

我们使用IDA反编译LdrLoadDll,可以看到调用的位置

 v4 = RtlDosApplyFileIsolationRedirection_Ustr(1, a3, &unk_7C99E214, &v11, &v14, &v17, 0, 0, 0);v5 = v4;if ( v4 >= 0 ){v9 = 1;}else{if ( v4 != -1072365560 )goto LABEL_6;}LdrLockLoaderLock(1, 0, &v10);ms_exc.disabled = 0;

15 g

16 kb 还是主线程(0)触发了断点,原因是LdrLoadDll中调用了LdrpLoadDll,该函数中需要进入临界区,这是第二次进临界区了。在《Best Practices for Creating DLLs》中有对这种现象允许的说明

The loader lock is recursive, which means that it can be acquired again by the same thread.  

在LdrLoadDll中我们看到

LdrLockLoaderLock(1, 0, &v10);ms_exc.disabled = 0;if ( LdrpTopLevelDllBeingLoaded ){if ( ShowSnaps || LdrpShowRecursiveDllLoads || LdrpBreakOnRecursiveDllLoads ){DbgPrint("[%lx,%lx] LDR: Recursive DLL load\n");DbgPrint("[%lx,%lx]   Previous DLL being loaded: \"%wZ\"\n");DbgPrint("[%lx,%lx]   DLL being requested: \"%wZ\"\n");if ( LdrpCurrentDllInitializer )DbgPrint("[%lx,%lx]   DLL whose initializer was currently running: \"%wZ\"\n");elseDbgPrint("[%lx,%lx]   No DLL initializer was running\n");}}LdrpTopLevelDllBeingLoaded = v17;v6 = LdrpLoadDll(v9, a1, a2, v17, a4, 1);

在LdrpLoadDll中我们看到


        17 g

18 kb 第三次进入临界区

19 g 主线程第一次退出临界区

20 kb 主线程第四次进入临界区

21 g 主线程第二次退出临界区

22 g 有线程要进入临界区

23 kb 这次是我们在代码中启动的工作线程(1)要尝试进入临界区

24 ~ 查看线程 确定有两个线程了

25 g

26 kb 工作线程(1)要进入临界区,可是它不会进去的,因为它会被挂起

27 g 死锁了

28 control+break windbg要启动一个中断线程,中断线程触发了断点

29 ~ 查看线程,ID为2的就是windbg插入的线程

30 ~0s 切换到主线程(0),发现主线程在内核态中出不来了

31 kb 查看主线程调用堆栈,确实是在等工作线程结束

32 ~1s 切换到工作线程,发现它也在内核态中出不来了

33 kb 查看工作线程调用堆栈

34 dt _RTL_CRITICAL_SECTION 0x7c99e174  查看临界区所有权,从线程TID中我们可以看到,临界区的确是被主线程占着。

DllMain中不当操作导致死锁问题的分析--导致DllMain中死锁的关键隐藏因子2相关推荐

  1. DllMain中不当操作导致死锁问题的分析——DllMain中要谨慎写代码(完结篇)

    之前几篇文章主要介绍和分析了为什么会在DllMain做出一些不当操作导致死锁的原因.本文将总结以前文章的结论,并介绍些DllMain中还有哪些操作会导致死锁等问题.(转载请指明出于breaksoftw ...

  2. DllMain中不当操作导致死锁问题的分析--加载卸载DLL与DllMain死锁的关系

    前几篇文章一直没有在源码级证明:DllMain在收到DLL_PROCESS_ATTACH和DLL_PROCESS_DETACH时会进入临界区.这个论证非常重要,因为它是使其他线程不能进入临界区从而导致 ...

  3. DllMain中不当操作导致死锁问题的分析--导致DllMain中死锁的关键隐藏因子

    有了前面两节的基础,我们现在切入正题:研究下DllMain为什么会因为不当操作导致死锁的问题.首先我们看一段比较经典的"DllMain中死锁"代码.(转载请指明出于breaksof ...

  4. DllMain中不当操作导致死锁问题的分析--死锁介绍

    最近在网上看到一些关于在DllMain中不当操作导致死锁的问题,也没找到比较确切的解答,这极大吸引了我研究这个问题的兴趣.我花了一点时间研究了下,正好也趁机研究了下进程对DllMain的调用规律.因为 ...

  5. 导致DllMain中死锁的关键隐藏因子

    原文地址:https://blog.csdn.net/hczhiyue/article/details/18505087 有了前面两节的基础,我们现在切入正题:研究下DllMain为什么会因为不当操作 ...

  6. DllMain中不当操作导致死锁问题的分析--进程对DllMain函数的调用规律的研究和分析

    不知道大家是否思考过一个过程:系统试图运行我们写的程序,它是怎么知道程序起始位置的?很多同学想到,我们在编写程序时有个函数,类似Main这样的名字.是的!这就是系统给我们提供的控制程序最开始的地方(注 ...

  7. MySQL笔记-死锁原理与分析及InnoDB中如何减少死锁

    根据InnoDB的加锁规则(Record Lock.Gap Lock.meta data lock)可以写出不会发生死锁的SQL语句,也能定位出产生死锁的原因. 死锁产生的原因: 产生回路:两个或两个 ...

  8. DllMain中不当操作导致死锁问题的分析——线程中调用GetModuleFileName、GetModuleHandle等导致死锁

    之前的几篇文章已经讲解了在DllMain中创建并等待线程导致的死锁的原因.是否还记得,我们分析了半天汇编才知道在线程中的死锁位置.如果对于缺乏调试经验的同学来说,可能发现这个位置有点麻烦.那么本文就介 ...

  9. 在光纤通信中最常用的波长和作用分析

    描述 光是由它的波长来定义,在光纤通信中,使用的光是在红外区域中的光,此处光的波长大于可见光. 在光纤通信中,典型的波长是800到1600nm,其中最常用的波长是850nm.1310nm和1550nm ...

最新文章

  1. java接口的映射文件,详解mybatis通过mapper接口加载映射文件
  2. lograotate 配置常用配置
  3. C#封装类似任务管理器CPU使用记录图
  4. 2019年第十届蓝桥杯 - 省赛 - C/C++大学B组 - C. 数列求值
  5. 20161114记录一件工作的事
  6. python if break_python_if_else,while,break
  7. 程序win10_win10该文件没有与之关联的程序来执行操作
  8. tensorflow学习笔记1
  9. Node.js入门以及第一个helloworld程序.
  10. Java让数据库执行一条sql_java数据库编程——执行SQL 语句
  11. 2022年全网首发|大数据专家级技能模型与学习指南(胜天半子篇)
  12. js如何直接打开百度地图app进行导航
  13. 操作系统动态分区分配方式的模拟实现(分配与回收)C++
  14. 电脑查看曾经连接上的wifi密码
  15. ubuntu更改网卡设置等出现输入default keyring密码的解决方法
  16. 怎么组建云计算中心?
  17. 小李飞刀:Python我又来啦,例无虚发~
  18. 数据可视化利器D3.js教程 API
  19. JavaScript判断浏览器版本
  20. 想要刚毕业就月入过万必须要懂这些面试题(Vue 篇)

热门文章

  1. Open3D 三维点云读取可视化、下采样、去除离群点、地面提取
  2. Pyhton,OpenCV对象检测之——Haar级联人脸及眼睛检测
  3. 基于视频理解TSM和数据集20bn-jester-v1的27类手势识别
  4. keras 的 example 文件 variational_autoencoder.py 解析
  5. keras 的 example 文件 cnn_seq2seq.py 解析
  6. OpenCV(十九)直方图(直方图计算、掩膜、均衡化、自适应均衡化)
  7. 【MediaPipe】(2) AI视觉,人体姿态关键点实时跟踪,附python完整代码
  8. 【Pandas库】(6) 索引操作--改、查、高级索引
  9. ssl 接收到一个超出最大准许长度的记录_我所经历的一次Dubbo服务雪崩,这是一个漫长的故事...
  10. python获取数据类型_python数据类型详解