概述
我们常常以为(我之前就这么以为的)反汇编是一个简单的线性逆映射,后来经过研究才发现不是这样的。
第一个原因是data和code往往交织在一起,我们弄不清楚一段二进制是应该按照data处理,还是code处理。线性扫描直接往下扫的话显然会出错,有时候会把程序入口归为前面代码的一部分。
第二个原因是指令咬合(instruction occlusion),比如一个四字节的指令,从低到高是 48 89 75 e0,正常应该反编译为"MOV rsi, -0x20(rbp)",但是,如果从89开始翻译的话,就是"MOV esi -0x20(rbp)",甚至,若是从75开始翻译的话也是可以翻译通的,翻译为:"JNE 400599"。所以问题来了,一个二进制流可以有多个断句方式,我们往往拿不准该用哪个方式。
步骤1-ELF分析
Linux上是elf
Windows上是PE32
macOS上是Mach-O
ELF包括各种信息,我们需要尽可能的提取利用里面蕴含的信息
?反汇编是只反text段的吗?text会混杂一些data吗?会
?起始点是一定的存在于头文件的,从起始点还不能完全剥离data和text吗?主要是text里确实会包含一些data,比如switch的地址表。
?下载IDA Pro7? done
?如何交叉编译Linux和Windows的可执行文件on Mac
?从何处开始反汇编?一般就是从text里面反汇编
?如何选择下一条反汇编的指令
?如何区分代码与数据
?以及如何确定何时完成对最后一条指令的反汇编
线性扫描算法无法正确地将嵌入的数据与代码区分开来
步骤2-反汇编
嗯
步骤3-分析我们的正确性(可选)
其实我们可以自己制作一套benchmark体系,我们有开源源码,编译成.o,然后读取出里面的汇编指令作为标准答案。然后把ELF反编译出来的作为对比。开发出一套性能测试的框架,这样每次修改了我们的算法,都可以一行指令验证出我们的运行耗时,准确度指标。
以便于改进持续优化我们的算法,每次的迭代都会有一个量化的结果
MAC上面没有objdump,那就只好用brew按一个 g-的
网友评论