soot 静态分析框架Soot lambda 构建
Posted raintungli
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了soot 静态分析框架Soot lambda 构建相关的知识,希望对你有一定的参考价值。
1. JVM 的 Lambda构建
和JVM构建Lambda的方式不同,因为Lambda表达式的类是一个运行的时候动态生成的类,是通过新的JVM的指令集InvokeDynamic来实现,通过调用java/lang/invoke/LambdaMetafactory.metafactory去生成动态的内部Class,在Class里面封装了实现的抽象方法,在抽象方法里实现了对源类的静态方法package.classname.lambda$0的调用,Lambda里的实现的逻辑就在package.classname.lambda$0里,生成的动态的class里直接调用原类的静态的私有方法 package.classname.lambda$0
关于JVM如何构建Lambda表达式具体细节可参考博客(https://blog.csdn.net/raintungli/article/details/54910152),本篇博客就不在阐述。
2. Soot Lambda构建
因为Soot是静态分析工具,对JVM运行时后生成的类不能等到JVM运行的时候生成后进行分析,只能先提前生成。
Soot自己也封装了LambdaMetaFactory中,首先生成一个内部类package.classname.$lambda_0__1实现了你的接口myinterface,里面分装了a. bootstrap$()
public static myinterface bootstrap$()
package.classname$lambda_0__1 $r0;
$r0 = new pointto.testContainer$lambda_0__1;
specialinvoke $r0.< package.classname$lambda_0__1: void <init>()>();
return $r0;
|
初始化了类package.classname$lambda_0__1类,并返回
b. init的方法
public void <init>()
pointto.testContainer$lambda_0__1 $r0;
$r0 := @this: pointto.testContainer$lambda_0__1;
specialinvoke $r0.<java.lang.Object: void <init>()>();
return;
|
调用Object的init方法,所有类都继承object 需要在函数里调用object 的init方法
c.实现的接口的方法
public void method(java.lang.Object)
package.classname $lambda_0__1 $r0; java.lang.Object $r1; java.lang.String $r2;
$r0 := @this: package.classname$lambda_0__1;
$r1 := @parameter0: java.lang.Object;
$r2 = (java.lang.String) $r1;
staticinvoke <package.classname: void lambda$0(java.lang.String)>($r2);
return;
|
其本质和JVM一样就是调用package.classname.lambda$0的方法
这里和JVM不同的是,动态生成的类是在分析过程中直接虚拟生成的,和java的生成的类不同的是没有bootstrap$这个方法,调用方式也不一样
jvm是
0: invokedynamic #30, 0 // InvokeDynamic #0:accept:()Ljava/util/function/Consumer; |
而soot里就是直接调用了 bootstrap$的方法
staticinvoke <pointto.testContainer$lambda_0__1: java.util.function.Consumer bootstrap$()>(); |
个人觉的可以直接调用private static void lambda$0(java.lang.String);来构建call graph
以上是关于soot 静态分析框架Soot lambda 构建的主要内容,如果未能解决你的问题,请参考以下文章