Soot - A Java optimization framework

Overview

Build Status Gitpod Ready-to-Code

Using Soot? Let us know about it!

We are regularly applying for funding to help us maintain Soot. You can help us immensely by letting us know about projects that use Soot, both commercially or in the form of research tools.

Also many thanks to JProfiler for supporting Soot with a free-to-use open source license!

Thanks to our Sponsors...

... for supporting the further Development of Soot! Amazon Web Services is a Gold Sponsor. AWS

Read more here about how to become a sponsor on your own.

Soot supports Java 9 modules now!

Try and get involved in Soot's Java 9 bleeding edge developement.

What works and is tested?

  • Automatic modules (modules automatically created from jars in the module-path)
  • Named modules
  • Exploded modules
  • Modular jar files
  • Resolving modules in Soot's ModuleScene
  • Spark

What does not work yet?

  • Anonymous modules (mixing module- and class-path)
  • Multi-module jar files

What is Soot?

Soot is a Java optimization framework. It provides four intermediate representations for analyzing and transforming Java bytecode:

  • Baf: a streamlined representation of bytecode which is simple to manipulate.
  • Jimple: a typed 3-address intermediate representation suitable for optimization.
  • Shimple: an SSA variation of Jimple.
  • Grimp: an aggregated version of Jimple suitable for decompilation and code inspection.

See https://soot-oss.github.io/soot for details.

How do I get started with Soot?

We have some documentation on Soot in the wiki and also a large range of tutorials on Soot.

For detailed information please also consider the Soot's JavaDoc and Options Documentations.

Including Soot in your Project

A Soot release is currently built for each commit to the master branch. You can include Soot as a dependency via Maven, Gradle, SBT, etc using the following coordinates:

<dependencies>
  <dependency>
    <groupId>org.soot-oss</groupId>
    <artifactId>soot</artifactId>
    <version>4.2.1</version>
  </dependency>
</dependencies>

You can also obtain older builds of the master branch. A complete listing of builds can be found on Maven Central.

A Soot SNAPSHOT is currently built for each commit to the develop branch. You can include Soot as a dependency via Maven, Gradle, SBT, etc using the following coordinates:

<dependencies>
  <dependency>
    <groupId>org.soot-oss</groupId>
    <artifactId>soot</artifactId>
    <version>4.3.0-SNAPSHOT</version>
  </dependency>
</dependencies>
<repositories>
  <repository>
      <id>sonatype-snapshots</id>
      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
      <releases>
          <enabled>false</enabled>
      </releases>
  </repository>
</repositories>	

You can also obtain older builds of the develop branch. A complete listing of builds can be found on Maven Central.

How do I obtain Soot without Maven?

We recommend using Soot with Maven You can obtain the latest release build of Soot directly. You can obtain the latest SNAPSHOT build of Soot directly.

The soot-<RELEASE>-jar-with-dependencies.jar file is an all-in-one file that also contains all the required libraries.

The soot-<RELEASE>.jar file contains only Soot, allowing you to manually pick dependencies as you need them. If you do not want to bother with dependencies, we recommend using the former.

Building Soot yourself

If you cannot work with the prebuild versions and need to build Soot on your own, please consider the wiki for further steps.

About Soot's source code

Soot follows the git-flow convention. Releases and hotfixes are maintained in the master branch. Development happens in the develop branch. To catch the bleeding edge of Soot, check out the latter. In case of any questions, please consult the Soot mailing list at: http://www.sable.mcgill.ca/mailman/listinfo/soot-list/

How do I contribute to Soot?

We are happy to accept arbitrary improvements to Soot in form of GitHub pull requests. Please read our contribution guidelines before setting up a pull request.

Please help us improve Soot!

You are using Soot and would like to help us support it in the future? Then please support us by filling out this little web form.

That way you can help us in two ways:

  • By letting us know how we can improve Soot you can directly help us prioritize newly planned features.
  • By stating your name and affiliation you help us showcasing Soot’s large user base. Thanks!

How to use Soot's Java 9 Features?

If you want to run Soot with Java > 8, you are done. Just run it as usal. If you want to execute Soot with Java 8 but analyze Java >8 Projects or vice versa, see below.

Use from Source Code

To load modules in Soot's ModuleScene from java:

// configure Soot's options, refer to example configurations below
Options.v().set_soot_modulepath(modulePath);


// load classes from modules into Soot
// Here, getClassUnderModulePath() expects the module path to be set using the Options class as seen above
Map<String, List<String>> map = ModulePathSourceLocator.v().getClassUnderModulePath(modulePath);
for (String module : map.keySet()) {
   for (String klass : map.get(module)) {
       logger.info("Loaded Class: " + klass + "\n");
       loadClass(klass, false, module);
       // the loadClass() method is defined below
   }
}


//this must be called after all classes are loaded
Scene.v().loadNecessaryClasses();


public static SootClass loadClass(String name, boolean main, String module) {
     SootClass c = ModuleScene.v().loadClassAndSupport(name, Optional.of(module));
     c.setApplicationClass();
     if (main)
         Scene.v().setMainClass(c);
     return c;
}

ModuleUtil.module_mode() helps you check whether you have modules enabled in Soot. This is done based on whether the module path is set using the Options class.

Example Configurations: Java 8, Java >= 9 Classpath, Java >= 9 Modulepath

if(java < 9 ) { // when you have a target benchmark with Java < 9 and hence no modules
    Options.v().set_prepend_classpath(true);
    Options.v().set_process_dir(Arrays.asList(applicationClassPath().split(File.pathSeparator)));
    Options.v().set_soot_classpath(sootClassPath());
}

if(java >= 9 && USE_CLASSPATH) { // when you have a target benchmark with Java >= 9 and do not want module support
    Options.v().set_soot_classpath("VIRTUAL_FS_FOR_JDK" + File.pathSeparator + sootClassPath());
    Options.v().set_process_dir(Arrays.asList(applicationClassPath().split(File.pathSeparator)));
}


if(java>=9 && USE_MODULEPATH) { // when you have a target benchmark with Java >= 9 and want module support
    Options.v().set_prepend_classpath(true);
    Options.v().set_soot_modulepath(sootClassPath());
    Options.v().set_process_dir(Arrays.asList(applicationClassPath().split(File.pathSeparator)));
}

In the above examples, applicationClassPath() should be replaced with the path to the application classes for analysis by Soot and sootClassPath() should be replaced with the Soot classpath.

Use from the Command Line

To execute Soot using Java 1.9, but analyzing a classpath run, just as before: java -cp soot-trunk.jar soot.Main --process-dir directoryToAnalyse

if you want to specify the classpath explicitly run: java -cp soot-trunk.jar soot.Main -cp VIRTUAL_FS_FOR_JDK --process-dir directoryToAnalyse

the value VIRTUAL_FS_FOR_JDK indicates that Soot should search Java's (>9) virtual filesystem jrt:/ for classes, too, although Soot is not executed in module mode.

To load modules and classes in Soot using java 1.8 run:

java -cp PATH_TO_JAVA9/jrt-fs.jar:soot-trunk.jar soot.Main -pp -soot-modulepath modules/

Please replace PATH_TO_JAVA9 with the path to your local installation of java 9. The jrt-fs.jar is a built-in NIO FileSystem provider for the jrt:// filesystem java 9 uses that replaces rt.jar.

Comments
  • Jasmin errors while transforming APK to Java class

    Jasmin errors while transforming APK to Java class

    Command: java -Xms512m -jar soot.jar -allow-phantom-refs -src-prec apk -android-jars C:/android/sdk/platforms -outjar -process-dir a.apk

    Error: r.class Writing to kawa\lang\Pattern.class Writing to com\google\devtools\simple\runtime\components\android\ContactPicker.c lass Jasmin:20: Warning - Syntax error.

    ^ Jasmin:20: Error - Couldn't repair and continue parse.

    ^ Jasmin: Found 2 errors Writing to com\google\devtools\simple\runtime\variants\IntegerVariant.class Writing to com\google\devtools\simple\runtime\components\android\ListPickerActiv ity.class Writing to twitter4j\TwitterStream$StreamHandlingThread.class

    I also get the error at different points while writing different classes. below is the list.

    Other places where it gives error: Jasmin:20: Warning - Syntax error. Jasmin:20: Error - Couldn't repair and continue parse. Jasmin: Found 2 errors Jasmin:19: Warning - Syntax error. Jasmin:19: Error - Couldn't repair and continue parse. Jasmin: Found 2 errors Jasmin:25: Warning - Syntax error. Jasmin:25: Error - Couldn't repair and continue parse. Jasmin: Found 2 errors Jasmin:22: Warning - Syntax error. Jasmin:22: Error - Couldn't repair and continue parse. Jasmin: Found 2 errors Jasmin:21: Warning - Syntax error. Jasmin:21: Error - Couldn't repair and continue parse. Jasmin: Found 2 errors Jasmin:23: Warning - Syntax error. Jasmin:23: Error - Couldn't repair and continue parse. Jasmin: Found 2 errors Jasmin:26: Warning - Syntax error. Jasmin:26: Error - Couldn't repair and continue parse. Jasmin: Found 2 errors Jasmin:24: Warning - Syntax error. Jasmin:24: Error - Couldn't repair and continue parse. Jasmin: Found 2 errors

    bug Dexpler / Android-Specific 
    opened by yogiam 42
  • How to insert an android library method  which has not been used in the android application?

    How to insert an android library method which has not been used in the android application?

    Hi all, I am trying to insert an android system method to application but that method has not been used in android application. The insertion steps is as folows.

    1. Prepare arguments
    2. Get SootMethod
    3. Insert the method

    In the second step, I use Scene.v().getMethod to get the Soot method and create the 'InvokeStmt' as follows.

    SootMethod sm = Scene.v().getMethod
                    ("<android.support.v4.app.ActivityCompat: void startPostponedEnterTransition(android.app.Activity)>");
    
    InvokeStmt stm = Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(sm.makeRef(),args));
    units.insertBefore(stm,st);
    

    The problem is, the method Scene.v().getMethod return an exception saying java.lang.RuntimeException: tried to get nonexistent method. I think the problem here is, the method <android.support.v4.app.ActivityCompat: void startPostponedEnterTransition(android.app.Activity)) has not been used in the application (not in the callgraph of the application). Because of that, the method Scene.v().getMethod fires the exception. Is there a way of adding android system method to application which has not been used in the application ? @mbenz89 @ericbodden will you be able to help me ?

    opened by maldil 38
  • Merge defaul Soot and Java 9 Branch

    Merge defaul Soot and Java 9 Branch

    In the long run, we should merge the java 9 branch into the default Soot develop branch to handle JDK9, 10, and 11 in the default Soot implementation.

    The purpose of this PR is to discuss improvements for the Java9 branch before merging it into develop

    enhancement 
    opened by anddann 33
  • Change 35c5b lowers precision by introducing additional aliases

    Change 35c5b lowers precision by introducing additional aliases

    This change: https://github.com/soot-oss/soot/commit/35c5bcb5e72401fcf5a064de5e1c9176b7c13da6 introduces new local variables which lowers our precision since many problems require alias analysis now. See reprod attached. Example:

        public static String entryPoint() {
            ByteBuffer byteBuffer = null;
            try {
                byteBuffer = mySource();
                String hash = methodWithoutEffect(byteBuffer);
                return hash;
            } finally {
                mySink(byteBuffer);
            }
        }
    

    The jimple for the above method used to look as follows:

         label1:
            r4 = staticinvoke <RequiresAlias: java.nio.ByteBuffer mySource()>();
            r0 = staticinvoke <RequiresAlias: java.lang.String methodWithoutEffect(java.nio.ByteBuffer)>(r4);
         label2:
            staticinvoke <RequiresAlias: void mySink(java.nio.ByteBuffer)>(r4);
            return r0;
         label3:
            $r2 := @caughtexception;
            staticinvoke <RequiresAlias: void mySink(java.nio.ByteBuffer)>(r4);
    

    So it was easy to track the taint on byteBuffer by just following r4. With the latest changes, the body looks as follows:

         label1:
            $r0 = staticinvoke <RequiresAlias: java.nio.ByteBuffer mySource()>();
            r3 = $r0;
            $r1 = staticinvoke <RequiresAlias: java.lang.String methodWithoutEffect(java.nio.ByteBuffer)>($r0);
         label2:
            staticinvoke <RequiresAlias: void mySink(java.nio.ByteBuffer)>($r0);
            return $r1;
         label3:
            $r2 := @caughtexception;
            staticinvoke <RequiresAlias: void mySink(java.nio.ByteBuffer)>(r3);
    

    which requires an alias analysis to understand that $r0 and r3 may be aliased in the catch block. This is a little tricky because there is an exceptional edge from mySource where they are not aliased yet, so we would need an alias analysis that does the right thing on control-flow merges at label3, but I don't see how this can be done in IFDS.

    Is there a way to prevent the creation of this aliased variable?

    See reprod attached.

    reprod.zip

    opened by martinschaef 30
  • How to build soot? Update listed dependencies

    How to build soot? Update listed dependencies

    I tried cloning the repo to develop on the Eclipse plugin myself, however, the Eclipse project depends on the soot project, which I was unable to build.

    The README.md says that the project depends on jasmin and heros, I cloned them both and built them.

    Next I got an error about SootJastAddJ being missing. Googling revealed this and I imported the Eclipse project:

    https://svn.sable.mcgill.ca/abc/trunk/JastAddExtensions/
    

    The build of soot now progresses further until the following error:

    eclipse-ee-3.7-indigo-workspace\JastAddExtensions\SootJastAddJ\build.xml:18: taskdef class JFlex.anttask.JFlexTask cannot be found
    

    I don't know how to continue. What do I have to do?

    opened by alshain 27
  • Use linked variants of hash sets and maps.

    Use linked variants of hash sets and maps.

    Overall this patch is straightforward: replacing nearly all instances of three data structures — JDK’s HashMap, HashSet, Hashtable — with their linked variations — LinkedHashMap and LinkedHashSet.

    Aside from that there are only two small changes to keep unit tests passing:

    1. Replacing contains with containsInAnyOrder to remove dependence on container iteration order.
    2. Adding two classes from java.lang.invoke to a list of distinguished “basic” classes.
    opened by michael-emmi 25
  • Supports AnySubType for reaching types

    Supports AnySubType for reaching types

    Our previous implementation only worked on concrete reference types. Under Spark this was a MOSTLY a fine assumption, except that the native simulators handlers could still introduce anysubtype types into the PAG.

    This commit correctly handles this and, in principle, opens the door for types-for-invoke to be used with the CHA builder. However, the machinery to plug into the CHA is not written (yet).

    opened by jtoman 25
  • Objectweb ASM based front end.

    Objectweb ASM based front end.

    • Standardized some methods in soot.util.MultiMap
    • Added table data structure (soot.util.Table), and a hashmap based implementation.
    • Moved from coffi to asm
    opened by amiftah 25
  • Instrumented applications crash when running in android phone/emulator after instrumentation .

    Instrumented applications crash when running in android phone/emulator after instrumentation .

    Hi everyone, I am in the process of android application instrumentation. The problem is the application is crashed when I open the application after successful installation in both emulator and phone. What I did was,

    1. Changed the application with soot
    2. Singed the application
    3. Aligned the application
    4. Installed in phone and the emulator
    5. Open the application Application doesn't responded.

    Debugging procedure

    1. Removed the instrumentation code and did only the code transformation part. (removed the code in internalTransform(String s, Map<String, String> map)).
    2. Singed the application
    3. Aligned the application
    4. Installed and opened the application Hence, we can conclude the application crashed even just with transformation (without modification).

    Below is my instrumentation settings

            PackManager.v().getPack("wjtp").add(new Transform("wjtp.myAnalysis", new APKDSceneTransformer(finalChangingMethods)));
            PackManager.v().runPacks();
            PackManager.v().writeOutput();
    

    Below is the stack trace in log cat

    25 14:26:46.960 1328-1613/? W/audio_hw_generic: Not supplying enough data to HAL, expected position 3127472 , only wrote 2991025
    11-25 14:26:47.786 1626-2167/? I/ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=yogi.corporationapps.telescope.bigzoomhd/.HomeActivity (has extras)} from uid 10009 on display 0
    11-25 14:26:47.797 1626-1642/? W/BroadcastQueue: Permission Denial: broadcasting Intent { act=com.android.launcher3.action.LAUNCH flg=0x10 (has extras) } from com.android.launcher3 (pid=2005, uid=10009) requires com.google.android.launcher.permission.RECEIVE_LAUNCH_BROADCASTS due to receiver com.google.android.gms/.icing.proxy.ApplicationLauncherReceiver
    11-25 14:26:47.797 1626-1642/? W/BroadcastQueue: Permission Denial: receiving Intent { act=com.android.launcher3.action.LAUNCH flg=0x10 (has extras) } to com.google.android.gms/.chimera.GmsIntentOperationService$GmsExternalReceiver requires com.android.launcher3.permission.RECEIVE_LAUNCH_BROADCASTS due to sender com.android.launcher3 (uid 10009)
    11-25 14:26:47.797 1626-1642/? W/BroadcastQueue: Permission Denial: broadcasting Intent { act=com.android.launcher3.action.LAUNCH flg=0x10 (has extras) } from com.android.launcher3 (pid=2005, uid=10009) requires com.google.android.launcher.permission.RECEIVE_LAUNCH_BROADCASTS due to receiver com.google.android.googlequicksearchbox/com.google.android.search.core.icingsync.ApplicationLaunchReceiver
    11-25 14:26:47.813 1626-1780/? I/ActivityManager: Start proc 3512:yogi.corporationapps.telescope.bigzoomhd/u0a55 for activity yogi.corporationapps.telescope.bigzoomhd/.HomeActivity
    11-25 14:26:47.829 1328-1613/? D/AudioFlinger: mixer(0xb4300000) throttle end: throttle time(11)
    11-25 14:26:47.917 1626-1642/? W/art: Long monitor contention event with owner method=void com.android.server.am.ActivityManagerService.activityPaused(android.os.IBinder) from ActivityManagerService.java:6439 waiters=0 for 118ms
    11-25 14:26:47.929 1236-1687/? D/gralloc_ranchu: gralloc_alloc: Creating ashmem region of size 3686400
    11-25 14:26:47.952 3512-3512/? W/System: ClassLoader referenced unknown path: /data/app/yogi.corporationapps.telescope.bigzoomhd-1/lib/x86
    11-25 14:26:47.970 3512-3512/? I/art: Rejecting re-init on previously-failed class java.lang.Class<yogi.corporationapps.telescope.bigzoomhd.HomeActivity>
    11-25 14:26:47.970 3512-3512/? D/AndroidRuntime: Shutting down VM
    11-25 14:26:47.970 3512-3512/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                     Process: yogi.corporationapps.telescope.bigzoomhd, PID: 3512
                                                     java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{yogi.corporationapps.telescope.bigzoomhd/yogi.corporationapps.telescope.bigzoomhd.HomeActivity}: java.lang.ClassNotFoundException: Didn't find class "yogi.corporationapps.telescope.bigzoomhd.HomeActivity" on path: DexPathList[[zip file "/data/app/yogi.corporationapps.telescope.bigzoomhd-1/base.apk"],nativeLibraryDirectories=[/data/app/yogi.corporationapps.telescope.bigzoomhd-1/lib/x86, /vendor/lib, /system/lib]]
                                                         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2327)
                                                         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                         at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                         at android.os.Handler.dispatchMessage(Handler.java:102)
                                                         at android.os.Looper.loop(Looper.java:148)
                                                         at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                      Caused by: java.lang.ClassNotFoundException: Didn't find class "yogi.corporationapps.telescope.bigzoomhd.HomeActivity" on path: DexPathList[[zip file "/data/app/yogi.corporationapps.telescope.bigzoomhd-1/base.apk"],nativeLibraryDirectories=[/data/app/yogi.corporationapps.telescope.bigzoomhd-1/lib/x86, /vendor/lib, /system/lib]]
                                                         at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
                                                         at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
                                                         at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
                                                         at android.app.Instrumentation.newActivity(Instrumentation.java:1067)
                                                         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2317)
                                                         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                         at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                         at android.os.Handler.dispatchMessage(Handler.java:102)
                                                         at android.os.Looper.loop(Looper.java:148)
                                                         at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                         Suppressed: java.lang.NoClassDefFoundError: yogi.corporationapps.telescope.bigzoomhd.HomeActivity
                                                         at dalvik.system.DexFile.defineClassNative(Native Method)
                                                         at dalvik.system.DexFile.defineClass(DexFile.java:226)
                                                         at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:219)
                                                         at dalvik.system.DexPathList.findClass(DexPathList.java:338)
                                                         at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:54)
                                                                 ... 13 more
                                                         Suppressed: java.lang.ClassNotFoundException: yogi.corporationapps.telescope.bigzoomhd.HomeActivity
                                                         at java.lang.Class.classForName(Native Method)
                                                         at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
                                                         at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
                                                         at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
                                                                 ... 12 more
                                                      Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
    11-25 14:26:47.971 1626-1778/? W/ActivityManager:   Force finishing activity yogi.corporationapps.telescope.bigzoomhd/.HomeActivity
    

    The exception message was java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{yogi.corporationapps.telescope.bigzoomhd/yogi.corporationapps.telescope.bigzoomhd.HomeActivity}: java.lang.ClassNotFoundException: Didn't find class "yogi.corporationapps.telescope.bigzoomhd.HomeActivity"

    I would be really grateful if you can help me on this.

    opened by maldil 24
  • Can SPARK ignore library class?

    Can SPARK ignore library class?

    @StevenArzt Hi! As I see, cg.cha has the phase option "AppOnly" to reduce the call graph edges within library classes. But it seems that there is not any similar options in cg.spark to implement the same function as "AppOnly" does, am I right?

    question 
    opened by moonZHH 23
  • Cannot load JUnit 4.11 JAR file

    Cannot load JUnit 4.11 JAR file

    When trying to load the JUnit 4.11 JAR file, Soot fails in the CG phase. Looking for a cause, I found that the code produced by COFFI contains a type mismatch. Thus, the local splitter cannot find a valid split, type assignment fails to find consistent Java types and that inconsistency is what breaks SPARK in the end.

    In the code below, take a look at label4. i$ is clearly an integer (constant zero when coming from label3) here and it is also used as such in the following integer comparison. If this comparison evaluates to true, we jump to label5 which does nothing except for an unconditional jump to label1. In label1, i$ is however used like an object.

        public void (java.lang.Class)
        {
            unknown this, klass, $stack0, $stack1, $stack2, i$, eachClass, arr$, len$, eachMethod, $stack3, eachField;
    
            this := @this: org.junit.runners.model.TestClass;
            klass := @parameter0: java.lang.Class;
            $stack0 = this;
            specialinvoke $stack0.()>();
            $stack0 = this;
            $stack1 = new java.util.HashMap;
            $stack2 = $stack1;
            specialinvoke $stack2.()>();
            $stack0. = $stack1;
            $stack0 = this;
            $stack1 = new java.util.HashMap;
            $stack2 = $stack1;
            specialinvoke $stack2.()>();
            $stack0. = $stack1;
            $stack0 = this;
            $stack1 = klass;
            $stack0. = $stack1;
            $stack0 = klass;
            if $stack0 == null goto label0;
    
            $stack0 = klass;
            $stack0 = virtualinvoke $stack0.();
            $stack0 = lengthof $stack0;
            $stack1 = 1;
            if $stack0 <= $stack1 goto label0;
    
            $stack0 = new java.lang.IllegalArgumentException;
            $stack1 = $stack0;
            $stack2 = "Test class can only have one constructor";
            specialinvoke $stack1.(java.lang.String)>($stack2);
            throw $stack0;
    
         label0:
            $stack0 = this;
            $stack1 = this;
            $stack1 = $stack1.;
            $stack0 = specialinvoke $stack0.($stack1);
            $stack0 = interfaceinvoke $stack0.();
            i$ = $stack0;
    
         label1:
            $stack0 = i$;
            $stack0 = interfaceinvoke $stack0.();
            if $stack0 == 0 goto label6;
    
            $stack0 = i$;
            $stack0 = interfaceinvoke $stack0.();
            $stack0 = (java.lang.Class) $stack0;
            eachClass = $stack0;
            $stack0 = eachClass;
            $stack0 = staticinvoke ($stack0);
            arr$ = $stack0;
            $stack0 = arr$;
            $stack0 = lengthof $stack0;
            len$ = $stack0;
            $stack0 = 0;
            i$ = $stack0;
    
         label2:
            $stack0 = i$;
            $stack1 = len$;
            if $stack0 >= $stack1 goto label3;
    
            $stack0 = arr$;
            $stack1 = i$;
            $stack0 = $stack0[$stack1];
            eachMethod = $stack0;
            $stack0 = this;
            $stack1 = new org.junit.runners.model.FrameworkMethod;
            $stack2 = $stack1;
            $stack3 = eachMethod;
            specialinvoke $stack2.(java.lang.reflect.Method)>($stack3);
            $stack2 = this;
            $stack2 = $stack2.;
            specialinvoke $stack0.($stack1, $stack2);
            i$ = i$ + 1;
            goto label2;
    
         label3:
            $stack0 = eachClass;
            $stack0 = virtualinvoke $stack0.();
            arr$ = $stack0;
            $stack0 = arr$;
            $stack0 = lengthof $stack0;
            len$ = $stack0;
            $stack0 = 0;
            i$ = $stack0;
    
         label4:
            $stack0 = i$;
            $stack1 = len$;
            if $stack0 >= $stack1 goto label5;
    
            $stack0 = arr$;
            $stack1 = i$;
            $stack0 = $stack0[$stack1];
            eachField = $stack0;
            $stack0 = this;
            $stack1 = new org.junit.runners.model.FrameworkField;
            $stack2 = $stack1;
            $stack3 = eachField;
            specialinvoke $stack2.(java.lang.reflect.Field)>($stack3);
            $stack2 = this;
            $stack2 = $stack2.;
            specialinvoke $stack0.($stack1, $stack2);
            i$ = i$ + 1;
            goto label4;
    
         label5:
            goto label1;
    
         label6:
            return;
        }
    

    Does anyone have an idea on this?

    opened by StevenArzt 22
  • How to analysis implement class of interface in Application

    How to analysis implement class of interface in Application

    I want to analyze program as below

        public void lookup(final String key) throws ScriptException {
           ...
           final ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName(engineName);
    
            scriptEngine.eval(script);
        }
    

    ScriptEngine is an Interface, and soot won't analyze implement class of it. So, What should I do to let Soot analyze all implement classes of interface it meets in applications

    opened by chennbnbnb 4
  • Can Soot analyze multi-threaded application, if so, can you please refer me to a related resource?

    Can Soot analyze multi-threaded application, if so, can you please refer me to a related resource?

    Hello,

    I developed a small CHA Soot tool that plots the Call Graph. The tools work fine on single-threaded applications. Yet, when I introduce a multi-thread application to be plotted, I get the below error.

    Exception in thread "main" java.lang.RuntimeException: Could not load classfile: at soot.coffi.Util.resolveFromClassFile(Util.java:75) at soot.CoffiClassSource.resolve(CoffiClassSource.java:39) at soot.SootResolver.bringToHierarchy(SootResolver.java:215) at soot.SootResolver.bringToSignatures(SootResolver.java:239) at soot.SootResolver.bringToBodies(SootResolver.java:280) at soot.SootResolver.processResolveWorklist(SootResolver.java:150) at soot.SootResolver.resolveClass(SootResolver.java:124) at soot.Scene.loadClass(Scene.java:448) at soot.Scene.loadClassAndSupport(Scene.java:433) at soot.Scene.loadNecessaryClass(Scene.java:1053) at soot.Scene.loadNecessaryClasses(Scene.java:1067) at soot.Main.run(Main.java:167) at soot.Main.main(Main.java:141) at Main.main(Main.java:219)

    I know it is a multi-threading error since the same application works when I extract the concurrency from it. Can Soot be used to analyze multi-threaded applications, if so, can someone please refer me to related articles since I'm assuming it doesn't out-of-the-box?

    Thank you

    opened by omarjarkas1997 0
  • Consider supporting multi-module JAR files

    Consider supporting multi-module JAR files

    Consider supporting multi-module JAR files?Thank you.Forgive me for this broken English Please tell me why you don't consider supporting multiple jars。We look forward to your reply

    opened by 75ACOL 0
  • Jimple generation performance issue

    Jimple generation performance issue

    It's not a bug, but a huge performance issue.

    Description

    If we try to generate JimpleBody for a invoke statement with "hanging" arguments (see code snippet), it will take an exponential time.

    Input file

    Java snippet
    public class SootIssue {
        void example(
                boolean b1,
                boolean b2,
                boolean b3,
                boolean b4,
                boolean b5,
                boolean b6,
                boolean b7,
                boolean b8,
                boolean b9,
                boolean b10,
                boolean b11,
                boolean b12,
                boolean b13,
                boolean b14,
                boolean b15,
                boolean b16,
                boolean b17,
                boolean b18,
                boolean b19,
                boolean b20,
                boolean b21,
                boolean b22,
                boolean b23,
                boolean b24,
                boolean b25,
                boolean b26,
                boolean b27,
                boolean b28,
                boolean b29,
                boolean b30,
                boolean b31,
                boolean b32
        ) {
            bar(
                    (b1) ? 0 : 1,
                    (b2) ? 2 : 3,
                    (b3) ? 4 : 5,
                    (b4) ? 6 : 5,
                    (b5) ? 8 : 9,
                    (b6) ? 10 : 11,
                    (b7) ? 12 : 13,
                    (b8) ? 14 : 15,
                    (b9) ? 16 : 17,
                    (b10) ? 18 : 19,
                    (b11) ? 20 : 21,
                    (b12) ? 22 : 23,
                    (b13) ? 24 : 25,
                    (b14) ? 26 : 27,
                    (b15) ? 28 : 29,
                    (b16) ? 30 : 31,
                    (b17) ? 32 : 33,
                    (b18) ? 34 : 35,
                    (b19) ? 36 : 37,
                    (b20) ? 38 : 39,
                    (b21) ? 40 : 41,
                    (b22) ? 42 : 43,
                    (b23) ? 44 : 45,
                    (b24) ? 46 : 45,
                    (b25) ? 48 : 49,
                    (b26) ? 50 : 51,
                    (b27) ? 52 : 53,
                    (b28) ? 54 : 55,
                    (b29) ? 56 : 57,
                    (b30) ? 58 : 59,
                    (b31) ? 60 : 61,
                    (b32) ? 62 : 63
            );
        }
    
        void bar(
                int a1,
                int a2,
                int a3,
                int a4,
                int a5,
                int a6,
                int a7,
                int a8,
                int a9,
                int a10,
                int a11,
                int a12,
                int a13,
                int a14,
                int a15,
                int a16,
                int a17,
                int a18,
                int a19,
                int a20,
                int a21,
                int a22,
                int a23,
                int a24,
                int a25,
                int a26,
                int a27,
                int a28,
                int a29,
                int a30,
                int a31,
                int a32
        ) {
        }
    }
    

    Each variable increases the time of conversion in two times. For this example, it doesn't finish locally on my computer for any reasonable time.

    To reproduce

    Soot initialization script in Kotlin:

    fun initSoot(classpath: String?) {
        G.reset()
        val options = Options.v()
    
        options.apply {
            set_prepend_classpath(true)
            setPhaseOption("jb", "use-original-names:false")
            set_soot_classpath("")
            set_src_prec(Options.src_prec_only_class)
            set_process_dir(listOf(classpath))
            set_keep_line_number(true)
            set_ignore_classpath_errors(true)
            set_output_format(Options.output_format_jimple)
            set_allow_phantom_refs(true)
            set_full_resolver(true)
        }
    
        Scene.v().loadNecessaryClasses()
        PackManager.v().runPacks()
    }
    

    Expected behavior

    There is no fundamental performance issues related to bytecode to 3-address code conversion, so I expect at least a polynomial time in a size of a source file.

    Additional context

    If we create a local variable for each argument and then call the method, there won't be any performance problems.

    Some thoughts:

    Looks like there is a problem in soot.asm.AsmMethodSource#addEdges method, because we traverse each possible path in a program instead of traversing each edge once, so it works in O(2^n * poly(n)) time.

    Maybe the problem is that we explore every possible stack state instead of merging them earlier.

    opened by sergeypospelov 1
  • How to do backward slicing with Soot?

    How to do backward slicing with Soot?

    Thanks for this great library.

    I am thinking to use Soot for backward slicing.

    • Is there any example to do this?
    • Can I run it from a IntelliJ or Eclipse plugin?
    • Does it support latest JDK version such as java 16?
    • Can I map back the three address code to the actual code?

    For my case, what I need is to select the code based on a given statement:

    For example, given the following code, and slice point:

    x = 1;
    y = 2;
    z = y-2;
    r = x;
    z = x+y; /* the slice point is the end of the program */.
    

    I need to get the backward sliced code:

    x = 1;
    y = 2;
    z = x+y;
    

    I think this should have an example of its own as there have been many requests in the soot mailing list regarding this.

    I know this is an extremely powerful library.

    But it seems to be very convoluted and I am struggling to understand it. Is it actually possible to use it for my use case (backward slicing) without spending months with the tool?

    opened by smith-co 0
  • soot.SootResolver$SootClassNotFoundException: couldn't find class: com.mycompany.app.CallGraphs (is your soot-class-path set properly?)

    soot.SootResolver$SootClassNotFoundException: couldn't find class: com.mycompany.app.CallGraphs (is your soot-class-path set properly?)

    Hello,

    I'm trying to run the below call graph example in maven. My maven file tree is as follows with package com.mycompany.app

    .
    ── my-app-1
               ├── src
                │      └── main
                │                  └── java
                │                              └── com
                │                                        └── mycompany
                │                                                       └── app
                │                                                            └── CallGraphExample.java
                │                                                            └── CallGraph.java
                │ 
                └── pom.xml 
    
    

    Both CallGraphExample.java and CallGraph.java are under the same package com.mycompany.app;

    CallGraphExample.java

    package com.mycompany.app;
    
    imports ...;
    
    public class CallGraphExample 
    {
        public static void main( String[] args ) {
    
    		CallGraphs cg = new CallGraphs();
    
    		System.out.println(cg.getClass().getName());
    	   List<String> argsList = new ArrayList<String>(Arrays.asList(args));
    	   argsList.addAll(Arrays.asList(new String[]{
    			   "-w",
    			   "-main-class",
    			   "com.mycompany.app.CallGraphs",//main-class
    			   "com.mycompany.app.CallGraphs",//argument classes
    			   "com.mycompany.app.A"			//
    	   }));
    	
    
    	   PackManager.v().getPack("wjtp").add(new Transform("wjtp.myTrans", new SceneTransformer() {
    
    		@Override
    		protected void internalTransform(String phaseName, Map options) {
    		       CHATransformer.v().transform();
                           SootClass a = Scene.v().getSootClass("com.mycompany.app.A");
    
    		       SootMethod src = Scene.v().getMainClass().getMethodByName("doStuff");
    		       CallGraph cg = Scene.v().getCallGraph();
    
    		       Iterator<MethodOrMethodContext> targets = new Targets(cg.edgesOutOf(src));
    		       while (targets.hasNext()) {
    		           SootMethod tgt = (SootMethod)targets.next();
    		           System.out.println(src + " may call " + tgt);
    		       }
    		}
    		   
    	   }));
    
            args = argsList.toArray(new String[0]);
               
        	soot.Main.main(args);
    
        }
    }
    

    CallGraph.java

    package com.mycompany.app;
    
    public class CallGraphs
    {
    	public static void main(String[] args) {
    		doStuff();
    	}
    	
    	public static void doStuff() {
    		new A().foo();
    	}
    }
    
    class A
    {
    	public void foo() {
    		bar();
    	}
    	
    	public void bar() {
    	}
    }
    

    Since both are under the same package. I change the arguments from testers.CallGraphs to com.mycompany.app.CallGraphs.

    Despite making sure of the packages by printing System.out.println(cg.getClass().getName()); ---> com.mycompany.app.CallGraphs, i'm still getting couldn't find class: com.mycompany.app.CallGraphs (is your soot-class-path set properly?) error. the full error is below.

    Soot.SootResolver$SootClassNotFoundException: couldn't find class: com.mycompany.app.CallGraphs (is your soot-class-path set properly?)
            at soot.SootResolver.bringToHierarchyUnchecked(SootResolver.java:245)
            at soot.SootResolver.bringToHierarchy(SootResolver.java:221)
            at soot.SootResolver.bringToSignatures(SootResolver.java:292)
            at soot.SootResolver.bringToBodies(SootResolver.java:332)
            at soot.SootResolver.processResolveWorklist(SootResolver.java:171)
            at soot.SootResolver.resolveClass(SootResolver.java:141)
            at soot.Scene.loadClass(Scene.java:1069)
            at soot.Scene.loadClassAndSupport(Scene.java:1054)
            at soot.Scene.loadNecessaryClass(Scene.java:1836)
            at soot.Scene.loadNecessaryClasses(Scene.java:1848)
            at soot.Main.run(Main.java:241)
            at soot.Main.main(Main.java:141)
            at com.mycompany.app.CallGraphExample.main(CallGraphExample.java:59
    

    Any help would be much appreciated.

    opened by omarjarkas1997 2
Owner
Soot Program Analysis Framework
This organization hosts open-source projects related to the Soot program analysis framework
Soot Program Analysis Framework
enjarify 8.6 0.0 L5 Python Enjarify is a tool for translating Dalvik bytecode to equivalent Java bytecode. This allows Java analysis tools to analyze Android applications.

Note: This repository may be out of date. Future development will occur at https://github.com/Storyyeller/enjarify. Introduction Enjarify is a tool fo

Google 2.7k Jan 8, 2023
CLI tool for decompiling Android apps to Java. It does resources! It does Java! Its real easy!

Easy-as-pie Android Decompiler Why One stop shop I got pretty tired of decompiling Android apps with a bunch of steps that I had to remember all the t

Alex Davis 619 Dec 27, 2022
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An

Cossack Labs 1.6k Dec 29, 2022
UNIX-like reverse engineering framework and command-line toolset

Radare2: The Libre Unix-Like Reverse Engineering Framework See the Releases page for downloads. The current git master branch is 5.7.7, next will be 5

radare org 17.4k Jan 9, 2023
Mobile Security Framework (MobSF)

Mobile Security Framework (MobSF) is an automated, all-in-one mobile application (Android/iOS/Windows) pen-testing, malware analysis and security assessment framework capable of performing static and dynamic analysis.

Mobile Security Framework 13.2k Jan 4, 2023
Signal Protocol library for Java/Android

Overview A ratcheting forward secrecy protocol that works in synchronous and asynchronous messaging environments. PreKeys This protocol uses a concept

Signal 1.8k Dec 24, 2022
Grab’n Run, a simple and effective Java Library for Android projects to secure dynamic code loading.

Grab’n Run, a simple and effective Java Library for Android projects to secure dynamic code loading.

Luca Falsina 418 Dec 29, 2022
TweetNaCl in Java - a port of TweetNaCl-js

TweetNacl in Java: port of tweetnacl-js API/Usage Suggest always use TweetNaclFast implementation Public key authenticated encryption get key pair: Bo

AppNet.Link 40 Nov 10, 2022
Dex to Java decompiler

JADX jadx - Dex to Java decompiler Command line and GUI tools for producing Java source code from Android Dex and Apk files Main features: decompile D

null 32.8k Jan 2, 2023
Analyze any Android/Java based app or game

ClassyShark Introduction ClassyShark is a standalone binary inspection tool for Android developers. It can reliably browse any Android executable and

Google 7.2k Jan 3, 2023
A program analysis tool to find cryptographic misuse in Java and Android.

A program analysis tool to find cryptographic misuse in Java and Android.

null 92 Dec 15, 2022
CRYLOGGER: Detecting Crypto Misuses for Android and Java Apps Dynamically

CRYLOGGER: Detecting Crypto Misuses for Android and Java Apps Dynamically

Luca Piccolboni 139 Dec 12, 2022
Java bytecode obfuscator created by x4e.

Binscure Java bytecode obfuscator created by x4e. Usage First, create a config file, (example config here). When you have a config file, run binscure

null 35 Nov 22, 2022
Appdbg - make it possible to run android dex file in original Java Virtual Machine

Appdbg - make it possible to run android dex file in original Java Virtual Machine

null 137 Dec 20, 2022
A RSA Cipher implementation for Kotlin/Java

A RSA Cipher implementation for Kotlin/Java.

Lyzev 3 Aug 22, 2022
Smali/baksmali is an assembler/disassembler for the dex format used by dalvik, Android's Java VM implementation

About smali/baksmali is an assembler/disassembler for the dex format used by dalvik, Android's Java VM implementation. The syntax is loosely based on

Ben Gruver 5.7k Dec 27, 2022
Find Security Bugs is the SpotBugs plugin for security audits of Java web applications

The SpotBugs plugin for security audits of Java web applications and Android applications. (Also work with Kotlin, Groovy and Scala projects)

OWASP Find Security Bugs 2k Jan 6, 2023
Catch common Java mistakes as compile-time errors

Error Prone Error Prone is a static analysis tool for Java that catches common programming mistakes at compile-time. public class ShortSet { public

Google 6.3k Dec 23, 2022
App Launch Optimization

App Launch Optimization

null 0 Oct 30, 2021
Score - A calculus for scoreboard optimization

score A calculus for scoreboard optimization. Optimizations set fusion scoreboar

null 0 Jan 11, 2022