当前位置: 首页 > news >正文

使用反汇编工具IDA查看发生异常的汇编代码的上下文去辅助分析C++软件异常

目录

1、概述

2、如何使用IDA打开并查看二进制文件的汇编代码

3、在IDA中找到发生崩溃的那条汇编指令的位置

3.1、如何在IDA中找到发生异常的那条汇编指令

3.2、示例

4、阅读汇编代码上下文需要掌握一定的基础汇编知识

5、最后


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       在分析C++软件异常崩溃时,可能需要使用IDA工具去查看exe或dll二进制文件的汇编代码去辅助定位问题。今天我们就来讨论一下使用IDA工具去查看汇编代码相关细节问题。

1、概述

       我们使用Windbg打开dump文件分析异常时,会先去查看发生崩溃的汇编指令及相关寄存器中的值,然后查看异常所在线程的函数调用堆栈,必要时查看函数调用堆栈中的函数中的局部变量或者C++类对象中的数据成员变量的值去辅助分析。

       但在少部分场景下,通过上述分析并不能最终定位问题,需要使用IDA去查看汇编代码的上下文,结合C++源代码去做进一步分析的。比如下面的两个场景就需要去查看汇编代码上下文去辅助分析:

1)Windbg中显示的函数调用堆栈中的C++代码行号,和最新的代码对不上了

       发生异常崩溃的软件版本可能是几个月或者几年之前的,Windbg中显示的行号是很早之前的cpp文件代码了,最新的cpp文件代码相对这个出问题的版本做了很多修改,所以行号和最新的代码完全对不上了。这时候就需要使用IDA去查看发生异常的模块的汇编代码上下文了,看看到底是那一行代码引起的,一般还是要和最新的代码对比着看,看看最新的代码中哪一行代码。

2)Windbg中指示的发生崩溃的C++代码行上有多个函数调用,很难直接判断是哪个函数调用出问题了

        Windbg中指示的发生崩溃的C++代码行上有多个函数调用(比如if语句中有多个条件的组合判断),很难直接判断是哪个函数调用出问题了,可以查看汇编代码去确定到底是哪个函数调用出的问题,比如如下的if条件判断语句:

if (pContainer->IsVisible() && GetTargetImplPtr()->IsReady() && pDataProcImpl->IsBuildFinish)
{// 代码省略
}

       关于使用IDA查看汇编代码去辅助排查C++软件异常的详细理论说明,可以参见之前写的一篇文章:
使用IDA查看汇编代码上下文去辅助排查C++软件异常问题https://blog.csdn.net/chenlycly/article/details/128942626https://blog.csdn.net/chenlycly/article/details/128942626

2、如何使用IDA打开并查看二进制文件的汇编代码

       IDA安装完成后,双击启动程序,会弹出如下的提示框:

点击“New”即新建一个对象。紧接着弹出让选择要打开的文件:

可以找到目标文件的路径,打开目标文件即可。也可以点击取消,然后直接将文件拖到IDA中。打开文件时会让选择加载文件的方式:

对于Windows版本的二进制号文件,使用的都是PE文件格式,选择默认的PE方式即可。

       接下来会弹出是否要加载pdb文件的提示框:

选择Yes。此处需要注意一下,我们需要事先将pdb文件放置到目标二进制文件的同一级目录中,这样IDA在打开二进制文件时就会搜索到对应的pdb文件并加载pdb文件。有了pdb文件中符号,IDA打开的汇编代码中就会显示具体函数名和变量标识,以及大量注释信息。

       打开二进制文件后,默认显示的Graph view视图模式(显示各个代码模块的关系),如下:

需要点击右键,在弹出的右键菜单中点击Text view视图模式,切换到汇编源码模式。

       我们可以跳转到指定的函数中,点击菜单栏的Jump-->Jump o function:

弹出包含当前模块所有函数的列表,点击窗口下方的Search按钮:

直接输入要查看的目标函数的名称,搜索到目标函数后双击条目,即会跳转到目标函数的汇编代码处:

也可以按下快捷键g,直接跳转到指定地址的汇编代码行:

3、在IDA中找到发生崩溃的那条汇编指令的位置

       在Windbg中可以看到发生异常的那条汇编指令,以及这条汇编指令所在的模块,然后找到模块对应的二进制文件,用IDA打开二进制文件,就可以查看模块的汇编代码了。

3.1、如何在IDA中找到发生异常的那条汇编指令

       Windbg中可以看到发生异常汇编指令的地址(代码段地址),通过该指令的地址,可以到IDA打开的汇编代码中找到对应的位置,然后查看该位置的汇编指令的上下文,对照着C++源码,就可以进一步地去分析问题了。

       Windbg中显示的发生异常的汇编指令的地址,是主程序运行起来之后的实际地址,和IDA中显示的静态默认地址是不同的。主程序启动时,会先将其依赖的各个dll模块加载到进程空间中,给各个模块分配代码段地址,这样每个模块中的汇编指令就有了运行时的实际代码段地址了。
这个地方需要区分一下代码段地址和数据段地址:

代码中定义的变量的内存是在数据段内存上分配的,变量的内存地址都是数据段的地址。二进制代码(汇编代码)指令的地址,是代码段地址。

       发生异常的汇编指令在实际运行的地址,虽然和IDA中显示的静态默认地址是不同的,但该条汇编指令相对于所在模块的位置是固定的,即汇编指令相对于所在模块的地址偏移始终是固定的。可以在Windbg中计算出发生异常的那条汇编指令相对所在模块偏移,然后将这个偏移加上IDA中显示的模块默认起始地址,就得出该条汇编指令在IDA中的地址了,然后Go到这个地址,就可以看到发生崩溃的那条汇编指令了。

3.2、示例

       下面我们通过一个具体的实例来讲解如何在IDA打开的模块汇编代码中找到发生异常的那条汇编指令。我故意写了一段会引发异常的测试代码如下:

SHELLEXECUTEINFO* pInfo = NULL;CString strTip;
strTip.Format(_T("cbSize: %d"), pInfo->cbSize );::MessageBox( NULL, strTip, _T("提示"), MB_OK);

代码中定义了一个结构体指针变量pInfo,初始化为空(NULL),然后没有给该指针赋一个有效的结构体地址,直接用这个空指针去访问结构体中的成员cbSize,所以访问了一个地址很小的内存,所以触发了内存访问违例。

       程序运行上述代码时会产生崩溃,生成dump文件。用Windbg打开dump文件,并在Windbg中配置程序的pdb文件路径,打开后即看到发生异常崩溃的那条汇编指令及当时各个寄存器中的值,并看到发生的异常Code码及异常类型,如下所示:

首先,从上图可以看出,发生的是Access violation内存访问违例的异常。然后看到发生异常的那条汇编指令mov ecx,dword ptr [eax](指令的地址为0x00eb3787),并且这条指令位于TestDlg模块的函数CTestDlgDlg::OnBnClickedButton1中。

       接下来我们就来演示一下如何在IDA中找到发生异常的这条汇编指令的位置。发生异常的汇编指令位于TestDlg模块中,于是用IDA打开TestDlg.exe二进制文件,看到该模块的汇编代码。我们先计算出发生异常的汇编指令相对其所在模块的偏移。发生异常的汇编指令的地址为0x00eb3787,用lm命令查看其所在模块TestDlg的起始地址(代码段地址),如下:

TestDlg模块的起始地址为0x00ea0000,所以发生异常的那条汇编指令相对所在模块TestDlg起始地址的偏移为:

0x00eb3787 - 0x00ea0000

然后我们到IDA中,将鼠标拉到汇编代码的最上面,看IDA显示的TestDlg模块静态默认起始地址,如下:

TestDlg模块静态默认起始地址为0x400000,该模块中所有汇编指令的地址都是在此基础值上展开的。所以,发生异常的那条汇编指令在IDA中显示的地址为:

0x00eb3787 - 0x00ea0000 + 0x00400000 = 0x00413787

然后按下g快捷键,在弹出的搜索框中输入413787,点击确定,就Go到发生异常的那条汇编指令的位置了,如下:

这样我们就能查看这条发生异常的汇编指令的上下文,结合IDA中的注释及C++源码,就能对问题进行进一步分析了。

4、阅读汇编代码上下文需要掌握一定的基础汇编知识

       要去阅读汇编代码的上下文,是需要掌握一定的汇编基础知识的,比如了解一些常用寄存器的用途、熟悉一些常用的汇编指令、了解函数调用时的栈分布、了解C++虚函数调用的汇编代码实现(虚函数调用时的二次寻址)等。这里简单的提一下常用寄存器的用途:

在X86汇编指令中,EAX主要用于存放函数调用的返回值;在调用C++成员函数时会使用ECX寄存器用来传递C++对象地址;ESI是源地址寄存器,EDI是目的地址寄存器,主要用于内存拷贝的串操作指令中,比如memcpy的汇编实现中。

       关于分析C++软件异常需要掌握的基础汇编知识,这里就不再赘述了,可以参见我之前写的文章:

分析C++软件异常需要掌握的汇编知识汇总https://blog.csdn.net/chenlycly/article/details/124758670https://blog.csdn.net/chenlycly/article/details/124758670

5、最后

       直接去阅读汇编代码难度是比较大的,除非有很强的汇编语言功底与反汇编的能力。在实际工作中,我们一般是将汇编代码,与C++代码对照着阅读,同时结合着汇编代码上下文中的注释去辅助查看,这比单纯地去直接阅读汇编代码要容易很多。此外,编译器在Release下会对代码进行大量的优化,被优化的C++代码很难和优化后生成的汇编代码完全一一对应起来,这点需要注意一下。

       我们在分析C++软件异常问题时,只是简单地使用IDA工具,用IDA打开exe或dll二进制文件查看文件中的汇编代码(IDA会将二进制文件中的二进制机器码反汇编出汇编代码),以辅助分析问题。本文并没有详细讲述IDA工具的功能,感兴趣的朋友,可以去阅读一下IDA经典书籍《IDA Pro权威指南》。

二进制机器码,汇编代码等价于二进制机器码,汇编代码是二进制机器码的助记符,汇编代码的可读性很强。在CPU中执行的是二进制机器码,等同于执行的就是汇编代码,通过查看汇编代码可以看出程序的具体执行细节。

相关文章:

使用反汇编工具IDA查看发生异常的汇编代码的上下文去辅助分析C++软件异常

目录 1、概述 2、如何使用IDA打开并查看二进制文件的汇编代码 3、在IDA中找到发生崩溃的那条汇编指令的位置 3.1、如何在IDA中找到发生异常的那条汇编指令 3.2、示例 4、阅读汇编代码上下文需要掌握一定的基础汇编知识 5、最后 VC常用功能开发汇总(专栏文章列…...

怎么合并多个视频?简单视频合并方法分享

合并多个视频可以将它们组合成一个更长的视频,这对于需要播放多个短视频的情况非常有用。此外,合并视频还可以使视频编辑过程更加高效,因为不必将多个独立的视频文件分别处理。最后,合并视频可以减少文件数量,从而使整…...

webpack基础知识九:如何提高webpack的构建速度?

一、背景 随着我们的项目涉及到页面越来越多,功能和业务代码也会随着越多,相应的 webpack 的构建时间也会越来越久 构建时间与我们日常开发效率密切相关,当我们本地开发启动 devServer 或者 build 的时候,如果时间过长&#xff…...

批量改名字序号和前缀

echo off setlocal enabledelayedexpansion set count10 for /f %%i in (dir /b *.jpg,*.png,*.bmp,*.jpeg,*.gif) do ( set /a count1 echo %%i 前缀_!count! rename %%i 前缀_!count!.png ) REM …...

基于Spring Boot的医院预约挂号网站设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频: 基于Spring Boot的医院预约挂号网站设计与实现(Javaspring bootMySQL) 使用技术: 前端:html css javascript jQuery ajax thymeleaf 微信小程序 后端:Java spring…...

Linux命令200例:join将两个文件按照指定的键连接起来分析

🏆作者简介,黑夜开发者,全栈领域新星创作者✌。CSDN专家博主,阿里云社区专家博主,2023年6月csdn上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 &…...

谈谈网络安全

目录 1.概念 2.发展现状 3.主要问题 1.概念 网络安全是指保护计算机网络和其中的数据免受未经授权访问、损坏、窃取或破坏的过程和技术。网络安全涉及预防和检测潜在的威胁和漏洞,并采取措施保护网络的机密性、完整性和可用性。 网络安全的概念包括以下几个方面&am…...

机器学习深度学习——文本预处理

👨‍🎓作者简介:一位即将上大四,正专攻机器学习的保研er 🌌上期文章:机器学习&&深度学习——序列模型(NLP启动!) 📚订阅专栏:机器学习&am…...

Qt实现可伸缩的侧边工具栏(鼠标悬浮控制伸缩栏)

Qt实现可伸缩的侧边工具栏 一直在网上找,发现大多的实现方案都是用一个按钮,按下控制侧边栏的伸缩,但是我想要实现鼠标悬浮在侧边栏的时候就伸出,移开就收缩的功能,也没找到好的参考,所以决定自己实现一个…...

【Spring Boot】拦截器与统一功能处理

博主简介:想进大厂的打工人博主主页:xyk:所属专栏: JavaEE进阶 上一篇文章我们讲解了Spring AOP是一个基于面向切面编程的框架,用于将某方面具体问题集中处理,通过代理对象来进行传递,但使用原生Spring AOP实现统一的…...

RabbitMQ的6种工作模式

RabbitMQ的6种工作模式 官方文档: http://www.rabbitmq.com/ https://www.rabbitmq.com/getstarted.html RabbitMQ 常见的 6 种工作模式: 1、simple简单模式 1)、消息产生后将消息放入队列。 2)、消息的消费者监听消息队列,如果队列中…...

MFC第二十六天 CRgn类简介与开发、封装CMemoryDC类并应用开发

文章目录 CRgn类简介与开发CRgn类简介CRgn类区域管理开发CRgn类区域管理与不规则形状的选取 封装CMemoryDC类并应用开发CMemoryDC.h封装CMemoryDC开发游戏透明动画CFlashDlg.hCFlashDlg.cpp 封装CMemoryDC开发游戏动画 附录四大窗口CDC派生类 CRgn类简介与开发 CRgn类简介 CR…...

解决VScode远程服务器时opencv和matplotlib无法直接显示图像的问题

解决VScode远程服务器时opencv和matplotlib无法直接显示图像的问题 1、本方案默认本地已经安装了VScode与MobaXterm2、在服务器端3、在本地端安装MobaXterm4、测试5、opencv显示测试(测试过程中需保持MobaXterm开启的状态)6、 matplotlib显示测试&#x…...

支付模块功能实现(小兔鲜儿)【Vue3】

支付 渲染基础数据 支付页有俩个关键数据,一个是要支付的钱数,一个是倒计时数据(超时不支付商品释放) 准备接口 import request from /utils/httpexport const getOrderAPI (id) > {return request({url: /member/order/$…...

php meilisearch demo

# 创建一个meilisearch 使用完自动销毁 docker run -itd --rm -p 7700:7700 getmeili/meilisearch:v1.3docker-compose 参数 version: "3" networks:flyserver:driver: bridge services:search:image: getmeili/meilisearch:v1.3restart: alwaysenvironment:- MEILI…...

芒格之道——查理·芒格股东会讲话1987-2022

你越是认真生活,你的生活就会越美好! 这里将读书过程划线的内容摘抄在这里,方便自己回顾。 书分为两部分,我先读了后半部分,而且是从后往前读,到了前半部分,我是从前往后读。书还挺贵&#xff…...

如何运营手游联运平台游戏?

运营手游联运平台游戏需要综合考虑多个方面,包括游戏选择、合作伙伴、市场推广、用户运营等。以下是运营手游联运平台游戏的一些建议: 游戏选择:选择优质的手游,确保游戏的品质和内容能够吸引玩家,满足市场需求。 合…...

vscode连接远程Linux服务器

文章目录 一、环境安装1.1 下载vscode1.2 下载vscode-sever 二、ssh链接2.1 安装Remote-SSH2.2 设置vscode ssh2.3 设置免密登录2.3.1 本地生成公私钥2.3.2 服务器端添加公钥 三、安装插件3.1 vscode安装插件3.1.1 在线安装插件3.1.2.1 下载插件3.1.2.2 安装插件 3.2 vscode-se…...

numpy 转换成 cupy 利用GPU执行 错误

ModuleNotFoundError: No module named cupy._core. routines_sorting 提示缺少包 使用 pyinstaller -D views.py --nocons 可以正常打包出来 但是运行出现报错 说明这个打包工具 忽略了很多 隐式导入的包 解决方法很简单 hiddenimports [fastrlock, fastrlock.rlock, cu…...

力扣:55. 跳跃游戏(Python3)

题目: 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标。 来源:力扣(LeetCode) 链接:力扣 示例&#xf…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

归并排序:分治思想的高效排序

目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法&#xff0c;由约翰冯诺伊曼在1945年提出。其核心思想包括&#xff1a; 分割(Divide)&#xff1a;将待排序数组递归地分成两个子…...

跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践

在电商行业蓬勃发展的当下&#xff0c;多平台运营已成为众多商家的必然选择。然而&#xff0c;不同电商平台在商品数据接口方面存在差异&#xff0c;导致商家在跨平台运营时面临诸多挑战&#xff0c;如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...