1. 开篇:为什么人类看不懂反汇编?
也许不是所有的人不适合看反汇编总有人天赋异禀?就像传说中的“人肉逆向机”一样。
总有人天赋异禀?就像传说中的人肉逆向机一样。
反正我是做不到的啦~~我只是个普通的平凡人类。
身为人类的局限
人类短期记忆的容量大概在7个数字左右(左右范围是5到9个)这是著名的心理学家。。。。(嗯。。。他的名字超过了7个字母,所以我没记住)的研究结果。
ref:1956年George Miller论文 http://www.psychspace.com/psych/viewnews-12308
有兴趣的可以去:https://humanbenchmark.com/tests/number-memory 自己测试一下“你”是不是有独特的记忆天赋,反正我这个人经常忘掉东西。
而常用的指令集比如x86_64,哪怕把RIP/RBP/RSP/段寄存器/标志位全不算,剩下的寄存器还有10多个呢。要知道,记住一个寄存器的状态可比记一个数字难多了。
看不懂的汇编
汇编语言的设计就不是给人类看的。我举个最典型的例子,条件分支。
比如这样的代码
编译成汇编后因为标志位的比较是独立的,汇编代码可能是这样
如果有更加复杂的条件,循环,那就更是一坨了
来捣乱的编译器与伟大的F5
看不懂汇编和寄存器数量,他们还都不是主要的麻烦,可以通过反复训练+足够多的经验弥补。
最麻烦的还是编译器的优化,最典型的就是 指令选择+指令调度+寄存器分配+窥孔优化 (这几个话题每个都值得后面单独开一张来讲)
最终变成了一团奇奇怪怪的东西(尤其是大型软件的反编译)
幸好,我们还有反编译器来缓解这种问题。感谢伟大的F5。
为什么要学习这部分知识?
人类的局限告诉我们,绝大部分人是很难直接看懂反汇编的。
而逆向工程,尤其是对复杂软件的逆向工程,逆向目的往往不是看懂代码的每一处,而是在理解一段段业务在做什么,确认输入输出。而伟大的F5按钮能够极大的加速这个过程。
“但是,如果F5坏了或者不好用了怎么办!!!??”
这在逆向工作中太常见了,我举几个大家一定遇到过的例子:
花指令
switch跳转识别不出来
IDA说什么什么sp-error栈平衡错误是啥意思,咋解决
F5代码里充满了goto,根本看不懂
F5代码全是结构体偏移的指针计算,根本不想看
他这个二进制是c++、go、rust写的,简直一坨
<省略>
那么为什么会有这些问题,能不能解决,怎么解决?应该在哪一步编写插件?应该如何编写插件完成优化?
如果理解了反编译器的内部构造,就能大概回答这些问题。
Last updated