基于 JavaScript 进行符号执行测试

基于 JavaScript 进行符号执行测试

摘要

我们描述了一个名为 Jalangi 的工具框架,用于 JavaScript 程序的动态分析和符号执行测试。该框架是用 JavaScript 编写的,允许对 JavaScript 进行各种重载动态分析。Jalangi 包含两个关键技术:1)选择性录制回放,这是一种能够录制并准确地回放用户选择的程序部分的技术;2)阴影值和阴影执行,可以轻松实现重量级动态分析,例如,condicolic 测试和污点跟踪。Jalangi 通过对源代码注入进行检测,这使得它可以实现跨平台移植。根据 Apache 2.0 许可,可以从https://github.com/SRA-SiliconValley/jalangi获得Jalangi。我们在SunSpider基准套件和五个Web应用程序上对Jalangi的评估表明,Jalangi在录制过程中的平均速度降低了26倍,在重放和分析过程中的速度平均降低了30倍。与类似工具(如PIN和针对x86二进制文件的Valgrind)报告的类似情况相比,速度的降低是可比的。

关键词

JavaScript;动态分析;符号执行测试

一 导言

JavaScript 是编写客户端 web 应用程序的首选语言,并且在编写移动应用程序(例如用于 Tizen OS 和 iOS)、桌面应用程序(如 Windows 8 和 Gnome 桌面应用程序)和服务器端应用程序(如 node.js)时越来越流行。但是,针对 JavaScript 应用程序的分析、测试和调试的工具较少。我们已经开发了一个简单而强大的框架,称为 Jalangi,用于为 JavaScript 编写重载动态分析。本文简要介绍了该框架及其使用场景。该框架提供了一些有用的抽象和 API,大大简化了 JavaScript 动态分析的实现。关于 Jalangi 背后的技术的详细描述可以在[6]中找到。

Jalangi 可以在任何浏览器或 node.js 上工作。我们通过选择性的源代码检测来实现浏览器的独立性。即使某些源文件没有检测,Jalangi 也可以运行。对 Jalangi 的分析分两个阶段进行。在第一阶段中,在用户选择的平台(如 Android 上运行的 mobile chrome)上执行并录制一个插入指令的 JavaScript 应用程序。在第二阶段中,录制的数据用于在桌面环境中执行用户指定的动态分析。

Jalangi 允许通过支持阴影值和阴影执行轻松实现动态分析。阴影值使我们能够将阴影值与程序中使用的任何值相关联。在 Jalangi 中,我们使用阴影值和执行实现了几个动态分析:1)共同语言测试,2)纯符号执行,3)跟踪 null 和 undefined 的来源,4)检测可能的类型不一致,5)简单的对象分配分析器,6)简单的动态污染分析。

二 技术细节

我们提供了 Jalangi 的技术细节概要。有关更详细的技术讨论,请参阅[6]。用户标识由 Jalangi 检测的 web 应用程序的一个子集,以便录制和回放。在录制阶段,将在用户选择的平台上执行生成的检测代码。即使使用了用户代码的子集,整个应用程序也会在录制阶段执行,包括已插入和未插入 JavaScript 代码以及本机代码。但是,在回放阶段,Jalangi 仅回放已检测的代码。Jalangi 具有在用户平台上完整执行 JavaScript 应用程序的功能,使录制的执行可以在开发笔记本电脑/台式机 JavaScript 引擎上进行调试,以进行调试,包括移动浏览器和基于 node.js 的系统,或具有嵌入式 JavaScript 引擎的集成开发系统。这种方法还支持使用支持阴影执行的底层阴影值实现动态分析。

通过录制执行期间从内存加载的每个值,并在回放期间在相关内存加载期间重新使用它们,可以有效地提供录制和回放。这种方法虽然听起来不错,但也存在一些挑战,例如:(1)如何有效地录制函数和对象?(2) 如何在未检测本机函数(例如,JavaScript 事件 dispather)调用检测函数时提供回放?通过提供间接记录(其中唯一的数字标识符与每个对象和功能相关联)以及记录这些标识符的值来解决第一个问题。第二个问题通过显式录制和调用已检测功能来解决,这些功能又从未插入代码中调用,或者由于 JavaScript 事件处理程序调度而执行。

此外,我们还观察到,回放期间的内存负载值可以通过执行检测代码来计算,而无需录制所有内存负载的值。通过仅记录必要的内存负载,这用于提高 Jalangi 的效率。为了确定是否必须记录内存负载的值,Jalangi 在记录阶段跟踪影子内存,该影子内存将在执行实际代码时随实际内存一起更新。 执行本机和未执行的代码不会对影子内存进行更新。为了确保在重放阶段可以使用正确的值,只有在记录阶段在内存位置存储的值存在差异时(例如,如果在内存位置的值之间存在差异),Jalangi 才会存储内存负载的值。 实际加载的内存及其关联值存储在影子内存中)。

在 Jalangi 中,在回放阶段执行中使用的任何值都可以替换为带注释的值,该值可以为实际使用的值提供附加信息。例如,支持污染分析所需的额外污染信息,或者可能是与符号执行中的实际值相关的信息,这些信息可以以符号表达式的形式提供。Jalangi 使用 concolvalue 类型的对象来表示带注释的值。

三 动态分析

在 Jalangi,我们进行了以下动态分析:

  • 符号执行测试:符号执行测试沿着具体的执行路径执行符号执行,生成表示输入值约束的逻辑公式,并求解约束以生成新的测试输入,这些新的测试输入将沿着以前未探索的路径执行程序。Jalangi 中的符号执行测试支持对整数,字符串和对象类型的约束以及新颖的类型约束。我们引入类型约束来处理 JavaScript 的动态特性,对于程序的不同可行执行路径,输入变量的类型可以不同。
  • 纯符号执行:纯符号执行象征性地执行程序,从不为了回溯而重新启动程序。它在执行分支语句之前检查状态,执行一个分支,然后使用检查点状态回溯以探索另一个分支。对于小程序,纯符号执行避免了由于重复重新启动而造成的时间浪费。
  • 跟踪空值和未定义值的来源:此分析录制空值和未定义值来源的源代码位置,并在由于空值或未定义值而发生错误时报告位置。每当由于这些文本(例如访问空值的字段)而出现错误时,就会向用户报告文本的阴影值。这样的报告有助于程序员轻松识别空值的来源。
  • 检测可能的类型不一致:动态分析检查在给定程序位置创建的对象是否可以采用多个不一致的类型。它计算在程序中的每个定义位置创建的对象和函数值的类型。如果在程序位置定义的对象或函数值在执行期间被观察到具有多个类型,则分析报告程序位置和观察到的类型。有时,这种类型的不一致可能会指向程序中的潜在错误。我们已经在两个 SunSpider 基准测试程序中注意到了这样的问题。
  • 简单对象分配探查器:此动态分析录制在给定分配站点创建的对象数量以及访问对象的频率。它报告在给定分配站点创建的对象是只读的还是常量。它还报告对象创建时间和对象的最新访问时间之间的最大和平均差异。如果分配站点创建的常量对象太多,则可能导致内存效率低下。我们在基准测试套件中的一个 web 应用程序中发现了这样一个问题。
  • 动态污染分析:动态污染分析是一种信息流分析形式,它检查信息是否可以从一组特定的内存位置(称为源)流向另一组内存位置(称为汇)。我们在 Jalangi 中实现了一种简单的动态污染分析形式。在分析中,我们将任何对象的任何字段的读取(以前未由检测源编写)视为污染源。我们将任何可能改变程序控制流的内存位置的读取都视为接收器。我们附加污染信息与实际值的阴影值。

四 实施

Jalangi 可在https://github.com/SRA SiliconValley/Jalangi 上获得。我们已经用 JavaScript 实现了 Jalangi。

Jalangi 通过检测 JavaScript 代码进行操作。表 3 显示了在表 1 中插入代码后获得的代码。在检测期间,Jalangi 从 Jalangi 库插入各种回调函数。回调函数列在表 2 中。这些函数在 JavaScript 中包装了各种操作。Jalangi 的选择性录制重放引擎是通过定义这些回调函数来实现的。

Jalangi 将工具库公开为函数工具代码。这也使我们能够动态地测试在运行时创建和计算的任何代码。例如,我们将对 eval(s)的任何调用修改为 eval(instrumentCode(s))。

基于 JavaScript 进行符号执行测试

基于 JavaScript 进行符号执行测试

基于 JavaScript 进行符号执行测试

五 Jalangi 的表现

我们在 JavaScript-SunSpider(http://www.webkit.org/perf/SunSpider/SunSpider.html)基准套件中的26个程序和使用HTML5/JavaScript为Tizen操作系统编写的5个web应用程序上运行了Jalangi的录制回放。(https://developer.tizen.org/下载/示例web应用程序)。表4显示了与录制阶段和三个动态分析相关的开销:无分析(用null表示)、跟踪空和未定义的来源(用track表示)和污染分析(用taint表示)。我们还报告为每个基准程序录制的值的数量。实验是在配备2.3 GHz Intel Core i7 和 8 GB RAM 的笔记本电脑上进行的,并在 Chrome 25 上运行了网络应用,并在 node.js 0.8.14 上执行了重放。

我们没有衡量 web 应用程序的增长速度,因为它们大多是交互式应用程序。对于 SunSpider 基准套件,在记录阶段,我们观察到平均速度降低了 26 倍,最低为 1.5 倍,最高为 93 倍。 在重播阶段进行空分析时,我们观察到平均速度降低了 30 倍,最小值为 1.5 倍,最大值为 93 倍。 跟踪分析显示,平均速度降低了 32.75 倍,最小值为 1.5 倍,最大值为 96 倍。

5.1 JALANGI 动态分析检测到的问题

Jalangi 可能的类型不一致检查器发现,SunSpider 基准测试套件的 3d-cube.js 中的 CreateP 函数主要用作构造函数,但在某个位置它被称为函数。作为函数调用的结果,程序在全局对象中创建一个不必要的 V 字段。我们认为此调用可能是编程错误。

Jalangi 的对象分配分析器注意到附件游戏 webapp 中的 getValue(place,_board)方法创建了一个常量对象数千次。我们相信,通过在方法之外提升常数对象,可以避免这种不必要的常数对象的创建。

六 相关工作

据我们所知,Jalangi 是第一个 JavaScript 动态分析框架。很少有工具可以执行 JavaScript 程序的录制回放。JSBench 使用录制回放机制创建 JavaScript 基准。Mugshot 捕获所有事件,以确定地重放 web 应用程序的执行。Ripley 在服务器端副本上复制客户端 JavaScript 程序的执行。

七 结论

Jalangi 已经处理了 JavaScript 的各种具有挑战性的细节。由于可以处理 JavaScript 的所有令人担忧的问题,因此可以轻松地在 Jalangi 框架中实施动态分析。我们期望 Jalangi 将有助于未来 JavaScript 动态分析的研究。

致谢

本文由南京大学软件学院 2020 级硕士李彤宇转述翻译 感谢国家重点研发计划(2018YFB1003900)和国家自然科学基金(61832009,61932012)支持!


分享到:


相關文章: