序 从逆向视角透视代码大厦的那些砖石

序 从逆向视角透视代码大厦的那些砖石

相对于本书的中文名字《逆向工程权威指南》,我更喜欢它的英文原名《Reverse Engineering for Beginners》,可以直译为“逆向工程入门者必读”。在国外的程序员圈中,这本书被简称为《RE4B》,作者的Blog式连载已经引发了持续关注和好评。

本书的重要特色在于其清晰的章节结构,涵盖了函数、语句、结构体、数组等这些构成代码大厦的基本元素,如显微镜般逐一对比了这些元素在X86、ARM和MIPS体系架构下的“切片”影像。本书几乎每个章节都按照X86、ARM、MIPS三个体系架构分别展开,可以让读者深入对比理解在三种体系架构下,同样的指令、函数及数据结构呈现的异同和特点。无论对分析工程师,还是编码工程师来说,本书都是能更深入理解代码大厦原材料的工作指南。这是基础性、系统性的文献工作,也是令人耳目一新的结构安排。对于在中国传统高校计算机教育中,通过简单的X86 ASM来学习和了解体系结构的工程师来说,这也是尽快打通ARM、MIPS知识背景的“全栈”指南。对于那些从各种破解教程来切入逆向领域的安全爱好者来说,这更像是一份“正餐”。对于作者来说,我相信这个写作过程是充满激情的,但也充满了艰难和痛苦。对于Dennis这样的逆向工程专家来说,这本书的写作过程,更多的不是在探索未知的世界,也不是对高级技巧和经验的总结,而是要对看起来相对枯燥的单元式资料进行整理,将一些对其已经是常识的东西转化为系统而书面化(并易于读者理解)的语言。

逆向工程一直被宣传为一种充满乐趣和带有神秘主义的技能,而逆向分析者的工作看起来更有乐趣的原因,似乎就是在指令奔涌中逆流而上,绕开种种限制和保护,找到代码中的“宝藏”——错误、漏洞或者是被加密算法层层掩盖的数据结构。这个由媒体所打造的形象,也为部分逆向爱好者所自矜。而这也导致逆向领域的书籍和教程,更多地围绕着一些高阶的技巧展开,更多地讲解如何绕过加密和保护,却忘记了逆向工程的初衷是要洞察系统及软件的整体结构和机理。由于之前的逆向领域相关出版物中缺少“代码大全”式的基础读本,本书的完成填补了这一空白,然而,这不仅需要作者有高超的逆向研究能力,也要有正向系统的思维和视野。

本书的译者之一Archer提出想邀请安天的工程师们一同完成本书的翻译时,我曾经觉得他是不是“疯了”。本书当时并无定稿的英文版本,只是Dennis持续发布的Blog式的连载。尽管网络连载已经引发了好评如潮,但其精彩篇章彼时还如散落在海底的珍珠,尚未串成珠链。以Dennis天马行空的写作风格和追求完美主义的性格,他必然会在未完成全部章节的期间,不断地增加体系结构的新热点(如ARM64)和修补既有章节的内容,甚至会改动原有的样例代码,导致本书原版定稿遥遥无期。我觉得,与其说正在养病的Archer接手翻译这本书是一份艰难的任务,倒不如说,Dennis写完本书根本就是一份不可完成的任务。

因此当接近千页的样书摆在我面前时,我被深深震撼了,那种感觉和我之前依靠自己极为蹩脚的英语扫过的英文电子稿不同,我能想象Archer是如何一边咳嗽着、一边码字或者校对代码;以及安天CERT的同事们是如何在样本分析任务饱和的情况下挤出时间来一点点推动翻译进展的。当我在视频例会上向安天各地的部门负责人展示样书时,我能看到每个人的赞叹和兴奋,那种兴奋不啻于我们自己发布了一份最新的长篇分析报告。

二进制分析,是安全分析工程师,包括有志于投身安全领域的编码工程师的基本功底之一。硅谷一些安全人士都曾提及一个有趣的说法——华人的系统安全天赋。中国安全厂商和安全工作者,在系统安全领域和分析工作中,正在不断取得新的进步。在国际网络安全企业中,华人承担关键系统安全研究和分析工作的占比也很高,国际高校的一些华人研究者在新兴领域展开系统安全研究,同样取得了很大的国际影响。遗憾的是,Web和应用开发的兴起,一定程度上让更多年轻安全从业人员的目光转向Web和应用安全,当前新的安全从业者整体的二进制分析能力正在下降,存在着基本功缺失的问题,非常需要系统性的补课。

二进制分析能力,是对安全工程师的基础能力要求。但要对抗APT等新兴威胁,仅仅有基本功是不够的,还需要在更开阔的架构视野上,具备从攻击链、体系化等角度逆向分析研判攻击行为的全程、攻击对手的全貌的能力。

当年受到一些破解教程的误导,一些接触逆向工程的年轻人把破解序列号等当成逆向工程的目的,从而导致浅尝辄止,没有真正理解逆向工程的博大精深。即使是安天部分资深的分析工程师,也往往更乐于寻找解析攻击者的个性技巧和那些有“难度”的分析细节,并常以此感到自豪,而不能站到对攻击作业过程完整复盘和对攻击者画像的角度来看待问题,而后者才是一类高阶的逆向工程。

我们是从分析“震网”所遇到的系列挫折中,从对Flame蠕虫马拉松式的、收效甚微的模块分析中,认识到了传统分析工程师所面临的这种困境的。在“震网”分析中,由国际知名厂商的架构师和分析工程师所组成的混编分析团队,就能比安天完全由软硬件安全分析工程师组成的分析小组,取得更多的分析成果和进展。因为安全厂商和APT攻击之间,不是简单的查杀反制和单点的分析对抗,而是体系化对抗。从认识到这个问题开始,安天的分析团队一方面继续强化二进制分析的基本功底;另一方面自我批判那种“视野从入口点开始”的狭隘分析视角,避免我们自己从透析攻击者载荷的高级技巧中找到太多“快感”,而忘记那些更重要的全局性因素。

过去三年间,安天发布了针对APT-TOCS、白象、方程式等组织相关的多篇分析报告,也分析了类似乌克兰国家电网遭遇攻击停电等与关键基础设施有关的安全事件。在乌克兰停电事件的分析中,我们已经初步走出了入口点视野,而尝试在更大的时空视角上还原事件。

而即使从微观的分析来看,高阶恶意代码也已经从一个附着在宿主上的代码片段或单体文件的木马,进化为一个庞大的工程体系。对于高级恶意代码来说,不仅有前端的持久化载荷和大量按需投放的“原子化”模块,其后更有一个庞大的支撑工程体系。对于前端,我们还能够依靠代码逆向来分析,而对于后面这个大到无形的“魅影”,我们更多的只能依靠分析恶意代码的指令体系、有限的网络感知捕获、少得可怜的可公开检索信息,以及作为信息安全动物的逻辑和本能来进行猜测。我们所要完成的工作,不仅仅是要逐一进行载荷模块分析,而是要对整个攻击面和攻击链的深入复盘。

2017年1月25日,安天分析小组更新了针对方程式攻击组织的第四篇分析报告《方程式组织EQUATION DRUG平台解析》,基于对方程式组织大量恶意代码模块的分析,我们初步完成了一份有价值的工作,那就是方程式组织的主机作业模块积木拼图。

我的同事在《方程式组织EQUATION DRUG平台解析》中写道:

“这些庞杂的模块展开了一组拼图碎片,每一张图上都有有意义的图案,但如果逐一跟进,这些图案就会组成一个巨大的迷宫。迷宫之所以让人迷惑,不在于其处处是死路,而在于其看起来处处有出口,但所有的砖块都不能给进入者以足够的提示。此时,最大的期待,不只是有一只笔,可以在走过的地方做出标记,而是插上双翼凌空飞起,俯瞰迷宫的全貌,当然这是一种提升分析方法论的自我期待。我辈当下虽身无双翼,但或可练就一点灵犀。”

所有高阶的分析工作,都是以最基础的代码分析为起点的。无论是面对APT攻击的深度分析,还是对高级黑产行为的系统挖掘,仅有基本分析固然是远远不够的,但没有最基本的分析是万万不能的。从未来安全工程师所需要的能力来看,熟读本书并不能使你走出迷宫。但不掌握本书相关的基础能力,不能去透视代码迷宫的砖石,就连走入迷宫的资格都没有。也正因为此,本书是安天工程师人手一本的必备手册和必读之物。

肖新光

安天创始人,首席技术架构师,反病毒老兵

目录

  • 版权
  • 版权声明
  • 内容提要
  • 序 从逆向视角透视代码大厦的那些砖石
  • 前言
  • 第一部分 指令讲解
  • 第1章 CPU简介
  • 第2章 最简函数
  • 第3章 Hello,world!
  • 第4章 函数序言和函数尾声
  • 第5章 栈
  • 第6章 printf()函数与参数调用
  • 第7章 scanf()
  • 第8章 参数获取
  • 第9章 返回值
  • 第10章 指针
  • 第11章 GOTO语句
  • 第12章 条件转移指令
  • 第13章 switch()/case/default
  • 第14章 循环
  • 第15章 C语言字符串的函数
  • 第16章 数学计算指令的替换
  • 第17章 FPU
  • 第18章 数组
  • 第19章 位操作
  • 第20章 线性同余法与伪随机函数
  • 第21章 结构体
  • 第22章 共用体(union)类型
  • 第23章 函数指针
  • 第24章 32位系统处理64位数据
  • 第25章 SIMD
  • 第26章 64位平台
  • 第27章 SIMD与浮点数的并行运算
  • 第28章 ARM指令详解
  • 第29章 MIPS的特点
  • 第二部分 硬件基础
  • 第30章 有符号数的表示方法
  • 第31章 字节序
  • 第32章 内存布局
  • 第33章 CPU
  • 第34章 哈希函数
  • 第三部分 一些高级的例子
  • 第35章 温度转换
  • 第36章 斐波拉契数列
  • 第37章 CRC32计算的例子
  • 第38章 网络地址计算实例
  • 第39章 循环:几个迭代
  • 第40章 达夫装置
  • 第41章 除以9
  • 第42章 字符串转换成数字,函数atoi()
  • 第43章 内联函数
  • 第44章 C99标准的受限指针
  • 第45章 打造无分支的abs()函数
  • 第46章 变长参数函数
  • 第47章 字符串剪切
  • 第48章 toupper()函数
  • 第49章 不正确的反汇编代码
  • 第50章 混淆技术
  • 第51章 C++
  • 第52章 数组与负数索引
  • 第53章 16位的Windows程序
  • 第四部分 Java
  • 第54章 Java
  • 第五部分 在代码中发现重要而有趣的内容
  • 第55章 编译器产生的文件特征
  • 第56章 Win32环境下与外部通信
  • 第57章 字符串
  • 第58章 调用宏assert()(中文称为断言)
  • 第59章 常数
  • 第60章 检索关键指令
  • 第61章 可疑的代码模型
  • 第62章 魔数与程序调试
  • 第63章 其他的事情
  • 第六部分 操作系统相关
  • 第64章 参数的传递方法(调用规范)
  • 第65章 线程本地存储TLS
  • 第66章 系统调用(syscall-s)
  • 第67章 Linux
  • 第68章 Windows NT
  • 第七部分 常用工具
  • 第69章 反汇编工具
  • 第70章 调试工具
  • 第71章 系统调用的跟踪工具
  • 第72章 反编译工具
  • 第73章 其他工具
  • 第八部分 更多范例
  • 第74章 修改任务管理器(Vista)
  • 第75章 修改彩球游戏
  • 第76章 扫雷(Windows XP)
  • 第77章 人工反编译与Z3 SMT求解法
  • 第78章 加密狗
  • 第79章 “QR9”:魔方态加密模型
  • 第80章 SAP
  • 第81章 Oracle RDBMS
  • 第82章 汇编指令与屏显字符
  • 第83章 实例演示
  • 第九部分 文件分析
  • 第84章 基于XOR的文件加密
  • 第85章 Millenium游戏的存档文件
  • 第86章 Oracle的.SYM文件
  • 第87章 Oracle的.MSDB文件
  • 第十部分 其他
  • 第88章 npad
  • 第89章 修改可执行文件
  • 第90章 编译器内部函数
  • 第91章 编译器的智能短板
  • 第92章 OpenMP
  • 第93章 安腾指令
  • 第94章 8086的寻址方式
  • 第95章 基本块重排
  • 第十一部分 推荐阅读
  • 第96章 参考书籍
  • 第97章 博客
  • 第98章 其他内容
  • 第十二部分 练习题
  • 第99章 初等难度练习题
  • 第100章 中等难度练习题
  • 第101章 高难度练习题
  • 第102章 Crackme/Keygenme
  • 附录A x86
  • 附录B ARM
  • 附录C MIPS
  • 附录D 部分GCC库函数
  • 附录E 部分MSVC库函数
  • 附录F 速查表
  • 附录G 练习题答案
  • 参考文献

相关技术

推荐用户