我正在写一个IntelliJ-Plugin来分析java程序代码.因此我使用Soot编写静态分析.每次用户触发我的插件的分析操作时,我都会获取VirtualFile当前上下文的当前内容,如下所示:
FileEditorManager manager = FileEditorManager.getInstance(e.getProject());
VirtualFile files[] = manager.getSelectedFiles();
toAnalyse = files[0]; [...]
Run Code Online (Sandbox Code Playgroud)
当我检查此文件的内容时,将应用所有更改.在此之后,我正在加载我想在Soot中分析的课程.
String dir = toAnalyse.getParent().getPath() ;
Options.v().setPhaseOption("jb", "use-original-names");
Options.v().set_soot_classpath( System.getProperty("java.home")+";"+ dir);
c = Scene.v().loadClassAndSupport(name);
/*no analyse c*/
Run Code Online (Sandbox Code Playgroud)
这对我来说非常适合.但现在我的问题是:如果我改变某事.在我的插件的测试实例中,再次触发相同的分析,没有任何变化.
到目前为止我尝试了什么?
我设置了以下选项:
Options.v().set_dump_body( Arrays.asList("jb"));
Options.v().set_dump_cfg( Arrays.asList("jb"));
Options.v().set_allow_phantom_refs(true);
Options.v().set_whole_program(true);
Run Code Online (Sandbox Code Playgroud)
我也手动删除了所有课程
像这样:
Chain<SootClass> classes = Scene.v().getClasses();
Stack<SootClass> stack = new Stack<>();
for(SootClass s : classes)
stack.push(s);
while(!stack.empty())
Scene.v().removeClass(stack.pop());
Run Code Online (Sandbox Code Playgroud)
并再次启动该程序.
我正在使用 Java 进行一些非常简单的程序分析/转换Soot在 Java 中进行一些非常简单的程序分析/转换,并且我发现自己需要对布尔表达式进行一些简单的组合。例如,在我的分析过程中,我将有一个像这样的表达式(a < 25) && (b >= 10),我想(a >=-10)通过 OR 运算符将该表达式与 结合起来以获得像这样的完整表达式(a >=-10) || (a < 25) && (b >= 10)。基本上,只是将两个布尔表达式树组合成一个表达式。我可能还希望自动将表达式树转换为树的等效连接范式版本。
我的另一个要求是当我们有可以轻松消除的表达式时能够简化表达式(如果需要,可以通过自定义代码)。例如(a < 20) || (a >= 20)简化为TRUE、since (a < 20) = (!(a >= 20)),因此我们可以随时消除一些项。
我知道编写布尔表达式树是一个经典的介绍性问题,而且我很确定我以前已经实现过它(很久以前,对于数据结构类:))我知道我可以再做一次,如果需要......但考虑到这可能是以前处理过的事情,我想知道是否有关于我应该研究的库来解决上述问题的任何建议。我讨厌重新发明轮子,因为可能已经有一个非常好的轮子了。
总而言之,我正在寻找一个具有以下功能的 Java 库:
有什么建议吗?
(注意:我不会评估这些树,因此每个节点都将是未解析的谓词,例如variable != 20or foo >= 50,因此评估不是必需的,但如果它是库的一部分,也不会造成伤害。)
我使用烟灰库.
在不同的例子我看到.v()的方法,例如Jimple.v(),scene.v(),....
现在我想问这是什么意思?特别在Jimple.v().
比方说我有一个
class Foo(){
public final static int bar = -1;
}
Run Code Online (Sandbox Code Playgroud)
反汇编的字节码看起来像这样
super public class Foo
version 51:0
{
public static final Field bar:I = int -1;
public Method "<init>":"()V"
stack 1 locals 1
{
aload_0;
invokespecial Method java/lang/Object."<init>":"()V";
return;
}
} // end Class Foo
Run Code Online (Sandbox Code Playgroud)
是的,这让我感到惊讶.我本来期望有一个<clinit>包含赋值的方法bar,然后我可以替换它.(当我删除final修饰符时会发生这种情况.)
如何更改final字段的值?我该怎么做?
我想使用Soot对Java程序进行静态分析,包括例如控制流程图.
各种教程都说使用Soot的"标准方法"是创建一个main方法,其中一个将自定义转换添加到Soot管道,然后调用soot.Main.main(...):
public static void main(String[] args) {
PackManager.v().getPack("jtp").add(
new Transform("jtp.gotoinstrumenter", GotoInstrumenter.v()));
soot.Main.main(args);
}
Run Code Online (Sandbox Code Playgroud)
当然,如果你想在命令行工具之外使用Soot,这有一些严重的限制.例如,我不清楚在程序中多次调用Soot的主要方法是否合法.
那么有没有人知道有可能通过一个更复杂的API直接使用Soot分析工具?
我正在通过SOOT-ECLIPSE插件作为主类设置一个类,并希望它像单例一样运行.但是我的实现似乎不起作用,因为每次运行都会得到不同的实例.
我试图使用包装器并从那里调用单例类,以避免这个类被soot的类加载器垃圾收集的情况.但我也得到了不同的实例.
我确认它在一个JVM上运行,因为我在每次运行时获得的PID与每次运行时更改的类的实例相同.
我真的很感激对这一点的任何见解.
public class MyMain{
private static boolean isFirstInstance = true;
private static class MyMainHolder {
private static final MyMain INSTANCE = new MyMain();
}
public static synchronized MyMain getInstance() {
return MyMainHolder.INSTANCE;
}
private MyMain() {
if (MyMainHolder.INSTANCE != null) {
throw new IllegalStateException("Already instantiated");
}
}
public static void main(String[] args) {
System.out.println("PID: " + ManagementFactory.getRuntimeMXBean().getName());
MyMain tmp = getInstance();
}
Run Code Online (Sandbox Code Playgroud)