在Windbg中设置断点追踪打开软件远程调试开关的模块

目录

1、Windbg动态调试

2、在Windbg中设置断点

2.1、在函数入口处设置断点

2.2、在函数内部某一行上设置断点

3、设置断点跟踪对打开远程调试开关接口的调用

3.1、编写演示代码

3.2、在Windbg中设置调用SetRemoteDebugOn接口的断点进行跟踪

4、最后


VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具从入门到精通案例集锦(专栏文章正在更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html       最近在测试时发现,我们的软件在启动起来后会自动打开远程调试开关,而基于安全考虑,打开远程调试开关需要用户自己在设置中手动操作,不能自动打开。因为我们的软件模块有上百个dll库,涉及到多个开发组,无法确定到底是哪个模块自动打开的,后来想到可以使用Windbg动态调试设置断点去快速定位问题。本文详细讲述这一问题的排查过程。

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_perform+0x1D

       从下图也可以看出不同的汇编指令占的代码段内存的长度是不一样的:

注意,这个地方讲到的地址,都是代码段的地址,是二进制文件二进制代码(汇编代码)的地址。代码段的地址,要和数据段地址区分开来,变量占用的内存是数据段内存。   

       关于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函数调用的。如果有pdb,还能看到具体是函数中的哪一行代码调用的!

4、最后

       本例中通过在Windbg中设置断点,快速地定位出打开远程调试开关的模块及函数信息。Windbg动态调试功能确实很有用,希望本文能给大家带来一定的启示和参考。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/120589.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python tempfile模块:生成临时文件和临时目录

嗨喽~大家好呀,这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 tempfile 模块专门用于创建临时文件和临时目录,它既可以在 UNIX 平台上运行良好,也可以在 Windows 平台上运行良好。 tempfile 模块中常用…

idea Springboot 图书管理系统VS开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot 图书管理系统是一套完善的信息系统,结合springboot框架和bootstrap完成本系统,对理解JSP java编程开发语言有帮助系统采用springboot框架(MVC模式开发),系统具有完整的源代码和数据库&#…

react create-react-app v5配置 px2rem (暴露 eject方式)

环境信息: create-react-app v5 “react”: “^18.2.0” “postcss-plugin-px2rem”: “^0.8.1” 配置步骤: 我这个方式是 npm run eject 暴露 webpack配置的方法 1.安装 postcss-plugin-px2rem 和 lib-flexible cnpm install postcss-plugin-px2rem…

在MySQL中使用VARCHAR字段进行日期筛选

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…

V4L2 驱动架构介绍

V4L2 简介 Video for Linux two(Video4Linux2)简称 V4L2,是 V4L 的改进版。V4L2 是 linux操作系统下用于视频和音频数据采集设备的驱动框架,为驱动和应用程序提供了一套统一的接口规范。 在 Linux 下,所有外设都被看成一种特殊的文件&#xf…

sentinel-dashboard-1.8.0.jar开机自启动脚本

启动阿里巴巴的流控组件控制面板需要运行一个jar包,通常需要运行如下命令: java -server -Xms4G -Xmx4G -Dserver.port8080 -Dcsp.sentinel.dashboard.server127.0.0.1:8080 -Dproject.namesentinel-dashboard -jar sentinel-dashboard-1.8.0.jar &…

从Matrix-ResourceCanary看内存泄漏监控

不同于LeakCanary,在Matrix中,主要是通过Resource Canary来监控内存泄漏问题的,且监听的泄漏对象只支持Activity,官方说明如下: 结合分析LeakCanary的经验可知,要实现Activity内存泄漏监听,总体…

Unity实现设计模式——中介者模式

Unity实现设计模式——中介者模式 用一个中介者对象来封装一系列的对象交互,中介者使各对象不需要显示地相互引用,从而使其松散耦合,而且可以独立地改变它们之间的交互。 这里使用一个生活中的例子来介绍中介者模式,比如当我们在…

Linux系统如何将新硬盘挂载到Home目录下

Linux系统如果将硬盘挂载到Home目录下 目录 1、对新增磁盘进行分区 2、分区格式化 3、将新硬盘临时挂载在一个目录下

《Reinforcement Learning: An Introduction》第8章笔记

文章目录 Chapter 8 Planning and Learning with Tabular Methods8.1 Models and Planning8.2 Dyna: Integrated Planning, Acting, and Learning8.3 When the Models Is Wrong8.4 Prioritized Sweeping8.5 Expected vs. Sample Updates8.6 Trajectory Sampling8.7 Real-time D…

EasyWindow - Android 悬浮窗框架

官网 https://github.com/getActivity/EasyWindow 项目介绍 本框架意在解决一些极端需求,如果是普通的 Toast 封装推荐使用 Toaster 集成步骤 如果你的项目 Gradle 配置是在 7.0 以下,需要在 build.gradle 文件中加入 allprojects {repositories {/…

SR800-D 5G工业路由器:将无人驾驶汽车的通信能力提升到极限

​大家好!欢迎来到今天星创易联的课堂,我是你们的通信老师,今天我们将讨论无人驾驶解决方案,其中包括SR800-D 5G工业路由器的运用。 首先,让我们聚焦于无人驾驶技术的重要性。无人驾驶汽车正在迅速崛起,这种…