SootUp icon indicating copy to clipboard operation
SootUp copied to clipboard

Support MethodHandle Resolve in Callgraph Algorithm

Open tisble opened this issue 1 year ago • 4 comments

Hi, I used SootUp to analyze the following code example from my project and found a bug abou handling lambda invocation:

package org.me;
public class Test {
    public void m1() {
        Runnable runnable = this::m2;
        runnable.run();  // invoke m2
    }
    public void m2() {
        System.out.println("m2");
    }
}

Considering line 4 and line 7, SootUp should report an edge from m1 to m2, but it missed.

Version: develop-5af272dcda

My Code to Invoke SootUp

AnalysisInputLocation javaBaseInputLocation = new JavaClassPathAnalysisInputLocation("JDK_PATH", SourceType.Library);
AnalysisInputLocation classInput = new JavaClassPathAnalysisInputLocation("INPUT_PATH", SourceType.Application);
ArrayList<AnalysisInputLocation> allInput=new ArrayList<>();
allInput.add(classInput);
allInput.add(javaBaseInputLocation);
JavaView view = new JavaView(allInput);

List<String> EntrySignatures=new ArrayList<>();
EntrySignatures.add("<org.me.Test: void m1()>");
EntrySignatures.add("<org.me.Test: void m2()>");
List<MethodSignature> entryMethods = new ArrayList<>();
for(String EntrySignature:EntrySignatures){
    for (JavaSootClass klass : view.getClasses()) {
        for (JavaSootMethod method : klass.getMethods()) {
            if (method.getSignature().toString().equals(EntrySignature)) {
                entryMethods.add(method.getSignature());
            }
        }
    }
}
CallGraphAlgorithm rta = new RapidTypeAnalysisAlgorithm(view);
CallGraph cg = rta.initialize(entryMethods);

tisble avatar Apr 08 '24 08:04 tisble

that is an indirect edge which is currently not covered. I even wonder how other static analysis frameworks perform on this code

JonasKlauke avatar Apr 08 '24 09:04 JonasKlauke

Hi @JonasKlauke. I tried Wala and found it can generate the following edges to build the call:

org.me.Test.m1()V --> wala.lambda$org$me$Test$0.run()V wala.lambda$org$me$Test$0.run()V --> org.me.Test.m2()V

It seems that Wala can handle the lambda here. Hope this can help you.

tisble avatar Apr 08 '24 13:04 tisble

 public void m1();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=1
         0: aload_0
         1: invokedynamic #2,  0              // InvokeDynamic #0:run:(LTest;)Ljava/lang/Runnable;
         6: astore_1
         7: aload_1
         8: invokeinterface #3,  1            // InterfaceMethod java/lang/Runnable.run:()V
        13: return

BootstrapMethods:
  0: #19 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #20 ()V
      #21 invokevirtual Test.m2:()V
      #20 ()V

If you look at the bytecode you see that m2 is not called directly. A methodhandle is created and you see as one of the Method arguments that Test.m2 is called. SootUp currently does not support MethodHandle resolving. Wala seems to have already some MethodHandle support.

JonasKlauke avatar Apr 08 '24 14:04 JonasKlauke

A similar issue is shown in #917

JonasKlauke avatar Apr 15 '24 08:04 JonasKlauke