银川做企业网站,河池网站制作,服务器的wordpress怎么外网访问,实验设计方案怎么写模板目录
1、概述
2、老版本的输入法导致软件CPU频繁跳高#xff08;导致软件出现卡顿#xff09;的问题
3、QQ拼音输入法注入到安装包进程中#xff0c;导致安装包主线程卡死问题
3.1、多线程死锁分析
3.2、进一步研究
4、安全软件注入到软件中#xff0c;注入模块发生了…目录
1、概述
2、老版本的输入法导致软件CPU频繁跳高导致软件出现卡顿的问题
3、QQ拼音输入法注入到安装包进程中导致安装包主线程卡死问题
3.1、多线程死锁分析
3.2、进一步研究
4、安全软件注入到软件中注入模块发生了崩溃直接导致软件发生崩溃
5、安全软件注入到软件中注入模块发生了内存泄露直接导致软件内存耗尽后发生闪退
6、最后 VC常用功能开发汇总专栏文章列表欢迎订阅持续更新...https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程专栏文章列表欢迎订阅持续更新...https://blog.csdn.net/chenlycly/article/details/125529931C软件分析工具从入门到精通案例集锦专栏文章持续更新中...https://blog.csdn.net/chenlycly/article/details/131405795C/C基础与进阶专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_11931267.html开源组件及数据库技术专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享专栏文章持续更新中...https://blog.csdn.net/chenlycly/category_2276111.html 有些软件为了实现某些功能需要远程注入到其他软件进程中的比如输入法和安全软件等注入到其他进程后注入模块就运行在被注入的进程空间中了一旦注入模块发生内存泄漏、崩溃等问题会直接影响到被注入的进程引发被注入进程发生异常。本文结合项目中遇到的若干问题给大家详细介绍一下因为远程注入引发软件异常的几个典型项目实例以供大家借鉴或参考。
1、概述 在日常工作中接触比较多的需要注入到其他软件进程的软件主要有输入法和安全软件 1输入法输入法在注入到其他软件进程之后其他软件进程才能使用输入法输入文字。 2安全软件安全软件为了实时监控其他软件的操作与行为为了实时监控其他软件网络数据的收发也需要远程注入到其他软件进程中。 用于远程注入的模块注入到目标进程中后就驻留在目标进程中了即运行在目标进程的进程空间中了。一旦注入模块发生异常会直接影响到被注入的进程会直接引发被注入的进程发生异常。 根据之前项目中遇到的多个问题注入模块对被注入进程的影响主要有以下几类 1输入法注入到软件进程后可能会导致软件发生明显的卡顿特别是在输入文字时这个问题在客户使用低版本的搜狗输入法时遇到过。 2输入法注入到软件进程后可能会引发软件发生死锁这个问题在运行软件安装包程序时遇到过。 3注入模块在运行过程中遇到异常发生崩溃直接导致被注入的软件发生崩溃。因为注入模块就运行在被注入的软件进程中的。 4注入模块发生内存泄漏内存泄漏发生在被注入的软件进程中导致被注入软件发生Out of memory内存耗尽发生闪退。 下面讲几个在项目中遇到的问题实例来看看注入模块是怎样影响到我们软件的。
2、老版本的输入法导致软件CPU频繁跳高导致软件出现卡顿的问题 有客户反馈在其使用我们软件的过程中会时不时出现卡顿问题。让客户打开Windows任务管理器让其帮忙观察一下软件使用过程中该软件进程的CPU占用情况。 经观察发现软件在使用过程中CPU占用比例会时不时地跳高跳高之后又自动回落。特别是在聊天框中输入时CPU会跳高。CPU占用变高一般可能是因为软件中在持续地执行代码导致的比如程序中发生死循环一直在不停歇地执行代码。但本例中CPU会很快自动回落好像不是死循环导致的如果是死循环CPU占用会一直比较高。难道代码中会出现短时间内的死循环 于是使用Process Explorer工具查看CPU占用高的线程然后查看该线程的函数调用堆栈多次刷新多次查看函数调用堆栈发现线程中一直有搜狗输入法IME - Input Method Editor输入法相关函数的调用函数所在模块名中有Ime和Sougou字样所以判断是搜狗输入法相关模块所以怀疑这个问题可能和搜索输入法有关。 软件界面卡顿应该是软件UI界面卡顿所以应该是UI主线程有问题。Process Explorer中看到的CPU占用高的线程应该就是UI主线程。可以用Windbg确认一下将Windbg附加到软件进程上使用~命令将进程中的所有线程信息都打印出来如下所示 在Windbg中UI主线层是0号线程将该0号线程的线程id进程id为16进制数与Process Explorer中显示的线程id进程id为十进制数比较一下就知道了。至于怎么比较也可以参看我之前写的文章
使用Process Explorer/Process Hacker和Windbg高效排查软件高CPU占用问题https://blog.csdn.net/chenlycly/article/details/134180480 后来让客户查看了一下其安装的搜狗输入法的版本是一个较老的版本让他安装最新版本的搜狗输入法安装后好像就没问题了。所以该问题应该是和输入法有关的
3、QQ拼音输入法注入到安装包进程中导致安装包主线程卡死问题 在某客户的电脑上会时不时出现启动我们的软件安装包后没反应启动起来后应该显示安装包界面的但一直看不到安装包界面到任务管理器中可以看到软件安装包进程说明程序已经启动了。 估计是安装包UI界面所在的UI主线程发生卡死了查看安装包进程的CPU占用很低所以能排除程序发生死循环的可能。很可能是UI线程与其他线程发生死锁了。
3.1、多线程死锁分析 导致线程发生卡死一般有两种原因 1代码中发生死循环导致函数一直没返回线程卡死 2代码一直卡在WaitForSingleObject等待锁的状态导致函数一直没返回线程卡死。这是多个线程之间使用锁发生死锁引发的。 于是将Windbg启动起来附加到出问题的安装包进程上然后使用~0s命令切换到UI主线程UI主线程是0号线程然后输入kn命令查看函数调用堆栈如下所示 从堆栈中可以看出当前线程卡在等待锁的WaitForSingleObject函数上一直没返回。可以多次go多次查看0号线程的函数调用堆栈每次都卡在WaitForSingleObject函数上。 此外沿着函数调用堆栈向上看是调用EnterCriticalSection接口去获取临界区对象触发了WaitForSingleObject函数的调用。说明当前发生死锁的是临界区锁。 当前确定是UI主线程发生死锁了那与之关联的死锁线程是哪个呢安装包程序比较简单进程中没几个线程使用~*kn命令将所有线程的函数调用堆栈都打印出来看到1号线程也卡在获取临界区锁的函数调用上 那基本可以确定是0号线程和1号线程发生死锁了 至于是不是这两个线程形成了死锁需要分析锁的信息具体分析方法我在此就不赘述了可以查看我之前写的文章
使用Process Explorer/Process Hacker和Windbg高效排查软件高CPU占用问题https://blog.csdn.net/chenlycly/article/details/134180480 此处也可以用《Windows核心编程》第9章源码中提供了一个叫LockCop的死锁检测工具当时使用该工具监测结果如下 该死锁检测工具是调用Windows API函数去检测的只能检测到部分对象的死锁无法监测到所有类型的死锁关于这个工具的详细说明可以查看《Windows核心编程》第9章使用等待链遍历API来检测死锁的内容。 关于多线程及多线程死锁相关内容可以参考我的文章
从C软件调试实战的角度去看多线程编程中的若干细节问题https://blog.csdn.net/chenlycly/article/details/134358655 从发生死锁的1号线程的调用堆栈来看看到了QQPinYin的模块名那说明这个线程是与QQ拼音输入法相关的。这就是说这个死锁是与QQ拼音相关的当时建议尝试两个办法一个是升级QQ拼音输入法的版本另一个是将QQ拼音输入法换成搜狗输入法。客户采用了后面这个方法将输入法换成搜狗输入法后就不再出现了。
3.2、进一步研究 对于0号线程是调用了API函数SHGetSpecialFolderLocation触发的死锁对于1号线程是调用API函数SHGetSpecialFolderPathW触发的死锁。这说明死锁发生在底层的Windows系统库中不在上层库中。这种情况很少遇到一般死锁都发生在上层的业务代码中。 这两个函数在两个线程中调用会发生死锁于是尝试到微软MSDN上查看这两个函数的说明。看到这两个函数都已经被微软废弃了如下所示 建议不要使用这两个函数了应该使用对应的替代函数。 为了保证代码的健壮性我们应该遵从微软官方的说明不再使用已经废弃的API函数。如果继续使用可能会产生一些无法预料、未知的结果。
4、安全软件注入到软件中注入模块发生了崩溃直接导致软件发生崩溃 几年前遇到的一个客户问题他们的Windows系统中安装了VPN软件注入到我们的进程中hook了网络通信的相关接口以监控软件的网络数据包的收发其中hook的recvfrom接口实现有bug我们代码中有处调用recvfrom接口的地方传入了两个NULL参数对于系统API函数recvfrom传入NULL值是允许的结果直接导致该注入模块产生了崩溃进而导致了我们软件的崩溃。 到MSDN上查看套接字API函数recvfrom的说明函数的最后两个参数是可选的可以不传入直接设置NULL就可以了如下所示 但客户VPN软件注入模块将系统的recvfrom函数hook成了他们实现的recvfrom函数在实现他们自己的recvfrom函数时直接访问了recvfrom最后的两个参数而我们的代码直接传入了NULL值 这样在他们的recvfrom内部访问了NULL指针触发了内存访问违例导致VPN软件的注入模块发生崩溃从而导致了我们整个程序的崩溃。 事实上这个问题的排查难度远比此处文字描述的复杂崩溃时的函数调用堆栈不完整看不到套接字函数recvfrom的调用 崩溃的注入库MinLSP.dll是第三方安全厂商的我们拿不到该库的pdb文件可能厂商也没有保存 当时是使用IDA反汇编工具查看汇编代码以及使用Windbg的dds命令找出recvfrom函数调用的限于篇幅这个地方就没有完全展开了 像这类出在第三方安全软件中的问题必须要拿出足够的证据证明问题是出在安全软件上客户才会认可排查的结论客户才会找第三方安全软件开发商反馈问题。对于本例中的问题我们有个临时的规避办法我们只要传入两个有效的参数即可当然在对应的代码中我们并不关心这两个参数在函数调用完成之后的返回值不再传入两个NULL参数。
5、安全软件注入到软件中注入模块发生了内存泄露直接导致软件内存耗尽后发生闪退 有个客户在某台机器上运行的我们的软件每次大概运行半个多小时后软件就会出现闪退崩溃问题基本是必现的。软件运行一段时间后发生闪退崩溃可能是内存泄漏引起的。有内存泄露的代码在频繁地执行泄露的内存越来越多接近或达到用户态虚拟内存的上限32位程序默认的用户态虚拟内存位2GB就会导致Out of memory内存耗尽的异常程序就会发生闪退崩溃。 于是让客户重新运行软件按照之前的操作步骤操作然后在Windows任务管理器中持续地观察软件进程占用的内存情况看看内存是否在持续地升高。之前我们讲过Windows任务管理器中看不到进程占用的用户态虚拟内存需要使用Process Explorer去查看。不过任务管理器中看内存的变化趋势是可以的也能看到内存在持续增长的。我们推荐使用Process Explorer工具去查看虚拟内存占用。 经观察软件中确实存在内存泄露大概半个小时后内存就耗完了。然后就是使用工具去分析内存泄露的模块及位置了。当时选择Windbg去检测内存泄露将Windbg附加到目标进程上去监测。至于如何使用Windbg去检测内存泄露此处就不再赘述了可以查看我的文章使用Windbg定位Windows C程序中的内存泄漏https://blog.csdn.net/chenlycly/article/details/121295720 经分析内存泄露发生在某个dll模块中然后查看该dll模块的路径发现是客户安装的某个安全软件的路径即该dll模块是某安全软件中的。安全软件中的模块怎么会跑到我们的软件进程空间中来的呢答案只有一个这个dll库是远程注入到我们的软件进程中的安全软件正是通过这个注入模块对我们的软件进行监控的。 这个问题应该和客户机器的系统环境有关如果是软件本身模块有内存泄漏应该在公司内部测试环境中就发现了因为半个小时左右就能复现在公司环境中不用专门长时间拷机就能复现。 我们给客户的结论是安全软件的注入模块有内存泄露需要客户联系安全软件的开发厂商去核实排查一下。但客户有些不认可我们的结论他们给出的理由是运行其他软件都没问题为啥运行我们的软件就有内存泄露呢后来将发生泄漏模块所属的安全软件卸载掉后我们的软件运行就没有泄露了所以基本确定泄露和这个安全软件有关客户才愿意承认可能是安全软件引起的。然后联系了安全软件厂商协调了他们的相关开发人员然后创建了讨论组。 经排查得知安全软件在拦截UDP数据包进行分析时有内存泄露而我们的软件在加入会议后源源不断的音音视频码流都是使用UDP传输的所以导致内存一直在持续的泄露然后内存很快就耗尽程序发生闪退了。 至于软件是如何实现远程注入的可以查看《Windows核心编程》一书中的第22章DLL注入与API拦截的内容。 6、最后 本文详细讲述了几个项目中遇到的远程注入对软件产生影响的问题实例有很强的实战参考价值希望能给大家提供一定的借鉴或参考。