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 构建的主要内容,如果未能解决你的问题,请参考以下文章

soot 静态分析框架Soot lambda 构建

Soot 静态分析框架Soot 过程分析

Soot 静态分析框架Soot 过程分析

Soot 静态分析框架Soot 过程分析

Soot 静态分析框架Soot的核心

Soot 静态分析框架Soot的核心