IDA Pro的反汇编图以基本块作为节点,用连线来表示程序的控制流走向。当一个函数内部包含很多条件判断、循环结构以及异常处理时,图形很快就会变得十分复杂。整理反汇编图的关键,并不是要把所有的节点都排列得整整齐齐,而是应该先识别出函数的入口、主要的分支、循环结构以及返回路径,然后再通过重命名、添加注释、对节点进行分组以及利用交叉引用,逐步把分析范围缩小。
一、IDA Pro反汇编图怎么整理
在IDA Pro识别出函数之后,可以在文本反汇编视图和图形视图之间进行切换。图形视图更适合用来观察控制流,而文本视图则更方便连续阅读指令和查看具体地址。
1、先确认函数边界是否正确
按下【Space】键就可以在Graph View和Text View之间来回切换,这时要先检查函数的入口位置、结束位置以及基本块的划分是否准确。
如果有代码段被错误地识别成了数据,或者好几个函数被合并成了一个,反汇编图中就会出现跳转距离很远的情况,还会多出许多无关的节点。遇到这种问题,需要先把代码定义、函数边界和跳转目标修正过来,然后再去整理图形的布局,否则不管怎么移动节点,都没有办法解决结构上的混乱。
2、统一关键函数和变量名称
对于那些用途已经能够确认的函数、全局变量和参数,应该重新进行命名,并在重要的判断位置加上注释。名称最好能体现出它的功能,例如配置读取、权限检查、数据解密或者错误处理,但在证据还不足的时候,不要写得过于具体。
当节点中默认的名称慢慢变少之后,调用关系理解起来就会容易一些。入口参数、返回值和关键的状态变量也应当保持统一的命名,这样可以避免同一个对象在不同的位置被解释成不同的用途。
3、折叠暂时不关注的节点
选中一组逻辑上连续的基本块之后,可以使用【Group nodes】功能把它们合并起来显示。
初始化部分、重复的校验以及比较长的错误处理分支,都可以先组成节点组,只把当前需要分析的主流程保留下来。分组并不会把代码删除,后面如果需要查看,仍然可以再展开。IDA的Graph View还提供了Graph Overview功能,在分析复杂函数的时候,可以用来观察当前视图位于整张图形的哪一个区域。
二、IDA Pro反汇编图节点过多怎么快速定位
当节点数量太多的时候,从入口开始一个块一个块地去读,效率通常不高。更加实用的方法是先找到字符串、系统调用、关键常量或者返回值,然后再顺着交叉引用,反向把相关的分支定位出来。
1、从关键对象查看交叉引用
把光标放在函数、字符串或者全局变量上面,按下【X】键,就可以查看它们被引用的位置。
比如在分析配置读取的时候,可以从文件名或者配置键字符串入手;在分析网络逻辑的时候,可以从相关的API调用入手。交叉引用窗口能够把代码和数据之间的引用关系列出来,这比在一张很大的流程图中逐个搜索节点要直接得多。
2、根据箭头判断分支关系
在Graph View里面,不同类型的连线被用来表示条件成立时的走向、条件不成立时的走向以及普通的跳转。分析的时候,应该先找到比较指令和条件跳转,然后再沿着两条分支分别往下看,不必同时把所有后续节点都展开。
遇到循环结构时,要先确认循环的条件、用来计数的变量以及退出节点。如果某条连线反复指向前面已经出现过的基本块,通常说明这里存在循环或者状态重试的逻辑,适合先单独标记出来,再继续分析循环外部的主流程。
3、利用伪代码缩小目标范围
在反编译器可用的情况下,可以先在伪代码视图中识别出if、switch、循环和函数调用,然后再跳回对应的反汇编节点去核对底层的实现。伪代码适合用来快速理解整体的逻辑,而反汇编图则用来确认编译器优化、间接跳转以及寄存器的变化,把两种视图结合起来使用,比单独只看其中一种要稳定一些。
三、复杂反汇编图怎么减少无效节点
有些时候节点之所以显得很多,并不是程序本身的逻辑有多复杂,而是因为函数识别出了错误、间接跳转没有被正确解析、库代码混了进来,或者碰到了控制流平坦化等情况。在这种时候,仅仅调整布局并不会让阅读效果有明显的改善。
1、先排除库函数和通用代码
通过函数的特征、导入表以及调用关系,识别出运行库、日志、内存管理和编译器辅助函数。那些已经确认属于通用功能的节点,可以降低它们的分析优先级,把注意力集中在业务函数和关键的调用链上面。
2、检查间接跳转和switch结构
当跳转表没有被正确识别的时候,switch语句可能会表现为几个孤立的节点,或者连线显得不够完整。这时需要检查间接跳转的目标、数据表的类型以及引用关系,必要的时候重新定义跳转表,让IDA重新建立控制流。
3、改用调用关系图观察大范围逻辑
单张的函数图适合用来查看函数内部的控制流,而函数调用图和Proximity View则更适合用来观察函数与函数之间的关系。当节点数量实在太多时,可以从当前函数周围的调用者、被调用的函数以及全局数据开始,一步一步地扩展分析范围,而不是一次性把整个程序的所有调用关系都显示出来。
总结
IDA Pro反汇编图的整理,应当先修正函数的边界,再通过重命名、添加注释和节点分组来突出主流程。节点过多的时候,可以从字符串、函数调用和全局变量的交叉引用切入,结合条件箭头、伪代码以及Graph Overview,快速定位到关键的分支。如果图形依然显得异常复杂,还要继续检查跳转表、库代码以及函数识别的结果,不要把一个分析上的错误,误认为是程序本身的逻辑复杂。
