如果你是安全工程师、逆向工程师,那么你可能需要一本《二进制分析实战》

绝大多数计算机程序是使用C或C++等高级语言编写的,该类编程语言无法直接运行。在使用它们之前,必须先将其编译为包含计算机可运行的机器语言的二进制可执行文件。但是,你如何知道编译后的程序与高级源代码是否具有相同的语义?令人不安的答案是你无法知道!

高级语言和二进制机器语言之间存在很大的语义鸿沟,因此很少有人知道它们如何进行联系。大多数程序员对其程序在底层运行的知识了解很有限,他们只是简单地相信编译后的程序会符合他们的意图。结果是,许多编译器错误、细微的实现错误、二进制级别的后门程序和恶意寄生虫可能会被忽略。

更糟糕的是,在工业的系统、银行的系统和嵌入式系统中,有无数的二进制程序和库,这些源程序可能长期丢失或是私有的,这意味着无法使用常规方法对这些程序和库进行修补或在源代码级别上评估其安全性。即使对于大型软件公司,这也是一个现实存在的问题,例如,微软最近发布了精心制作的二进制补丁程序,用于解决Microsoft Office公式编辑器程序中的缓冲区溢出。

如何在二进制级别上分析和修改程序。《二进制分析实战》可以解除你的疑惑。

无论你是安全研究人员、恶意软件分析师、程序员,还是仅仅对二进制分析感兴趣的人,这些技术都将让你能掌握并深入了解你每天创建和使用的二进制程序。

本书的主要目标是使你成为全面的二进制分析人员,并熟悉该领域的所有重要主题,包括基本主题和高级主题,如二进制插桩、污点分析和符号执行。这本书并不是一个全面的资源,因为二进制分析领域和工具变化如此之快,一本全面的书可能很快就过时了。相反,这本书的目的是让你了解所有重要的主题,这样你就可以更独立地学习。同样,这本书也没有深入讲解如何对x86和x86-64代码进行逆向工程(尽管附录A涵盖了基础知识)或分析这些平台上的恶意软件的所有复杂之处。已经有许多关于这些主题的专门书籍,在这里重复它们的内容是没有意义的。

这本书分为4个部分。

第一部分“二进制格式”介绍二进制格式,这对理解本书的其余部分至关重要。如果你已经熟悉ELF和PE二进制格式以及libbfd,你可以跳过本部分的一章或多章。

第1章“二进制简介”提供二进制程序剖析的一般介绍。

第2章“ELF格式”介绍Linux上使用的ELF二进制格式。

第3章“PE格式简介”包含对PE的简要介绍,以及在Windows上使用的二进制格式。

第4章“使用libbfd创建二进制加载器”展示如何使用libbfd解析二进制文件,并构建本书其余部分使用的二进制加载器。

第二部分“二进制分析基础”包括基本的二进制分析技术。

第5章“Linux二进制分析”介绍Linux的基本二进制分析工具。

第6章“反汇编与二进制分析基础”涵盖基本的反汇编技术和基本的分析模式。

第7章“简单的ELF代码注入技术”,在本章,你将第一次体验如何使用寄生代码注入和十六进制编辑等技术来修改ELF二进制文件。

第三部分“高级二进制分析”介绍高级二进制分析技术。

第8章“自定义反汇编”展示如何使用Capstone创建自定义的反汇编工具。

第9章“二进制插桩”介绍如何用Pin修改二进制文件,Pin是一个成熟的二进制工具平台。

第10章“动态污点分析的原理”介绍动态污点分析的原理,这是一种非常先进的二进制分析技术,允许你跟踪程序中的数据流。

第11章“基于libdft的动态污点分析”教你用libdft构建自己的动态污点分析工具。

第12章“符号执行原理”专门介绍符号执行,这是另一种高级技术,你可以用它自动推理复杂的程序属性。

第13章“使用Triton实现符号执行”演示如何使用Triton构建实用的符号执行工具。

第四部分“附录”包括对你有用的资源。

附录A“x86汇编快速入门”为不熟悉x86汇编语言的读者提供简要介绍。

附录B“使用libelf实现PT_NOTE覆盖”提供在第7章中使用的elfinject工具的实现细节,并介绍libelf。

附录C“二进制分析工具清单”包含你可以使用的二进制分析工具列表。

什么是二进制分析,为什么需要它

二进制分析是分析计算机二进制程序(称为二进制文件)及其包含的机器代码和数据属性的科学和艺术。简而言之,所有二进制分析的目标是找出(并可能修改)二进制程序的真正属性——换句话说,它们真正在做什么,而不是我们认为它们应该做什么。许多人将二进制分析与逆向工程和反汇编联系起来,这种说法至少部分是正确的。在许多形式的二进制分析中,反汇编是重要的第一步,而逆向工程是二进制分析的常见应用,并且通常是记录专有软件或恶意软件行为的唯一方法。但是,二进制分析的领域远不止于此。从广义上说,你可以将二进制分析技术分为两类,或是这两类的组合,具体如下。

静态分析。静态分析技术可在不运行二进制文件的情况下对二进制文件进行分析。这种方法有两个优点:可以一次性分析整个二进制文件,且不需要特定的CPU来运行二进制文件。例如,你可以在x86计算机上静态分析ARM二进制文件。而这种方法的缺点是静态分析并不了解二进制文件运行时的状态,这会使分析非常具有挑战性。

动态分析。与静态分析相反,动态分析会运行二进制文件并在执行时对其进行分析。这种方法通常比静态分析更简单,因为你完全了解整个运行时状态,包括变量的值和条件分支的结果。但是,你仅能看到执行的代码,因此这种方法可能会遗漏程序中一些有趣的部分。

静态分析和动态分析各有优缺点,你将在本书中学习这两种方式的技巧。除了被动的二进制分析,你还将学习二进制插桩技术,用以在不需要源代码的情况下修改二进制程序。二进制插桩依赖于像反汇编这样的分析技术,同时它可以用来辅助二进制分析。鉴于二进制分析和插桩技术之间的这种共生关系,本书涵盖了这两块内容。

前面已经提到过,你可以使用二进制分析来对无源代码程序进行记录和测试。但是,即使有可用的源代码,二进制分析对于发现细微的错误也特别有用,这些错误在二进制级别的体现要比源码级别的更清晰。许多二进制分析技术对于高级调试也很有用。本书介绍了可以在这些场景中使用的二进制分析技术。

二进制分析因何具有挑战性

二进制分析具有挑战性,且相比源代码级别上的等价分析要困难得多。事实上,许多二进制分析任务基本上是不确定的,这意味着为这些问题构建一个总是返回正确结果的分析引擎是不可能的!为了让你了解即将遇到的挑战,这里列出了二进制分析困难的原由。遗憾的是,这个列表远远不够详尽。

  • 没有符号信息。当我们用像C或C++这样的高级语言编写源代码时,我们用有意义的名称给变量、函数和类这样的结构命名。我们称这些名称为符号信息,或简称为符号。良好的命名约定使源代码更容易理解,但是在二进制级别上它们并没有真正的相关性。因此,二进制文件通常去掉了符号,这使得理解代码更加困难。
  • 没有类型信息。高级语言的另一个特性是它们定义明确的变量类型(如int、float或string)以及更复杂的数据结构(如struct类型)。相反,在二进制级别上,类型从来没有被明确地声明过,这使得数据的用途和结构难以推断。
  • 没有高级抽象。现代程序被划分为类和函数,但是编译器扔掉了这些高级信息。这意味着二进制文件看起来是大量的代码和数据,而不是结构良好的程序,因而将其恢复为高级结构的过程非常复杂,且容易出错。
  • 混合代码和数据。二进制文件可以(并且确实)包含与可执行代码混合在一起的数据片段。这使得将数据解释为代码很容易。反之亦然,但这会导致错误的结果。
  • 位置相关的代码和数据。由于二进制文件的设计初衷不包括可修改,所以即使只添加一条机器指令也可能会产生其他代码移位的问题,从而使内存地址和代码中其他地方的引用无效。因此,任何类型的代码或数据修改都极具挑战性,并且容易破坏二进制文件。

由于以上这些挑战,所以我们在实践中不得不经常面对不精确的分析结果。二进制分析的一个重要部分是,尽管存在分析错误,但仍要以创造性的方式构建可用的工具!

谁需要阅读这本书

这本书的目标读者包括安全工程师、学术安全研究人员、逆向工程师、恶意软件分析师和对二进制分析感兴趣的计算机科学专业学生。。

另外,因为这本书涵盖了较高级的知识,所以一些编程和计算机系统的基础知识是必需的。为了充分利用这本书,你应该具备以下几点:

  • 可以使用C和C++进行有效编程;
  • 了解操作系统的内部(进程是什么,虚拟内存是什么等);
  • 了解如何使用Linux shell(尤其是bash);
  • 具有x86/x86-64汇编程序的工作知识。如果你还不了解任何程序集,请确保先阅读附录A。

如果你以前从未编写过程序,或者不喜欢钻研计算机系统的底层细节,那么这本书可能不适合你。

猜你喜欢

转载自blog.csdn.net/epubit17/article/details/121137553