在Windbg中设置断点追踪打开C++程序远程调试开关的模块

news2024/12/23 14:43:19

目录

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?spm=1001.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_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函数调用的。

4、最后

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

这一次,吃了Redis的亏,也败给了GPT

关注【离心计划】,一起离开地球表面 背景 组内有一个系统中有一个延迟任务的需求,关于延迟任务常见的做法有时间轮、延迟MQ还有Redis Zset等方案,关于时间轮,这边小苏有一个大学时候做的demo: https://github.com/JA…

Cacti监控远程linux机器配置(被监控端)

一、被监控机安装snmp yum -y install snmp二、被监控机的配置 vi /etc/snmp/snmpd.conf做以下更改: 1、找到com2sec notConfigUser default public 改为:com2sec notConfigUser 192.168.1.1(改成监控服务器的ip) public 2、找到acce…

【hello Linux】进程概念(上)

目录 1.操作系统(OS) 2. 进程 2.1 基本概念 2.2 task_struct 内的属性字段 2.3 查看进程 2.4 查看进程的PID及PPID 2.5 杀死进程 2.6 以文件的方式查看进程 2.7 查看退出码 2.8 上下文数据 下面介绍两个较为方便的快捷键: Linux🌷…

语义分割新范式:上海 AI Lab 联合北邮、商汤提出StructToken

来源:投稿 作者:xin 编辑:学姐 Motivation 本文将当前语义分割的方法分为两类,一类是静态逐像素分类方法(static per-pixel classification),另一类为动态逐像素分类方法(dynamic p…

Ubuntu备份与恢复

Ref: create-backup-image-of-running-ubuntu Linux中我们有权访问所有系统文件,因此,最简单且直接的备份方法是将整个根目录打包: sudo su tar -cpzf /path/to/backup.tar.gz --exclude/tmp --one-file-system /其中-cpzf 表示建立压缩归档…

MQTT 持久会话与 Clean Session

1. 会话(session) 我们将从客户端向服务端发起 MQTT 连接请求开始,到连接中断直到会话过期为止的消息收发序列称之为会话。会话是服务端和客户端的一个连接,进行消息交互前必须先建立会话。 2. 会话的生命周期 MQTT v3.1.1会话…

003_螺旋矩阵

力扣54和59题 54.顺时针打印矩阵 题目: 思路:将矩阵分为若干层,首先打印最外层的元素,然后一直往里打印 对于每层,从左上方开始以顺时针的顺序遍历所有元素。假设当前层的左上角位于(top,left),右下角位于…

Axios请求(对于ajax的二次封装)——Axios取消请求、请求体编码

Axios请求(对于ajax的二次封装)——Axios取消请求、请求体编码知识回调(不懂就看这儿!)场景复现核心干货axios取消请求AbortControllerCancelToken deprecated请求体编码浏览器qs库编码数据ES6库方法node.jsQuery stri…

【神经网络】tensorflow实验3--NumPy科学计算库

目录 1. 实验目的 2. 实验内容 3. 实验过程 题目一: ① 代码 ② 实验结果 题目二: ① 代码 ② 实验结果 题目三: ​编辑 ① 代码 ② 实验结果 5. 实验小结 ① 实验过程中遇到了哪些问题,你是如何解决的? …

Android引入Apollo(阿波罗)

程序猿日常 记Android项目引入Apollo(阿波罗)上源码 apollo开发分支 应用 Apollo(阿波罗)客户端会管理好应用的后台GraphQL数据 之前网络请求使用RetrofitOkHttp 改成使用ApolloOkHttp 引入 1.对应的module的build.gradle中添加 id("com.apollographql.apollo3&qu…

【计算机系统概论Yale.patt】第一章

文章目录1. 计算机是简单部件的系统组合1.1 计算机组成1.1.1 编码体系1.1.2 晶体管构建微处理器1.1.3 冯诺依曼机1.1.4 LC-3机(冯诺依曼机实现)1.1.5 LC-3编程机器语言编程汇编语言编程输入输出信息问题两个重要机制栈和数据转换示例:计算器1.2 两个重要理念1.2.1 抽…

Linux基础篇(三)常见指令

目录 一、创建文件和目录 二、命令详解 0. 命令和选项 1. ls命令 2. cd命令 3. touch命令 4. mkdir命令 5. tree命令 6. rmdir命令 7. rm命令 8. man 9. nano 10. cat命令 11. cp 命令 12. mv 命令 13. echo命令 14. more命令 15. less命令 16. Ctrl C 17. head 命令 18. tail…

台灯的种类有哪些?国内热门护眼灯品牌推荐

台灯是我们日常生活中常见的电器之一,台灯不仅可以为人们照明,还可以用来家居装饰,根据人们不用的需求,台灯的种类也很多,有书房台灯、读写台灯、工艺台灯。 书房台灯:灯光的局部照明效果,以书写…

禅道OpenAI更新至1.2版本,超多实用功能惊喜上线!

广受欢迎的禅道OpenAI插件近日成功发布,截至目前已更新至1.2版本。 截至本版本发布,禅道OpenAI已经拥有了神奇海螺(ChatGPT聊天)、需求润色、任务润色、Bug润色及本次的需求一键生成用例功能,仍有更多实用的新功能正在…

Sentinel 工作主流程

Overview 在 Sentinel 里面,所有的资源都对应一个资源名称以及一个 Entry。Entry 可以通过对主流框架的适配自动创建,也可以通过注解的方式或调用 API 显式创建;每一个 Entry 创建的时候,同时也会创建一系列功能插槽(…

2023年第1季社区Task挑战赛开启,等你来战!

社区Task挑战赛是面向社区开发者开展的代码或教程征集活动。该挑战赛为社区中热爱FISCO BCOS及周边组件的开发者提供了探索区块链技术、挑战技术难题的舞台。该挑战赛去年在社区成功举办了3季,共吸引了数百名开发者报名。 前3季都有哪些有趣的作品? 在…

【图数据挖掘】— 子图同构问题、单射函数和双射函数、同构(isomorphic)和同态(homomorphism)

子图同构问题 子图同构(Subgraph Isomorphism)是指在图论中,两个图之间是否存在一种关系,使得其中一个图的顶点集合和边集合可以通过对应的方式映射到另一个图的顶点集合和边集合上,且保持原来的边和顶点的关系不变。…

如何设计一个安全的对外接口?

对外接口安全措施的作用主要体现在两个方面,一方面是如何保证数据在传输过程中的安全性,另一方面是数据已经到达服务器端,服务器端如何识别数据。 1. 数据加密 数据在传输过程中是很容易被抓包的,如果直接传输,数据可…

elasticsearch 核心概念

1.近实时(Near Real Time,NRT) elasticsearch 是一个近实时的搜索和分析平台,这意味着从索引文档到可搜索文档都会有一段微小的延迟(通常是1s以内)。这种延迟主要是因为 elasticsearch 需要进行数据刷新和索引更新。 …

远程代码执行渗透与防御

远程代码执行渗透与防御1.简介2.PHP RCE常见函数3.靶场练习4.防御姿势1.简介 远程代码执行漏洞又叫命令注入漏洞 命令注入是一种攻击,其目标是通过易受攻击的应用程序在主机操作系统上执行任意命令。 当应用程序将不安全的用户提供的数据(表单、cookie…