[原]调试ComFriendlyWaitMtaThreadProc崩溃

项目里安装了UIA相关的钩子来监听UIA相关事件,退出的时候偶尔会崩溃在ComFriendlyWaitMtaThreadProc中,如下

  从上图可以 看出 是访问到无效的 地址 了,用!address  07acf914 看下地址信息
  确实是不可访问的,但是为啥呢?用ub看了下前面的代码
  从红框中我们 可以看出edi是指向第一个参数(ebp+8指向第一个参数),用k命令看下调用栈,如下
原来 ComFriendlyWaitMtaThreadProc 是线程回调函数啊,那么edi就指向了传入的参数!通过查看CreateThread的原型我们可以知道  ComFriendlyWaitMtaThreadProc 原型是 typedef DWORD ( __stdcall *LPTHREAD_START_ROUTINE )( LPVOID   lpThreadParameter );
综上可知,参数lpThreadParameter出问题了,指向了一个非法的地址!
有两种猜测:
1. 调用线程用了一个栈上的局部变量,但是调用线程挂掉了,栈上的内容无效了!
2. 代码中存在bug,传递参数的时候就传的有问题!(可能性太低了)
 
单纯的从dump中看不出更多的信息了!于是我决定给  ComFriendlyWaitMtaThreadProc 下断点, 看看是否能找到是谁创建了这个线程!
  1. bu uiautomationcore!ComFriendlyWaitMtaThreadProc
  2. g
断下来后用~*k查看当前所有线程,逐一查看,是否有可疑线程,发现11号线程很可疑
 
  经过一系列的反汇编,逻辑确认,最终确认11号线程是我们要找的线程!
 
结论:
当主程序退出时,0号线程( 主线程 )做清理工作,会等待11号线程(卸载钩子)一定的时间,如果超时了就将其强行杀死(正是这个TerminateThread的调用导致了崩溃)! 18号线程会用11号线程传过来的线程参数,如果11号线程被意外杀死了,那么11号线程中的操作就是未定义的!!!至此真相大白!(中间还有很多相关细节太琐碎了,这里直接写出了结论)
 
 
 
说明:
uia在装钩子和卸载钩子的时候都会做类似的操作,而且会做很多次,具体没再仔细研究!
 
高能预警:
不要使用TerminateThread!!!事实再次残酷的证明了,调用TerminateThread不会有好果子吃!





转载于:https://www.cnblogs.com/bianchengnan/p/6226780.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值