论文部分内容阅读
随着软件不断的演化和发展,软件的复杂性日益增加,对软件的理解和推理变得愈加困难。软件复杂度来源于很多因素,包括代码含义的模糊、代码相互依赖和软件中潜在的恶意负载等。软件复杂度随着这些因素不断递增,对软件正确性和可靠性提出巨大挑战。对程序进行分析和检测是人们理解软件的重要方法。对程序性质的分析一般是从静态的视角去分析程序代码,尤其是带有指针和递归数据结构的程序所满足的递归性质,建立其与前后置条件之间的关系,从而可以帮助人们理解程序代码的含义。分析和理解程序含义的另一个重要方面是局部推导,即对一段程序代码的理解仅限于这段代码本身,而不需要了解其它模块的含义。这意味着程序的分析难度与代码之间相互依赖关系成正比。对于面向对象程序来说,封装性是重要的依赖关系解耦手段,是实现局部推导的重要基础。现实中很多面向对象程序因为多种因素,如快速迭代和需求变化等,面临封装性缺失的问题。因此系统性地评估封装性对面向对象程序的性质分析具有非常重要的意义。另外,软件中普遍存在的隐藏恶意负载也使得软件的行为逻辑变得复杂。即使一个程序满足了功能性需求,它的非功能性负载也会对软件的质量和可靠性带来很大威胁。近年来,相当一部分的安卓恶意应用利用WebView技术允许Java代码和JavaScript代码相互调用的特性,有意地将自己的恶意负载分散在跨语言的特性中,并且设定较为严苛的触发条件,使得这类行为难以被现有方法系统性地分析和检测出来。在此背景下,本文针对上面指出的与软件复杂度相关的三个问题,即程序递归性质难以分析的问题、面向对象程序中封装性缺失带来依赖性问题和软件中潜在的恶意负载难以检测的问题,展开研究,主要工作包括以下三个方面。1.提出了一种分析程序中指针和递归数据结构性质的框架。框架分为3个主要部分。首先,我们将递归数据结构的性质分为两个主要类别,并提出对应的处理模式,从而帮助简化对于程序中的递归数据结构上的相关性质的分析。其次,提出了一种称为分割与拼接的技术来发现和描述递归数据结构是如何被程序修改的:递归数据结构首先被分割为若干个互不相交的片段,然后,这些片段以新的方式重新拼接在一起,形成一个新的数据结构。这个技术的重点在于如何将程序原有的性质保留下来,从而为后面的分析过程所使用。最后,提出了一种调用上下文敏感的程序摘要过程间分析方法。案例分析和实验结果表明:分析框架可以有效地分析递归数据结构的性质,并生成对程序证明过程有用的断言。2.提出了一种分析和评估面向对象程序封装性的技术。这个技术扩展了在编译器优化中被广泛采用的逃逸分析技术,通过基于表达式的数据流分析去计算面向对象程序的运行时内存布局。这个分析技术能够有效地将面向对象程序中常见的内存问题检测出来,从而得出对面向对象程序的封装性的评价。具有良好封装特性的类更加易于分析和验证。对于封装性较差的类,分析结果会给出建议的重构方法帮助开发人员完善类的设计和实现。3.提出了一种通过跨语言强制执行技术检测软件中隐藏恶意行为的技术。这个技术针对安卓Web View恶意应用,其核心在于对安卓Web View应用中的Java和JavaScript代码同时进行强制执行,使得程序根据需要往不同的路径执行,而不需要任何环境搭建和手动输入。通过这个技术,我们能将WebView中隐藏的恶意行为强制性地暴露出来。为了解决强制执行可能导致的异常问题,提出了一种新型的执行模型,使得程序能够检测出异常,并从异常中恢复执行。此外,这个执行模型还能够按需要为程序执行提供必要的输入。实验结果显示,跨语言强制执行技术能够高效且准确地在150个随机挑选的安卓WebView应用中发现包含恶意行为的119个应用,对于WebView恶意行为的检测能力高于现有的相关技术约23%.本文针对导致软件复杂性的三个问题,分别从不同的角度提出了检测和分析方法。我们相信这些分析方法为解决程序分析与检测中的若干问题做出了一定贡献,为程序理解和推理提供了有效支持。