每天一个IDA小技巧(六)交叉引用
在使用IDA进行逆向时,经常会碰到需要「定位某个变量被哪些函数访问」或者「某个函数是从什么地方被调用的」。这种跟踪变量或函数的功能在IDA中被称作交叉引用(XREF),同时IDA还提供了图形生成功能,以更直观的方式显示代码与数据之间的关系。
一. 交叉引用
先总结,IDA中有两类交叉引用:
代码交叉引用 CODE XREF
函数调用导致的交叉引用
跳转交叉引用
数据交叉引用 DATA XREF
读取交叉引用
写入交叉引用
偏移量交叉引用
所有的交叉引用都是在一个地址引用另一个地址。这些地址可能是代码地址或数据地址。如果引入有向图论,那么就可以把每个地址看成是有向图中的节点,交叉引用看成为边,边的方向就代表着谁引用了谁。
1.1. 代码交叉引用
代码交叉引用是一个非常重要的概念,因为它可帮助IDA生成控制流图形和函数调用图形,这些图形最直观的用法就是可以帮助我们识别程序的流程,例如判断代码是否被OLLVM的控制流平坦化混淆过。
一个基本的代码交叉引用类似如下:
.text:00401000 sub_40100 proc near ; CODE XREF: main+2A ↓p
CODE XREF代表这是一个代码交叉引用,后面的地址(这里为_main+2A)是交叉引用的源头地址,即_main+2A处调用了该方法,交叉引用中使用的地址提供了额外的信息,指出交叉引用是在一个名为_main的函数中提出的,具体而言是_main函数中的第0x2A(42)字节。
地址后面总是有一个上行或下行箭头,表示引用位置的相对方向。需要向下滚动才能到达该地址。同样,上行箭头表示引用地址是一个较低的内存地址,需要向上滚动才能到达。
箭头后还包含了一个单字符后缀,代表交叉引用的类型,p代表这是一个调用类型,j则代表这是一个跳转类型的交叉引用。
可能很多人会好奇为什么将例如if else的代码改写成switch case的形式会被成为控制流平坦化,在IDA中,指令转交控制权的方式叫做流(flow)。IDA中有3种基本流:普通流、跳转流和调用流。
普通流(ordinary flow)是一种最简单的流,它表示由一条指令到另一条指令的顺序流。这是所有非分支指令(如ADD)的默认执行流。除了指令在反汇编代码清单中的显示顺序外,正常流没有其他特殊的显示标志。
每个无条件分支指令和条件分支指令将分配到一个跳转流(jump flow)。函数调用则被分配到一个调用流例如call指令。
通过交叉引用我们可以快速的追溯到每个跳转流和调用流的关系流程。
1.2. 数据交叉引用
数据交叉引用用于跟踪二进制文件访问数据的方式。IDA中最常用的3种数据交叉引用分别用于表示某个位置何时被读取、何时被写入以及何时被引用。下面这张图就展示了这三种数据交叉引用:
1.3. 读取交叉引用
读取交叉引用(read cross-reference)表示访问的是某个内存位置的内容,使用r作为单字符后缀,例如上面IDA反汇编中可以得知read_it被main+E处被读取。
同理write_it处的写入交叉引用表示修改write_it处的值,使用w作为单字符后缀,值得注意的是,write_it位置显示的交叉引用以省略号处结束,表明对write_it的交叉引用数量超出了当前的交叉引用显示限制。你可以通过Options▶General对话框中Cross-references选项卡中的Number of displayed xrefs(显示的交叉引用数量)设置修改这个限制。
第三类数据交叉引用为偏移量交叉引用(offset cross-reference),它表示引用的是某个位置的地址(而非内容),使用o作为后缀。通常,代码或数据中的指针操作会导致偏移量交叉引用。例如,数组访问操作一般通过在数组的起始地址上加上一个偏移量来实现。因此,许多全局数组的第一个地址通常可以由偏移量交叉引用来确定。为此,许多字符串数据(在C/C++中,字符串作为字符数组)成为偏移量交叉引用的目标。
一. 交叉引用列表窗口
如前所述,在某个位置显示的交叉引用注释的数量由一个配置控制,其默认设置为2。只要一个位置的交叉引用数量不超出这个限制,你就可以相当直接地访问这些交叉引用。
但如果想要查看某个位置的交叉引用完整列表,第一种方法是打开与某一特定位置有关的交叉引用子窗口。将光标放在一个或多个交叉引用的目标地址上,并选择View▶OpenSubviews▶Cross-References(查看▶打开子窗口▶交叉引用),即可打开指定位置的交叉引用完整列表。
第二种访问交叉引用列表的方法是选中一个你感兴趣的符号名称,在菜单中选择Jump▶Jump to xref(使用热键CTRL+X)打开一个对话框,其中列出了引用选中符号的每个位置。
交叉引用列表可用于迅速确定调用某个特殊函数的位置。例如如果想要确定程序中哪些地方调用了C标准库中的strcpy函数,可以用上述方法打开该函数的交叉引用列表窗口,甚至可以添加一段包含strcpy文本的注释,并使用该注释激活“交叉引用”对话框,因为IDA会讲注释中的符号名称也作为一个操作数处理,通过点击注释中的strcpy也能快速打开交叉引用列表。
最后,欢迎大家关注公众号「菜鸟学Python编程」,共同进步
每天一个IDA小技巧(六)交叉引用相关推荐
- arm ida 伪代码 安卓 符号表_每天一个IDA小技巧(一): 序言
前言 Native逆向大概是每个逆向人都敬畏又心存挑战的存在,但是又不知道从何下手,得益于汇编的繁琐,简单的高级语言在反编译成汇编指令之后分析起来复杂膨胀了无数倍,再加上对IDA Pro的一无所知,反 ...
- new 一个结构体数组_每天一个IDA小技巧(四):结构体识别
之前提到IDA可以将一长串的数组数据声明变成一行数组声明,简化反汇编代码,对于结构体,IDA也同样支持通过各种设置工具来改善结构体代码的可读性. 这篇文章的目标是将[edx+10h]之类的结构体元素访 ...
- 每天一个IDA小技巧(二):基本代码转换
重命名和注释 变量重命名 快捷键(y),若想恢复则更名为空白名称即可 方法/寄存器重命名 快捷键(N) 注释:常规注释(:)/可重复注释(;),「;」表示该行为注释 如果你所分析的文件类型与常见编译器 ...
- 每天一个脱发小技巧 | Eclipse环境下spotbugs的安装配置和详细使用方法
每天一个脱发小技巧 | Eclipse环境下spotbugs的安装配置和详细使用方法 SpotBugs介绍 Eclipse环境下SpotBugs安装 SpotBugs的使用 其他 SpotBugs介绍 ...
- 程序员的反击!每天一个离职小技巧
作者 | 梦想橡皮擦 来源 | 非本科程序员(ID:htmlhttp) 写在前面 俗话说的好,代码写的少,离职少不了. 最近畅游互联网,发现一些离职小技巧,读后,内心被深深的打动了,但是细细的品过之后 ...
- 3分钟学会python_3分钟学会一个Python小技巧
Python时间日期转换在开发中是非常高频的一个操作,你经常会遇到需要将字符串转换成 datetime 或者是反过来将 datetime 转换成字符串. datetime 分别提供了两个方法 strp ...
- pandas apply lambda_一分钟一个Pandas小技巧(二)
" 在逛Kaggle的时候发现了一篇不错的Pandas技巧,我将挑选一些有用的并外加一些自己的想法分享给大家.本系列虽基础但带仍有一些奇怪操作,粗略扫一遍,您或将发现一些您需要的技巧.&qu ...
- vob转mp4,每天一个实用小技巧
vob转mp4,vob的英文全称是Video Object,它是DVD视频媒体使用的容器格式,vob格式擅长将数字视频.音频.字幕.菜单等多个元素复用在流格式中.而且vob格式的文件可以被加密保护.经 ...
- 开源一个IDA小插件:修复VMP dump导入函数
简述: 通常我们在静态分析vmp加壳后的程序或者驱动时,都会选择将其跑开然后看dump文件.但是vmp会将某些函数地址进行混淆,所以当我们想看一个函数时,常常会见到如下图所示代码段: 面对上述情况,我 ...
最新文章
- intellij IDEA怎样打war包
- 500元辛苦费,求一C#算法,自由定义表达式
- C++阶段01笔记01【C++初识(第一个C++程序、注释、变量、常量、关键字、标识符命名规则)】
- 最全的常用正则表达式大全分享(转)
- [高斯消元及理论]线性方程组整数/浮点数,模线性方程组,异或方程组模板
- 为什么很多人不跑滴滴了?
- 网站统计功能的设计与实现
- ulimit: command not found 问题解决
- Android计算器代码分析
- WPS专业版可用key
- 单片机 WIFI模块发送AT指令收不到回复问题
- 修改mysql密码后wordpress_修改数据库密码后,wordpress网站打不开
- NESSUS简介与安装
- Apache Spark源码走读(九)如何进行代码跟读使用Intellij idea调试Spark源码
- 蓝桥杯练习-调和级数。
- ubuntu18.04企业微信字体
- 每个人都能制作的简易版QQ音乐(HTML+CSS+JQuery)
- 洛谷P1957 口算练习题
- rewrite地址转换
- debian11删除swap分区之后出现mdadm no arrays found in config file or automatically的的解决方法