java - 使用 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”文件并获得这两个虚拟边。我怎样才能做到这一点?我应该设置什么参数?非常感谢!
解决方案
推荐阅读
- ios - How to optimize memory for very long navigation stack of UIViewControllers
- ruby-on-rails - One to Many To Many: One user has many store. One store has many products
- java - Hibernate 事务管理比较
- javascript - 使用 Vanilla Javascript 关闭多个弹出消息框
- javascript - 如何在 javascript 中使用 map 函数迭代嵌套字典
- javascript - 比较键后如何将对象列表转换为嵌套对象
- firebase - react-native-firebase:根据用户设置显示 firebase 通知
- xamarin.android - 在 Xamarin Android 设计器页面 (main.axml) 中找不到字体资产异常
- jenkins - 如何获得当前詹金斯构建管道代码的结束时间?
- r - 使用不在 Task Scheduler R 环境中的变量