0 概述
IDA,懂的人自然懂,不懂的人请百度
这里不做过多介绍
本篇作为学习笔记的第一篇,主要介绍反汇编的理论和常见反汇编方式
1 反汇编简介
编程语言进化过程为:二进制-》汇编-》C/C++等编译语言-》python等动态脚本语言
二进制的,可以直接看ARM Thumb2指令集手册,里面有对应的编码介绍,汇编就是ARM中常见的启动代码,
C/python之类的,都是程序员常见的语言,都很熟悉,不多介绍
2 为什么要反汇编
反汇编的意义在于,很多时候,我们并不能拿到C级别的源码,只能拿到bin格式的固件,所以需要通过bin来反向成汇编代码,然后分析程序
其它的几个原因
- 分析恶意软件
- 分析闭源软件的漏洞
- 分析闭源软件的互操作性
- 分析编译器生成代码,以验证编译器性能和准确性
- 在调试时显示程序指令
3 反汇编的困难
理论上来讲,bin属于透明代码,大神可以直接看二进制格式,但这么做效率太低,所以很多人做了工具,IDA就是其中一种,虽然有了工具,
但分析过程,仍然困难重重,原因如下
- 编译过程会造成损失
bin是给机器看的,所以它不需要任何变量或者函数,但我们需要,所以变量类型只能通过分析,才能知道具体类型
现在ARM Thumb2指令集稍微好一点,会固化各种符号和类型,方便分析一些 - 编译属于多对多操作
主要是因为编译优化,或者故意混淆的手段,或者IAR编译时,没有生成符号表,从而导致缺乏一些分析辅助信息 - 反编译器依赖于语言和库
选对反编译器,才能正确反编译 - 反编译任何错误,都会影响反编译生成的效果
4 如何反汇编
最简单的工具,可以用各种IDE里面的binary工具,比如elfdump,直接导出符号表和汇编代码
但这种太简单了,不便于大型系统分析
理论上,反汇编的过程如下
确定反汇编的代码区域
这个要看具体文件格式,比如elf之类的,直接包含各种section,可以分析
但bin,就要区分哪些是代码,哪些是数据,这是一个难点
我们可以换一个方向来看,对于STM32或者ARM Cortex系列的芯片来说,入口是固定的,我们直接找程序入口就可以了找到入口地址,开始逐条分析
这里,可能需要进行表查找来获取数据;对应C语言来说,就是字符串表,变量表或者函数表找到操作符和操作数,反编译成汇编指令
继续反汇编下一条指令
5 反汇编算法
主要有两种,也很简单
- 线性法
- 递归下降法
线性法:就是逐条分析汇编,读取操作码,读取操作数,反汇编,然后下一条指令;理论上很简单,但容易出错,比如,我故意在汇编指令中
插入一些混淆数据,就可以扰乱反汇编器的输出;它的好处在于,能分析出所有的二进制代码
GDB和dbjdump都是采用线性分析法,他们因为有elf的各种辅助信息,在有代码的基础上调试,所以能知道哪些是有效数据,有效代码
递归下降法:则是从另外一个方向来反汇编,就是从程序入口地址,然后分析下一条指令,顺序指令则直接继续分析,分支指令,比如if或者switch,则
直接分成两个反编译方向,依次反编译;或者跳转指令,就跳转到对应到地址。
也就是说,反编译器会尝试理解bin程序流,然后给出最佳的反汇编代码,但这样,也会有问题,机器毕竟是机器
想一下,我们在函数中,故意设置LR返回地址,估计反编译器就无能为力了。针对这种情况,我们可以用动态模拟器来调试,百试百灵
6 最后
反汇编的过程就像填字游戏,给你有限信息,然后补齐整个游戏,还是挺好玩的