在Windbg中设置断点追踪打开C++程序远程调试开关的模块
目录
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动态调试功能确实很有用,希望本文能给大家带来一定的启示和参考。
相关文章:
在Windbg中设置断点追踪打开C++程序远程调试开关的模块
目录 1、Windbg动态调试 2、在Windbg中设置断点 2.1、在函数入口处设置断点 2.2、在函数内部某一行上设置断点 3、设置断点跟踪对打开远程调试开关接口的调用 3.1、编写演示代码 3.2、在Windbg中设置调用SetRemoteDebugOn接口的断点进行跟踪 4、最后 VC常用功能开发汇总…...
CRM客户管理软件开发功能有哪些?
互联网技术的不断提高使得企业管理方式也发生了变化,企业CRM系统应用市场逐渐扩大,相关软件开发也引起越来越多商家企业的关注。因为企业CRM系统软件开发能够根据企业需求制作,帮助企业更好的追踪管理客户信息,实时更新并进行相关…...
C++函数式魔法之旅(Journey of Functional Magic)
C函数式魔法之旅(Journey of Functional Magic) 一、引言(Introduction)C Functional模板库简介(Overview of C Functional Template Library)Functional模板库的重要性和作用(The Importance a…...
Vue基础入门(上)
<script src"https://unpkg.com/vuenext"></script> 从面向dom编程到面向数据编程 输入显示列表 const appVue.createApp({data(){return{inputValue:,list:[]}},methods:{handleAddItem(){this.list.push(this.inputValue);this.inputValue;}},templ…...
字符串匹配—KMP算法
字符串匹配的应用非常广泛,例如在搜索引擎中,我们通过键入一些关键字就可以得到相关的搜索结果,搜索引擎在这个过程中就使用字符串匹配算法,它通过在资源中匹配关键字,最后给出符合条件的搜索结果。并且我们在使用计算…...
【微信小程序】 权限接口梳理以及代码实现
1、权限接口说明 官方权限说明 部分接口需要经过用户授权统一才能调用。我们把这些接口按使用范围分成多个scope,用户选择对scope进行授权,当授权给一个scope之后,其对应的所有接口都可以直接使用。 此类接口调用时: 如…...
【每日一词】leit-motif
1、释义 leit-motif: n. 主乐调;主题;主旨。 复数:leit-motifs 2、例句 Hence the ‘ancient’ rhyme that appears as the leit-motif of The Lord of the Rings, Three Rings for the Elven-Kings under the sky, Seven for the Dwarf-lor…...
windows 环境修改 Docker 存储目录
windows 环境修改存储目录 docker 安装时不提供指定安装路径和数据存储路径的选项,且默认是安装在C盘的。C盘比较小的,等docker运行久了,一大堆的东西放在上面容易导致磁盘爆掉。所以安装前可以做些准备,让安装的实际路径不在C盘&…...
上海市青少年算法月赛丙组—目录汇总
上海市青少年算法2023年3月月赛(丙组) T1 神奇的字母序列 T2 约数的分类 T3 循环播放 T4 数对的个数 T5 选取子段 上海市青少年算法2023年2月月赛(丙组) T1 格式改写 T2 倍数统计 T3 区间的并 T4 平分数字(一…...
手动实现promise.all
手动实现promise.all function promiseAll(promises) {return new Promise((resolve, reject) > {const results [];let count 0;promises.forEach((promise, index) > {Promise.resolve(promise).then(result > {results[index] result;count;if (count promise…...
如何搭建关键字驱动自动化测试框架?这绝对是全网天花板的教程
目录 1. 关键字驱动自动化测试介绍 2. 搭建关键字驱动自动化测试框架 步骤1:选择测试工具 步骤2:定义测试用例 步骤3:编写测试驱动引擎 步骤4:实现测试关键字库 步骤5:执行测试 3. 实现关键字驱动自动化测试的关…...
字符串反转操作
1:将字符串反转 给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。 输入格式: 测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母…...
TensorFlow 智能移动项目:1~5
原文:Intelligent mobile projects with TensorFlow 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 深度学习 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 不要担心自己的形象,只…...
[MAUI 项目实战] 手势控制音乐播放器(四):圆形进度条
文章目录 关于图形绘制创建自定义控件使用控件创建专辑封面项目地址 我们将绘制一个圆形的音乐播放控件,它包含一个圆形的进度条、专辑页面和播放按钮。 关于图形绘制 使用MAUI的绘制功能,需要Microsoft.Maui.Graphics库。 Microsoft.Maui.Graphics 是…...
web路径专题+会话技术
目录 自定义快捷键 1. 工程路径问题及解决方案1.1 相对路径1.2 相对路径缺点1.3 base标签1.4 作业11.5 作业21.6注意细节1.7 重定向作业1.8 web工程路径优化 2. Cookie技术2.1 Cookie简单示意图2.2 Cookie常用方法2.2 Cookie创建2.3 Cookie读取2.3.1 JSESSIONID2.3.2 读取指定C…...
Jetpack Compose 实战 宝可梦图鉴
文章目录 前言实现效果一、架构介绍二、一些的功能点的介绍加载图片并获取主色,再讲主色设置为背景一个进度缓慢增加的圆形进度条单Activity使用navigation跳转Compose可组合项返回时页面重组的问题hiltViewModel() 主要参考项目总结 前言 阅读本文需要一定compose基础&#x…...
高效时间管理日历 DHTMLX Event Calendar 2.0.3 Crack
DHTMLX Event Calendar用于高效时间管理的轻量级 JavaScript 事件日历 DHTMLX 可帮助您开发类似 Google 的 JavaScript 事件日历,以高效地组织约会。 用户可以通过拖放来管理事件,并以六种不同的模式显示它们。 JavaScript 事件日历功能 轻的简单的 Java…...
ASIC-WORLD Verilog(2)FPGA的设计流程
写在前面 在自己准备写一些简单的verilog教程之前,参考了许多资料----asic-world网站的这套verilog教程即是其一。这套教程写得极好,奈何没有中文,在下只好斗胆翻译过来(加了自己的理解)分享给大家。 这是网站原文&…...
数字化体验时代,企业如何做好内部知识数字化管理
随着数字化时代的到来,企业内部的知识管理也面临着新的挑战和机遇。数字化技术的应用,可以极大地提高企业内部知识的数字化管理效率和质量,从而提升企业内部的工作效率、员工满意度和企业竞争力。本文将从数字化时代的背景出发,探…...
Qt5.12實戰之Linux靜態庫與動態庫多文件生成a與so文件並調用
1.編輯並輸入內容到test.cpp與test2.cpp test.cpp #include <stdio.h> int func() {return 888; } test2.cpp #include <stdio.h> int func2() {return 999; } 將test.cpp與test2.cpp編譯成目標文件: g -c test.cpp test2.cpp 一次性生成目標文件…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...
【版本控制】GitHub Desktop 入门教程与开源协作全流程解析
目录 0 引言1 GitHub Desktop 入门教程1.1 安装与基础配置1.2 核心功能使用指南仓库管理日常开发流程分支管理 2 GitHub 开源协作流程详解2.1 Fork & Pull Request 模型2.2 完整协作流程步骤步骤 1: Fork(创建个人副本)步骤 2: Clone(克隆…...
C# WPF 左右布局实现学习笔记(1)
开发流程视频: https://www.youtube.com/watch?vCkHyDYeImjY&ab_channelC%23DesignPro Git源码: GitHub - CSharpDesignPro/Page-Navigation-using-MVVM: WPF - Page Navigation using MVVM 1. 新建工程 新建WPF应用(.NET Framework) 2.…...
