导语:这篇文章的目的是对动态二进制插桩的原理和基本实现过程进行全面的介绍,其中,我会选择一些最知名和最常用的动态二进制插桩框架进行具体说明,其中包括Pin,DynamoRIO和Frida。
动态二进制修改对运行性能的影响
动态二进制插桩的原理和基本实现过程(一)回顾。现在就来讲讲动态二进制修改会对正在运行的程序的性能产生什么影响,根据我的经验,通常观察到的性能开销,实际上取决于各种实际运行因素。不过一般情况下,用户实现的修改都会造成性能开销的变化。无论如何,使用作为动态二进制插桩时,你首先要做的决定就是确定所需的代码覆盖率,进而在衡量性能开销是否合理。
Pin
Pin是由英特尔公司开发的动态二进制插桩框架,它允许我们为Windows,Linux和OSX构建称为Pintools的程序分析工具。我们可以使用这些工具来监控、修改和记录程序运行时的行为。
点此链接就可以免费下载和使用Pin,除了文档和二进制文件之外,Pin还包含大量Pintools的样本源代码。在开发任何Pintool之前,这些都是我们必须考虑且必须阅读的宝贵材料。
在我看来,Pin是最容易使用的动态二进制插桩框架,至少我觉得深入了解它的API比使用DynamoRIO更容易。虽然除了这两个以外我没有花太多时间去深入学习其他API,但像Valgrind,Triton,Dyninst和Frida,总体上是不如Pin的。
不过选择什么,还得看你的实际用途。如果你想创建一个商业工具并发布它的二进制版本,Pin将不是一个好的选择。根据我的测试,Pin的特点就是稳定可靠。我在某些动态二进制插桩框架下运行某些程序时经常会遇到了一些问题,主要是大型程序,如Office套件,游戏和杀毒软件引擎。其中一些动态二进制插桩框架甚至在运行某些小型应用程序时,也会发生崩溃。
设置Pin(Windows)
Linux中的Pin设置非常简单,但是,在Windows系统上,情况则完全不同。如果你想尝试我在本文里的测试,可以按着以下方式快速设置。
从这里获取Pin的最新版本,并将其解压缩到C:\驱动器或任何你想要的位置。为简单起见,我通常使用C:\pin,同时我建议你也这样做。
Pin的压缩文件中包含source/tools下的大量Pintools样本。你在实践中将会看到,此API非常易于阅读和理解。
我喜欢用Microsoft Visual Studio(简称VS),我将使用它来构建本文中提到的所有工具。有一个Pintool样本几乎可以用Visual Studio构建,你只需要调整其中的几个设置而已。但是,每次当我想创建一个新的Pintool工具时,我都不想手动复制和重命名文件,为此我创建了一个已经调整好了的样本,你可以连同下面的python脚本一起放在C:\pin\source\tools下。不过,由于较新版本的Visual Studio保存设置的方式已更改,因此我不得不重新编写了一个全新的脚本。
因此,每次要使用Visual Studio构建新的Pintool时,只需执行以下操作。
cd\ cd pin python create_pintool_project.py -p <name_of_your_project>
然后,你只需点击Pintool的解决方案文件,即可使用Visual Studio构建Pintool。我使用的是Visual Studio Professional 2015,但它也适用于Visual Studio 2017,我使用Visual Studio 2017 Enterprise进行了几次构建测试,都没有任何问题。
Pin Visual Studio集成
我们可以将我们制作的Pintools作为外部工具集成到Visual Studio中,这样我们就可以在不使用命令行的情况下运行和测试制作的Pintool。配置非常简单,从“工具”菜单中,选择“外部工具”,此时将出现一个对话框。单击“添加”按钮,然后参照下图,填写对应的文本。
在标题输入框中,输入你想要的任何内容。在命令输入文本框中,输入pin.exe的完整路径,如果你在c:\pin下安装它,请输入c:\pin\pin.exe。在参数中,你必须包含要发送给Pintool的所有参数,至少需要像上图中指定的那样。-t用于指定Pintool的位置, — 后跟的是你要插桩的目标程序。
设置完成后,你只需从工具菜单中运行你的Pintool即可,如下图所示。
点击确定,既可以开始运行了。
Visual Studio的输出窗口,将显示写入stdout的Pintool输出。
DynamoRIO
DynamoRIO也是另一个使用动态二进制插桩框架的平台,最初是由惠普的Dynamo优化系统与麻省理工学院的Runtime Introspection and Optimization(RIO)研究小组合作开发的。它允许我们为Windows和Linux构建称为客户端的程序分析工具,我们可以使用这些工具来监控、修改和记录程序运行时的行为。
DynamoRIO于2002年首次作为单独的二进制工具被包发布,后来在2009年开源了BSD许可证。与Pin一样,它还附带了多个客户端样本的源代码。这些是让我们开始并使用其API的非常宝贵的例子。
DynamoRIO是一个运行时刻代码( runtime code)操作系统,它允许我们在程序运行时对程序的任何部分进行代码转换,它可以作为应用程序和操作系统之间的中间平台。
正如我之前所说,我并没有发现DynamoRIO的API好用。但是,如果你计划制作商业版本或发布二进制版本,DynamoRIO可能是最佳选择。它的一个优点是获得了BSD许可,这意味着它是个免费软件。
另请注意,通常认为DynamoRIO比Pin更快,然而,Pin比DynamoRIO更可靠,这是我在运行大型软件程序时的亲身感受。
设置DynamoRIO(Windows)
要在Windows上安装DynamoRIO,只需从此处下载最新的Windows版本,类似于我们对Pin所做的设置,只需将其解压缩到C:\dynamorio下即可。
要在Windows上构建自己的DynamoRIO工具,可能有点困难。你可以尝试按照这个说明以及这个说明进行操作即可,或者直接套用我下面讲的DynamoRIO Visual Studio模板。
正如我之前所说,我喜欢Visual Studio。所以我用它创建了一个样本,该样本已经修改了所需的所有include和libs(前提是你已经解压缩了DynamoRIO文件),具体可在点此处获得。然后,就像使用Pin一样,我们也需下载python脚本。由于这两个工具的文件结构有点不同,我无法直接使用我之前编写的脚本,因此我不得不创建一个针对于DynamoRIO的新脚本。
因此,每次要使用Visual Studio构建新的DynamoRIO客户端时,只需执行以下操作。
python create_dynamorio_project.py -p <name_of_your_project>
请注意,上面的命令所提到提到的Python脚本和样本都必须在同一个文件夹中。
然后,你只需点击解决方案文件,即可使用Visual Studio构建DynamoRIO客户端。我使用的是Visual Studio Professional 2015,但它也适用于Visual Studio 2017。我使用Visual Studio 2017 Enterprise进行了几次构建测试,没有遇到任何问题。
DynamoRIO Visual Studio集成
我们还可以将DynamoRIO与Visual Studio集成,由于设置过程和Pin完全相同我就不赘述了,看图便知。
Frida
Frida是一个主要由Ole André V. Ravnås开发的动态二进制插桩框架,该工具在网络社区中变得非常受欢迎,并获得了相当多志愿者的积极修改。Frida目前可以支持OSX,Windows,Linux和QNX,并且有一个可用于多种语言的API,如Python,C#,Swift,Qt\QML和C.,就像上面提到的动态二进制插桩框架一样,我们可以使用Frida和脚本在程序运行时监控、修改和记录程序的行为。
Frida是免费的,非常容易安装。安装之后,还有详细的案例教程,你可以系统性进行学习。Frida目前已经将谷歌的V8引擎注入到它的进程中,这样Frida内核就会与Frida的代理(进程端)进行通信,并使用V8引擎运行JavaScript代码(创建动态hook)。
随着Web相关技术的发展,JavaScript所要承担的工作也越来越多,早就超越了“表单验证”的范畴,这就更需要快速的解析和执行JavaScript脚本。V8引擎就是为解决这一问题而生,在node中也是采用该引擎来解析JavaScript。
Frida的API由两大功能块组成:JavaScript API和bindings API。我并没有对它们进行深入研究,只是使用了我认为最受欢迎的JavaScript API,我发现它易于使用,非常灵活,我可以用它来快速编写一些内省(introspection)工具。
尽管Pin和DynamoRIO是比较流行的动态二进制插桩框架,并且最成熟,但Frida具有一些优势。如上所述,它具有更多语言的优势,并且配备了快速开发工具。不过与其他框架相比,它还有一些缺点,成熟度较低,文档较少,粒度较小,因此缺乏某些功能。
Frida的设置(Windows)
Frida的设置非常简单,只需下载它即可,然后运行:
python get-pip.py
并且,实际安装Frida类型如下。
cd\ cd Python27\Scripts pip.exe install frida