假设我的库中有两种方法:
void com.somepackage.SomeClass.someSink(String s)
和
int com.someotherpackage.SomeOtherClass.someSource(int i)
第一种方法用作数据接收器,第二种方法用作我的代码中的数据源。类型参数int, String
仅作为示例给出,可能会在实际情况中发生变化。
我想在某些满足以下特定模式的代码中检测这些方法的用法:
x
)
y
)f1(f2(... fn(x))
y
被提供给接收器。转换可以是任意函数,只要存在从函数调用的序列,该函数生成接收器的数据到从源接收数据的函数。这些函数也可以采用任何其他参数,并用作黑盒子。
扫描可以是源或字节码级别。有哪些工具可用于此类分析?
首选基于非IDE的工具和Java API。
[编辑:]澄清更多内容,someSink
和someSource
分别是类SomeSome
和SomeOtherClass
中的任意方法名称。它们可能是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}}是需要捕获的模式。)
答案 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逻辑并重新实现传递闭包代码。