建设金融网站哪家好,手工制作方法,挂机宝做网站,拍卖 网站 建设目录
1、Windbg动态调试
2、在Windbg中设置断点
2.1、在函数入口处设置断点
2.2、在函数内部某一行上设置断点
3、设置断点跟踪对打开远程调试开关接口的调用
3.1、编写演示代码
3.2、在Windbg中设置调用SetRemoteDebugOn接口的断点进行跟踪
4、最后 VC常用功能开发汇总…目录
1、Windbg动态调试
2、在Windbg中设置断点
2.1、在函数入口处设置断点
2.2、在函数内部某一行上设置断点
3、设置断点跟踪对打开远程调试开关接口的调用
3.1、编写演示代码
3.2、在Windbg中设置调用SetRemoteDebugOn接口的断点进行跟踪
4、最后 VC常用功能开发汇总专栏文章列表欢迎订阅持续更新...https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程专栏文章列表欢迎订阅持续更新...https://blog.csdn.net/chenlycly/article/details/125529931C软件分析工具案例集锦正在更新中https://blog.csdn.net/chenlycly/category_12279968.html?spm1001.2014.3001.5482 最近在测试时发现我们的软件在启动起来后就自动打开了远程调试开关而基于安全考虑打开远程调试开关需要用户自己在设置中手动操作的不能自动打开。因为我们的软件模块有上百个dll库涉及到多个开发组无法确定到底是哪个模块自动打开的后来想到可以使用Winddbg动态调试设置断点去快速定位问题。本文详细讲述这一问题的排查过程。
1、Windbg动态调试 一般在排查C软件异常问题时如果有包含异常上下文的dump文件我们优先使用Windbg打开dump文件去进行静态分析。如果发生异常时没有生成dump文件则将Windbg附加到目标进程上或者使用Windbg启动目标程序进行动态调试。 Windbg主要用来分析C软件异常的除此之外还可以在动态调试时帮我们辅助定位问题。我们可以在动态调试的Windbg中设置断点设置代码段的地址去对程序的运行轨迹进行跟踪。本案例中正是通过在Windbg中设置断点定位问题的。 使用Windbg进行动态调试有两种方式 1直接将Windbg附加到已经运行起来的目标进程上。点击菜单栏中的File-Attach to a Process...。 2可以直接使用Windbg启动目标程序。点击菜单栏中的File-Open Executabe...。如果问题出在程序启动的过程中则使用此种方式。 本项目问题中自动打开远程调试开关的操作应该是在程序启动时执行的所以我们要用Windbg去启动程序的方式。
2、在Windbg中设置断点 可以使用bp命令设置断点可以在函数入口处设置断点也可以在函数内部设置断点。在函数内部某一行设置断点可以查看到中断时函数中局部变量的值变量的值可能是排查问题的重要线索。
2.1、在函数入口处设置断点 在函数入口处设置断点直接使用函数名就可以了函数名就是函数在代码段的首地址。以netdll.dll库中的SetRemoteDebugOn函数为例设置断点的命令为 bp netdll!SetRemoteDebugOn 其中netdll就是所在dll库名称不带.dll后缀SetRemoteDebugOn就是函数名。 此处的SetRemoteDebugOn函数是netdll.dll库的导出函数函数的符号是对外公开的无需pdb符号库文件。如果要设置的函数是dll库内部的函数非dll库的导出函数则需要将库的pdb文件设置到Windbg中因为内部函数需要pdb文件中的函数符号否则Windbg没法识别。
2.2、在函数内部某一行上设置断点 此处说的函数内部的某一行不是C源码的某一行二是二进制文件中汇编代码的某一行。因为程序最终运行的是二进制文件执行的是二进制文件中的二进制代码与汇编代码等价的汇编代码是二进制代码的助记符。 其实就是在所在函数函数就是函数在代码段的首地址基础上加上一个offset偏移值。但这个偏移值不是随意写的需要使用IDA打开二进制文件查看汇编代码去确定。因为不同的汇编指令其长度也是不一样的只能设置汇编指令的地址不能设置两条汇编指令地址中间的地址值否则会无效不会命中断点。 以开源库libcurl.dll为例我们使用IDA Pro打开该库文件查看反汇编出来的汇编代码找到该库的内部函数easy_perform在该函数中的10007D2D行设置断点如图所示 要在IDA中看到库内部函数的符号需要将pdb文件拿过来放到libcurl.dll同级目录中IDA回去自动加载。关于如何使用IDA反汇编工具可以查看我之前写的文章
IDA反汇编工具使用详解https://blog.csdn.net/chenlycly/article/details/120635120 要在指定的10007D2D行设置断点需要计算这行汇编指令相对所在函数的偏移 0x10007D2D - 0x10007D10 0x1D 所以设置断点的WIndbg命令为 bp libcurl!easy_perform0x1D 从下图也可以看出不同的汇编指令占的代码段内存的长度是不一样的 注意这个地方讲到的地址都是代码段的地址是二进制文件二进制代码汇编代码占用的地址。代码段的地址要和数据段地址区分开来变量占用的内存是数据段内存。关于C程序的内存分区可以查看之前的文章实例详解C程序的五大内存分区https://blog.csdn.net/chenlycly/article/details/120958761 此外我们要说一下了解汇编代码的重要性从此处我们也能看到出一点端倪。熟悉汇编代码不仅可以辅助排查C程序问题还可以理解高级语言无法理解的编程细节或代码执行细节的问题。如果要了解排查C软件问题所需要掌握的汇编基础知识可以查看我之前写的文章分析C软件异常需要掌握的汇编知识汇总https://blog.csdn.net/chenlycly/article/details/124758670
3、设置断点跟踪对打开远程调试开关接口的调用 为了跟踪是哪个模块自动打开远程调试开关只要拿来底层库用来打开远程调试的函数名称及所在的模块名就可以在动态调试的Windbg中设置断点进行跟踪了。 此处不便展示项目中的相关模块和接口也为了方便日后的视频课程的讲解我特意写了一些测试代码来讲述整个问题的跟踪过程。
3.1、编写演示代码 使用Visual Studio创建了一个MFC主程序TestDlg.exe以及一个包含打开远程调试接口SetRemoteDebugOn的netdll.dll动态库。在TestDlg.exe主程序的Test按钮的响应函数中调用netdll.dll库中的用于打开远程调试的API接口SetRemoteDebugOn。 动态库netdll.dll中API接口SetRemoteDebugOn定义如下 主程序TestDlg.exe中的Test按钮的响应函数调用SetRemoteDebugOn的代码如下 3.2、在Windbg中设置调用SetRemoteDebugOn接口的断点进行跟踪 使用Windbg启动TestDlg.exe使用Windbg动态调试。因为最终调用的是netdll.dll模块中的SetRemoteDebugOn接口去打开远程调试开关所以只要对SetRemoteDebugOn接口入口处设置断点就可以了即bp netdll!SetRemoteDebugOn如下所示 我们使用bl命令查看当前断点列表如上所示。 然后点击TestDlg.exe程序窗口中的Test按钮 在按钮的响应函数中调用SetRemoteDebugOn接口这样就命中了刚才设置的断点Windbg中断下来使用kn命令查看此时的函数调用堆栈 我们就知道是哪个模块调用了SetRemoteDebugOn接口将远程调试关闭了。从上图可以看出TestDlg.exe模块调用了打开远程调试开关的接口并且还能看到是TestDlg.exe模块中的CTestDlgDlg::OnBnClickedTest函数调用的。
4、最后 本例中通过在Windbg中设置断点快速地定位出打开远程调试开关的模块及函数信息Windbg动态调试功能确实很有用希望本文能给大家带来一定的启示和参考。