[原]调试ComFriendlyWaitMtaThreadProc崩溃

mac2025-01-08  38

项目里安装了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 下断点, 看看是否能找到是谁创建了这个线程! bu uiautomationcore!ComFriendlyWaitMtaThreadProcg 断下来后用~*k查看当前所有线程,逐一查看,是否有可疑线程,发现11号线程很可疑     经过一系列的反汇编,逻辑确认,最终确认11号线程是我们要找的线程!   结论: 当主程序退出时,0号线程( 主线程 )做清理工作,会等待11号线程(卸载钩子)一定的时间,如果超时了就将其强行杀死(正是这个TerminateThread的调用导致了崩溃)! 18号线程会用11号线程传过来的线程参数,如果11号线程被意外杀死了,那么11号线程中的操作就是未定义的!!!至此真相大白!(中间还有很多相关细节太琐碎了,这里直接写出了结论)       说明: uia在装钩子和卸载钩子的时候都会做类似的操作,而且会做很多次,具体没再仔细研究!   高能预警: 不要使用TerminateThread!!!事实再次残酷的证明了,调用TerminateThread不会有好果子吃!

来自为知笔记(Wiz)

最新回复(0)