哪种静态分析工具用于扫描从一种方法到另一种方法的数据流?

时间:2012-05-06 19:58:28

标签: java static-analysis findbugs pmd

假设我的库中有两种方法:

void com.somepackage.SomeClass.someSink(String s)

int com.someotherpackage.SomeOtherClass.someSource(int i)

第一种方法用作数据接收器,第二种方法用作我的代码中的数据源。类型参数int, String仅作为示例给出,可能会在实际情况中发生变化。

我想在某些满足以下特定模式的代码中检测这些方法的用法:

  1. 生成了一些数据(比如x
  2. 使用一系列转换生成一些数据(比如说yf1(f2(... fn(x))
  3. y被提供给接收器。
  4. 转换可以是任意函数,只要存在从函数调用的序列,该函数生成接收器的数据到从源接收数据的函数。这些函数也可以采用任何其他参数,并用作黑盒子。

    扫描可以是源或字节码级别。有哪些工具可用于此类分析?

    首选基于非IDE的工具和Java API。

    [编辑:]澄清更多内容,someSinksomeSource分别是类SomeSomeSomeOtherClass中的任意方法名称。它们可能是static,也可能不是MyClass1.java:12: value1 = com.someotherpackage.SomeOtherClass.someSource(...) MyClass2.java:23: value2 = foo(value1, ...) MyClass3.java:3: value3 = bar(value2) MyClass4.java:22: com.somepackage.SomeClass.someSink(value3, ...) ,可能需要任意数量的参数(我应该能够定义)。参数的类型也不是任意的。唯一的要求是该工具应扫描代码并输出模式出现的行号。因此该工具可能会以这种方式工作:

    • 从用户处获取接收器和源名称(类和方法名称的完全限定名称)。
    • 静态扫描代码并查找使用给定接收器和源的所有位置
    • 检查是否存在路径,其中某些数据源输出直接或间接通过一系列操作(运算符,方法)接收。
    • 忽略那些不存在此类路径的源/接收器并输出剩余的路径(如果有的话)。

    示例输出:

    a = source(); void foo(){ c = a+b }; foo(); sink(c)

    注意:如果函数不接受参数但对数据有一些副作用,则还需要考虑。 (示例{{1}}是需要捕获的模式。)

2 个答案:

答案 0 :(得分:3)

在做了一些研究之后,我发现soot最适合这类任务。 Soot比其他开源替代品(如PQL)更成熟。

答案 1 :(得分:2)

因此,源和接收方法的作用很简单,x源自源方法(某处)并在目标方法中消耗(某处)?你如何描述“x”,或者你只是想要所有具有这种属性的x?

假设您已在源方法中识别出特定的x,那么a)是否坚持通过方法调用将x传递给目标方法 [这会使目标方法成为最后一次调用您的调用链],还是可以复制其中一个中间值? b)坚持每个函数调用都有一个参数?

我们为大型C系统做过类似的事情。问题是将指定的变量跟踪到其他函数中的使用,包括它们可能存在的其他函数,包括表示不相同但意图相同的值(“抽象复制”;如果我使用,字符串“1.0”抽象地等于整数1字符串最终作为数字;“int_to_string”是一个“抽象复制”函数,它将一个表示中的值转换为另一个表示中的等价值。)。

我们需要的是对每个函数进行定义分析(“特定赋值的值从何而来?”)和“抽象副本”到达分析,该分析确定特殊函数消耗到达值的位置标记为“抽象副本”,以及该抽象复制函数的结果到达的位置。然后计算x可以去的“x到达z”和“x到达f(x)到达z”的传递闭包。

我们使用提供通用解析和流分析机制的DMS Software Reengineering Toolkit和DMS C Front End来实现这一点,它实现了C的特定到达和抽象复制到达计算.DMS有{ {3}}计算到达定义;一个人可以添加abstact-copy-reaching逻辑并重新实现传递闭包代码。