首页 > 解决方案 > 使用 soot 生成调用图?

问题描述

最近我尝试使用 soot 为一个类生成一个调用图:

public class Main {
    public static void main(String[] args) {
        System.out.println("A-1.0 main call B-1.0 C-2.0");
        BClass b = new BClass();
        b.B1_0_func();
        b.B1_0_func1();
        CClass c = new CClass();
        c.C1_1_func();
    }
}

而soot生成的Jimple代码如下:

public class Main extends java.lang.Object
{

    public void <init>()
    {
        Main r0;

        r0 := @this: Main;

        specialinvoke r0.<java.lang.Object: void <init>()>();

        return;
    }

    public static void main(java.lang.String[])
    {
        java.io.PrintStream $r0;
        BClass $r1;
        CClass $r3;
        java.lang.String[] r5;

        r5 := @parameter0: java.lang.String[];

        $r0 = <java.lang.System: java.io.PrintStream out>;

        virtualinvoke $r0.<java.io.PrintStream: void println(java.lang.String)>("A-1.0 main call B-1.0 C-2.0");

        $r1 = new BClass;

        specialinvoke $r1.<BClass: void <init>()>();

        virtualinvoke $r1.<BClass: void B1_0_func()>();

        virtualinvoke $r1.<BClass: void B1_0_func1()>();

        $r3 = new CClass;

        specialinvoke $r3.<CClass: void <init>()>();

        virtualinvoke $r3.<CClass: void C1_1_func()>();

        return;
    }
}

如您所见,有一个名为“Main”的类具有“main”方法。我将它编译为目录“C:\Works\javaworks\A4\A\target\classes”中名为“Main.class”的类文件。“BClass”类不属于这个“Main.class”文件。我使用 soot 来计算 Main.class 的调用图。命令行内容为“-allow-phantom-refs -w -ire -process-dir C:\Works\javaworks\A4\A\target\classes”。我使用 CHATransformer 生成调用图,结果如下:

CLINIT edge: $r0 = <java.lang.System: java.io.PrintStream out> in <Main: void main(java.lang.String[])> ==> <java.lang.System: void <clinit>()>
CLINIT edge: $r0 = <java.lang.System: java.io.PrintStream out> in <Main: void main(java.lang.String[])> ==> <java.lang.Object: void <clinit>()>
SPECIAL edge: specialinvoke r0.<java.lang.Object: void <init>()>() in <Main: void <init>()> ==> <java.lang.Object: void <init>()>
SPECIAL edge: specialinvoke $r1.<BClass: void <init>()>() in <Main: void main(java.lang.String[])> ==> <BClass: void <init>()>
SPECIAL edge: specialinvoke $r3.<CClass: void <init>()>() in <Main: void main(java.lang.String[])> ==> <CClass: void <init>()>

很明显main方法调用了BClass类的B1_0_func()方法和B1_0_func1()方法,但是调用图中并没有显示出来。我需要调用图来包含以下边缘:

VIRTUAL edge: virtualinvoke r2.<BClass: void B1_0_func()>() in <Main: void main(java.lang.String[])> ==> <BClass: void B1_0_func()>
VIRTUAL edge: virtualinvoke r2.<BClass: void B1_0_func1()>() in <Main: void main(java.lang.String[])> ==> <BClass: void B1_0_func1()>

但我不想添加其他“-process-dir”参数。我只想处理这个“Main.class”文件并获得这两个虚拟边。我怎样才能做到这一点?我应该设置什么参数?非常感谢!

标签: javasoot

解决方案


推荐阅读