Coder Social home page Coder Social logo

soot-oss / soot Goto Github PK

View Code? Open in Web Editor NEW
2.8K 103.0 705.0 612.83 MB

Soot - A Java optimization framework

License: GNU Lesser General Public License v2.1

HTML 0.88% Java 95.85% Shell 0.02% XSLT 0.61% Julia 0.01% CSS 0.01% TeX 2.52% Makefile 0.01% Perl 0.04% Limbo 0.06%
java optimization java-optimization-framework analysis-framework static-analysis jimple bytecode soot

soot's People

Contributors

agorski3 avatar alexandre-bartel avatar anddann avatar bergerbd avatar ericbodden avatar florian-kuebler avatar gnom7 avatar henryhchchc avatar hsenag avatar jkluge avatar jpstotz avatar juliusnmn avatar linghuiluo avatar ljhendren avatar malaverdiere avatar marcmil avatar mbenz89 avatar nignag avatar olhotak avatar pavanupb avatar piskachev avatar plam avatar pnest avatar rajatkhanna1994 avatar richardxx avatar soot-ci avatar ste-lam avatar stevenarzt avatar tim-hoffman avatar timtadh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

soot's Issues

Tutorials to use Soot as a Library

Newcomers to Soot sometimes have a difficulty getting started. Good tutorials on how to use soot (especially when used as a library) would be appreciated.

Automated testing + regression tests

A lot of the test cases in Soot are dependent on a human to read their output. They should be converted to use a testing framework such as JUnit of TestNG that can give a clear pass/fail.

Test cases should be available for all the features in soot. Good luck with that! :)

Generating statistics for Soot

(copy-pasted from GSOC application)
Explanations:
The Soot framework and Heros solver divide the analysis of Java in multiple steps, termed phases. Each phase can have multiple transformers, which perform one analysis and possibly performs transformation based on analysis results. Currently, Soot gathers minimal statistics like execution time by phase. As Soot is used for analysing increasingly large applications, it is important that we identify which stages negatively impact the performance of the analysis. In addition, Soot offers a great deal of options, some of which can significantly alter the execution time and memory consumptions. Researchers building analyses would benefit from being able to determine which options have significant impact on their analyses. Furthermore, it will be useful to determine how much resources are taken by which part of the application (application core code, application libraries, Java libraries). Finally, this feature would enable the developers to perform regression testing if a commit adversely impacts the performance.

Expected Results:
A Java component that obtains CPU and memory usage and is integrated with the phase and transformer architecture of Soot; output of results in CSV format; instrumentation in the soot framework for recording the number of Soot internal object for each of the parts of the application, a framework for analyses to notify of the usage analysis for each part of the application and integration in the Heros solver.

Knowledge prerequisite:
Very good Java knowledge and experience with writing Java code, the ability to understand a large and complex existing code base written and Java. Previous knowledge on static analysis and/or Soot is helpful, but not required - if not present, we expect the student to read the corresponding research papers (provided by us) before the coding period starts.

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?

Exception because body isn't loaded yet

This exception happened in the wjpp phase:

Exception in thread "main" java.lang.RuntimeException: method has no active body!
at soot.Printer.printTo(Printer.java:209)
at

Symbolic execution for Java/Android code

(copy-pasted from GSOC application)
Explanations:
Symbolic execution is a program analysis technique that has many applications such as test-input generation, bug finding. The basic idea behind symbolic execution is as follows. The program is executed with symbolic values, instead of concrete values, as program inputs, and the values of program variables are represented as symbolic expressions of those inputs. At any point during symbolic execution, the state of a symbolically executed program includes the symbolic values of program variables at that point, a path constraint on the symbolic values to reach that point, and a program counter. The path constraint (PC) is a boolean formula over the symbolic inputs, which is an accumulation of the constraints that the inputs must satisfy for an execution to follow that path. At each branch point during symbolic execution, the PC is updated with constraints on the inputs such that (1) if the PC becomes unsatisfiable, the corresponding program path is infeasible, and symbolic execution does not continue further along that path and (2) if the PC is satisfiable, any solution of the PC is a program input that executes the corresponding path. The program counter identifies the next statement to be executed. In this project, the student is expected to extend the code base of ACTEve (http://code.google.com/p/acteve), which is a symbolic-execution tool for Android apps (available in Java .class format) and uses Soot.
Note: There are many interesting research problems related to symbolic execution. So this project can be equally suitable for students interested in research publication.

Expected Results:
A symbolic-execution tool for Java. Specifically, given a program input, the tool will (1) compute PC for the path that the program takes for that input, and (2) generate new inputs that drive the program along paths that are different than the path that the original input takes.

Knowledge prerequisite:
Good Java programming skills; knowledge of symbolic execution in particular and program analysis in general.

Keep Line Number setting not saved

When creating a new configuration in the Soot Eclipse plugin, the --keep-line-number setting is not saved.

Creating a new configuration on the fly using the Run... menu shows "Keep line numbers" enabled in Input Attribute Options, but the flag is not being passed to soot.

Workaround: Manually amend args in the custom Main class' main(String[] args) function.

Eclipse:

Version: Juno Service Release 2
Build id: 20130225-0426

Wrong classpath generation in plugin on Windows

The Eclipse plugin assembles the soot class-path incorrectly.

The build path is configured as follows:

/C:/<projectname>/<pathWithinProject>

Expected

/C:/<pathToProject>/<projectname>/<pathWithinProject>

Some build path entries are present twice, once in the wrong format, once in the correct format. One path is only present in the wrong format.

Modularize Soot and Deprecate Some Modules

Soot currently is semi-modularized. Some mandatory dependencies (e.g. Jasmin) and optional ones (e.g. Probe, Paddle) are organized separately.

However, many modules within Soot are merged in the same code base. Some modules are unmaintained currently.

The core Soot project should contain the following modules:

  • Jimple and Jimple processing packs that are enabled by default
  • Bytecode front-end
  • Up-to-date Java front-end
  • Heros implementation supporting Jimple
  • Spark
  • Geometric-encoded context-senstitive variant of Spark
  • Output to Jimple and Java bytecode

Optional modules should be:

  • Paddle (already external)
  • Dava (already external)
  • Probe (already external)
  • Heros (already external)
  • Eclipse plug-in
  • Java 1.4 Polyglot front-end
  • Shimple and all Shimple processing packs
  • Optional (not enabled by default) Jimple transformers
  • Output to Shimple, jimp, shimp, baf, b, grimple, grimp, dava, templates
  • Annotation-related transformers

Tag annotations do not work (properly) in Java files

The null pointer analysis example as described in the Soot survivor's guide, page 20 does not have Eclipse show any markers whatsoever.

In my own examples, I got StringTag that I put on statements to show up as a marker in Eclipse, if and only if I pass the --keep-line-numbers option.

Manually tagging ValueBoxes has the same effect as running the NullPointerColorer example.

The XML file records all tags, however, some information is lost:

  • For ColorTags on statements, the line is recorded, spos and epos are zero. -> No marker generated
  • For StringTags on statements, the line is recorded, spos and epos are zero -> Marker generated, hint shown on hover.
  • For StringTag in combination with ColorTag, it works the same as for StringTag, but still no highlight shown.
  • For String/ColorTags on ValueBoxes, line information is lost completely, as are epos and spos

The Jimple position information is saved correctly in all cases.

ICFG clinit edges change violate clients assumption

The change from 9eb4ba9 changes the behaviour of the icfg in case of static initializers and violates some basic assumptions on the client side. It would be better to have a flag whether to include the clinit edges or not.

Background: A call to a static method x.foo(42) now also has foo.clinit and Object.clinit as additional callees (given that foo is of type Foo and Foo is derived directly from Object). Some clients assume that all callees of a call take the same number of Parameters and that this number is equal to the number of arguments given in the call Statement which is no longer the case here as clinit never takes any parameters. There are cases in which we need to handle clinit edges (and then take care of this special case) and others in which we don't. A flag could elegantly solve this problem.

Problematic boolean array to int array widening

Hi Eric,

Soot is producing the problematic boolean array to int array widening described in the following paragraphs. The behaviour is reproductible in the current develop branch, however the official 2.5.0 jar is fine. I could not test the master branch.

Given the program:

public class Foo { 
  public static void main(String[] args) {
    int index = 1;
    boolean values[] = new boolean[10];
    boolean res = (index > -1) ? values[index] : false;
  }
}

Transformed with java -jar soot-2.5.0.jar Foo, giving a coherent result:

public static void main(java.lang.String[]);      
Code:
      0: iconst_1      
      1: istore_0      
      2: bipush        10
      4: newarray       boolean
      6: astore_1      
      7: iload_0       
      8: iconst_m1     
      9: if_icmple     19
    12: aload_1       
    13: iload_0       
    14: baload        ### loading a boolean from the array
    15: istore_1      
    16: goto          21
    19: iconst_0      
    20: istore_1      
    21: iload_1       
    22: istore_1      
    23: return

Notice the 14: baload.

Now, transformed with java -jar soot-develop.jar Foo, gives the following bytecodes:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   istore_0
   2:   bipush  10
   4:   newarray boolean
   6:   astore_1
   7:   iload_0
   8:   iconst_m1
   9:   if_icmple   22
   12:  aload_1
   13:  checkcast   #5; //class "[I"  ### casting boolean array to int array !
   16:  iload_0
   17:  iaload   ### loading integer from the array
   18:  istore_1
   19:  goto    24
   22:  iconst_0
   23:  istore_1
   24:  iload_1
   25:  istore_1
   26:  return

The 13: checkcast is checking the boolean array against target type [I integer array. Also notice the 17: iaload replacing the baload.
The execution of this code raises a ClassCastException with HotSpot and JikesRVM.

Improve Bit Vectors

The default bit vector used in Soot is not a sparse bit vector, resulting in wasted memory. Soot shout switch to a faster bit vector such as OpenBitSet or a compressed bit set such as javaewah or a sparse bit set

Depending on the performance results, Soot may consider switching from hybrid sets to the chosen bit sets as default set representation.

Establish a Legal Entity for Soot

The Soot community would benefit to be organized similarly to other open source project such as Linux, Apache or LibreOffice.

The community should institute a non-profit foundation or association.

Status of IDalvikTyper

In Dexpler, there is this interface named IDalvikTyper, which is referenced in DexBody many times. But the respective code does not ever get excuted because a flag IDalvikTyper.ENABLE_DVKTYPER that guards all those code is set to false.

I am wondering about the status of IDalvikTyper: (1) Is it something that will be no longer used, (2) is it work-in-progress and will be used in future in place of Soot's type assigner, which does not seem to work in some cases, or (3) is it something that is planned to be enabled/disabled through an option.

Performance Improvements

Optimize memory and CPU usage.

Optimizations include:

  • Improve the bit sets (see #46)
  • Improve data structures
  • Parallelize algorithms

loadClassAndSupport creates empty SootClass

import static org.junit.Assert.fail;
import org.junit.Before;
import org.junit.Test;
import soot.G;
import soot.Scene;

public class TestSootBug
{
    @Before
    public void setUp()
    {
        G.reset();
    }

    @Test(expected = RuntimeException.class)
    public void testClassDoesNotExist()
    {
        String className = "DoesNotExist";

        Scene.v().loadClassAndSupport(className);
    }

    @Test(expected = RuntimeException.class)
    public void testBug()
    {
        String className = "DoesNotExist";

        try
        {
            Scene.v().loadClassAndSupport(className);
            fail();
        }
        catch (RuntimeException e)
        {
        }

        // should also throw RuntimeException
        Scene.v().loadClassAndSupport(className);
    }
}

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?

[Soot-list] java.lang.RuntimeException: cannot set body for non-concrete method!

Provide better error message for entry points. See message below.

While preparing the example, I found the problem. At least that's what I think. Here is the "minimal" code that reproduces the exception:


import java.util.LinkedList;
import java.util.List;

import soot.PackManager;
import soot.Scene;
import soot.SootClass;
import soot.SootMethod;
import soot.options.Options;

public class NonConcreteMethodBug {

public static void main(final String[] args) {
    Options.v().set_whole_program(true);
    Options.v().parse(new String[] {"TestInterface"});

    for(final Object name : Options.v().classes())
        Scene.v().forceResolve((String) name, SootClass.BODIES);

    Scene.v().loadNecessaryClasses();
    Scene.v().setEntryPoints(allPublicMethods());

    PackManager.v().runPacks();
}

private static List<SootMethod> allPublicMethods() {
    List<SootMethod> entryPoints = new LinkedList<SootMethod>();
    for(final Object name : Options.v().classes()) {
        List<SootMethod> methods = Scene.v().getSootClass(
                (String) name).getMethods();
        for(final SootMethod method : methods)
            if(method.isPublic())
                entryPoints.add(method);
    }
    return entryPoints;
}

}

interface TestInterface {
void doSomething();

}

By looking at it like that, you immediately see that I am adding interface (abstract) methods as entry points. And this is what seems to cause the problem. If I add the necessary check:

if(method.isPublic() && !method.isAbstract()
entryPoints.add(method);

the exception no longer occurs.

Of course it doesn't make any sense to add abstract methods as entry points, so this is my fault. But I think it would be good if Soot handled this error more nicely, either by ignoring abstract entry point methods or by checking it in the setEntryPoints() method and throwing an exception with a meaningful error message.

In any case, thank you very much for helping me here.

Michael

StackOverflowException in Dexpler

There seems to be a rather direct StackOverflowException happening in Dexpler:

Exception in thread "main" java.lang.StackOverflowError
at soot.jimple.internal.JAssignStmt.containsArrayRef(JAssignStmt.java:131)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:123)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
at soot.dexpler.DexTransformer.findArrayType(DexTransformer.java:225)
...

I can provide the APK in which the problem occurs (v2_com.wetter.androidclient_1_26_wetter.com.apk) on request.

Switch Soot API to collections API whenever necessary

[Edit: updated title to make more sense]
There is a lot of getNumXYZ and getXYZ(i) in the Soot internal API. These methods should be marked as deprecated and the collections API should be used instead.

Futhermore, there are many methods that return an Iterator, which cannot be used in a for-all loop. Iterators should be wrapped in a collection similar to Scala's IterableOnce.

AbstractFlowSet equals/hashCode contract issues

Hello,

First of all, thanks for the wonderful open source framework.

I'd like to draw your attention to the current implementation of the AbstractFlowSet implementation and its subclasses wrt to the equals/hashCode contract. I've encountered several issues:

  1. Violation of the hashCode contract (equal objects must have the same hashCode).
    For example, take the following snippet:
ArraySparseSet ars1 = new ArraySparseSet();
ars1.add("a");
ars1.add("b");

ArraySparseSet ars2 = new ArraySparseSet();
ars2.add("b");
ars2.add("a");

System.out.println(ars1.equals(ars2)); // true
System.out.println(ars1.hashCode() == ars2.hashCode()); // false; violates the hashCode contract

AbstractFlowSet also accept intertype equality, but fails to comply to the hashCode contract:

ArrayPackedSet aps = new ArrayPackedSet(new CollectionFlowUniverse<String>(Arrays.asList("a","b")));
aps.add("b");
aps.add("a");

System.out.println(ars1.equals(aps)); // true
System.out.println(ars1.hashCode() == aps.hashCode()); // false; violates the hashCode contract

This happens because the hashCode is calculated based on the iteration order, whereas the equals checks for equality independent of order.

One way to fix this could be to relax the hashCode implementation below:

public int hashCode() {
    final int PRIME = 31;
    int result = 1;
    Iterator iter = iterator();
    while(iter.hasNext()) {
        Object o = iter.next();
        result = PRIME * result + o.hashCode();
    }
    return result;
}

to something like:

public int hashCode() {
    int result = 1;
    Iterator iter = iterator();
    while(iter.hasNext()) {
        Object o = iter.next();
        result += o.hashCode();
    }
    return result;
}
  1. One consequence of allowing intertype equality (like the comparisson between ArrayPackedSet and ArraySparseSet above) is that it is very hard to comply with the simmetry clause of the equals contract:
ToppedSet ts1 = new ToppedSet(ars1);
System.out.println(ts1.equals(ars1)); // false
System.out.println(ars1.equals(ts1)); // true; violates the simmetry clause of the equals contract
  1. and also to comply with the transitivity clause. Suppose the following class:
class MyFlowSet extends ArraySparseSet {
    private int myState = 0;

    public void setState(int state) {
        myState = state;
    }

    @Override
    public boolean equals(Object otherFlow) {
        if (otherFlow instanceof MyFlowSet) {
            MyFlowSet other = (MyFlowSet) otherFlow;
            if (other.numElements != this.numElements || other.myState != this.myState)
                return false;

            for(int i = 0; i < this.numElements; i++)
                if(!other.contains(this.elements[i]))
                    return false;
            return true;    
        }

        return super.equals(otherFlow);
    }

    @Override
    public List toList() {
        return super.toList();
    }
}

Because intertype equality is allowed, the following case can emerge:

MyFlowSet mfs1 = new MyFlowSet();
mfs1.add("a");
mfs1.add("b");

MyFlowSet mfs2 = new MyFlowSet();
mfs2.add("a");
mfs2.add("b");
mfs2.setState(1);

System.out.println(mfs1.equals(ars1)); // true
System.out.println(mfs2.equals(ars1)); // true
System.out.println(mfs1.equals(mfs2)); // false; violates the transitivity clause of the equals contract

I believe that many of these issues could be avoided by separating the object equality from the "content equality", maybe using the EquivTo interface, or by disallowing intertype equality. Both of these alternatives will most likely break backwards compatibility wth existing code.

Are any of these two alternatives viable options? What are the developers position on this?

Thanks!

unsound jimple produced with certain array store

I found a strange behavior related to commit f6f3522 (and probably the previous version).

The following Java code

Object[] arr = new Object[1];
arr[0] = "0"

Produce the following Jimple code

java.lang.Object[] r1;
java.lang.Object r2;
java.lang.String r3;
r1 = newarray (java.lang.Object)[1];
r2 = r1[0];
r3 = (java.lang.String) r2;
r3 = "1";

I fixed my example by modifying line 258 of UseChecker into

stmt.setRightOp(this.uv.visit(rhs, tlhs, stmt));

However I'm not sure it is the right fix.

Windows users cannot execute make_singleton

Soot build executes the bash script src/make_singleton. Windows users cannot execute this script and thus cannot compile Soot.

Shall we translate the script to a java program ?

javac complains about non-ASCII characters when building Soot

Hi Eric, my javac complains about non-ASCII characters in the copyright notice of multiple files.

[javac] (...)/src/soot/dexpler/DexBody.java:4: unmappable character for encoding ASCII

I fixed it by adding the encoding="UTF-8" attribute for the <javac node of the compile target in build.xml. I guess it is also possible to switch the few problematic characters into their equivalent in ascii.

In DexBody.java, DexClass.java, DexField.java, Util.java, DexlibAbstractInstruction.java changed by commit d77ac83

[javac]  * (c) 2012 University of Luxembourg ??? Interdisciplinary Centre for

In AnnotationTag.java changed by commit cbf4542

[javac]  * Copyright (C) 2013 Tata Consultancy Services & ??cole Polytechnique de Montr??al
[javac]  * Modified by Marc-Andr?? Laverdi??re-Papineau in 2013

Regards.

Improved Points-To API

(copy-pasted from Richard Xiao's email)
New query interfaces should be added to give users more ways to access information. The typical example is the points-to information. Using the "forAll" function to visit the points-to vector is not efficient because first, we have to create a visitor object and pass it to "forAll". Second, sometimes we only search for particular object, the "forAll" function forces us to visit all objects and it is not easy to terminate the visit process earlier. Therefore, it is more convenient to provide a "iterator" way to access the points-to vector. Another problem is that the "is alias" query is not defined in the standard query interface. Therefore, users have to write different code for experimenting with different points-to packages, which increases the burden for users to study the internal design of these packages.

Update baksmali

The baksmali version Soot uses is a bit dated. Replacing baksmali 1.3.2 with version 2.x is a bit of work since the API seems to have changed a lot. Going for version 1.4.2 seems to be an option as this is also a rather recent release, so the 1.x branch still seems to be under active development. However, this is not a drop-in replacement either - most of the required changes seem to be purely technical, though.

Repeated applications of jb.* BodyTransformers in Dexpler

In the Dexbody class, there is this following code, which will apply different types of BodyTransformers included in the "jb" phase.

PackManager.v().getPack("jb").apply(jBody);

However, by the time the above code gets executed, some of the transformations (e.g., TypeAssigner, LocalPacker, LocalSplitter, LocalNameStandardizer) that are included in the "jb" phase have already been to the method body (by direct invocation of their "transform" methods).

I am wondering if such repeated applications of some of those transformations necessary.

Mavenize Build

Building Soot can be a bit difficult for newcomers. A simpler build process that handles all the dependencies is desirable.

Further, the build process should take in consideration the projected modularization (see #43)

Soot should be built using Maven or Ivy, and the whole software should be buildable from a single command, with no parametrization needed.

RuntimeException in Dexpler:Attempt to create VarNode of type byte

In a test application I can provide upon request (v2_com.zeptolab.ctr.ads_1_20_Cut the Rope FULL FREE.apk), the following exception occurs in Dexpler:

Exception in thread "main" java.lang.RuntimeException: Attempt to create VarNode of type byte
at soot.jimple.spark.pag.VarNode.(VarNode.java:106)
at soot.jimple.spark.pag.LocalVarNode.(LocalVarNode.java:44)
at soot.jimple.spark.pag.PAG.makeLocalVarNode(PAG.java:540)
at soot.jimple.spark.builder.MethodNodeFactory.caseLocal(MethodNodeFactory.java:207)
at soot.jimple.internal.JimpleLocal.apply(JimpleLocal.java:132)
at soot.jimple.spark.builder.MethodNodeFactory.caseCastExpr(MethodNodeFactory.java:184)
at soot.jimple.internal.AbstractCastExpr.apply(AbstractCastExpr.java:127)
at soot.jimple.spark.builder.MethodNodeFactory$1.caseAssignStmt(MethodNodeFactory.java:74)
at soot.jimple.internal.JAssignStmt.apply(JAssignStmt.java:221)
at soot.jimple.spark.builder.MethodNodeFactory.handleStmt(MethodNodeFactory.java:67)
at soot.jimple.spark.pag.MethodPAG.buildNormal(MethodPAG.java:181)
at soot.jimple.spark.pag.MethodPAG.build(MethodPAG.java:147)
at soot.jimple.spark.solver.OnFlyCallGraph.processReachables(OnFlyCallGraph.java:64)
at soot.jimple.spark.solver.OnFlyCallGraph.build(OnFlyCallGraph.java:56)
at soot.jimple.spark.solver.PropWorklist.handleVarNode(PropWorklist.java:123)
at soot.jimple.spark.solver.PropWorklist.propagate(PropWorklist.java:53)
at soot.jimple.spark.SparkTransformer.internalTransform(SparkTransformer.java:152)
at soot.SceneTransformer.transform(SceneTransformer.java:39)
at soot.Transform.apply(Transform.java:89)
at soot.RadioScenePack.internalApply(RadioScenePack.java:57)
at soot.jimple.toolkits.callgraph.CallGraphPack.internalApply(CallGraphPack.java:49)
at soot.Pack.apply(Pack.java:114)
at soot.PackManager.runWholeProgramPacks(PackManager.java:464)
at soot.PackManager.runPacksNormally(PackManager.java:373)
at soot.PackManager.runPacks(PackManager.java:335)
at soot.jimple.infoflow.Infoflow.computeInfoflow(Infoflow.java:226)
at soot.jimple.infoflow.android.SetupApplication.runInfoflow(SetupApplication.java:245)
at soot.jimple.infoflow.android.TestApps.Test.main(Test.java:133)

toDex: "check-cast on non-reference in v0" with k9mail APK

As reported by Shengqian on the Soot-list, running an APK from k9mail through Soot without modifications produces an APK with an invalid opcode or register state. The generated APK yields a VerifiyError if installed on an emulator for Android 2.2:

01-22 17:50:09.845: W/dalvikvm(468): VFY: check-cast on non-reference in v0
01-22 17:50:09.845: W/dalvikvm(468): VFY:  rejecting opcode 0x1f at 0x0959
01-22 17:50:09.845: W/dalvikvm(468): VFY:  rejected Lcom/android/email/MessagingController;.synchronizeMailboxSynchronous (Lcom/android/email/Account;Ljava/lang/String;)V
01-22 17:50:09.855: W/dalvikvm(468): Verifier rejected class Lcom/android/email/MessagingController;
01-22 17:50:09.855: D/AndroidRuntime(468): Shutting down VM
01-22 17:50:09.855: W/dalvikvm(468): threadid=3: thread exiting with uncaught exception (group=0x4001aa28)
01-22 17:50:09.855: E/AndroidRuntime(468): Uncaught handler: thread main exiting due to uncaught exception
01-22 17:50:09.855: E/AndroidRuntime(468): java.lang.VerifyError: com.android.email.MessagingController
01-22 17:50:09.855: E/AndroidRuntime(468):     at com.android.email.Email.onCreate(Unknown Source)
01-22 17:50:09.855: E/AndroidRuntime(468):     at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1045)
01-22 17:50:09.855: E/AndroidRuntime(468):     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3871)
01-22 17:50:09.855: E/AndroidRuntime(468):     at android.app.ActivityThread.access$2800(ActivityThread.java:116)
01-22 17:50:09.855: E/AndroidRuntime(468):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
01-22 17:50:09.855: E/AndroidRuntime(468):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-22 17:50:09.855: E/AndroidRuntime(468):     at android.os.Looper.loop(Looper.java:123)
01-22 17:50:09.855: E/AndroidRuntime(468):     at android.app.ActivityThread.main(ActivityThread.java:4203)
01-22 17:50:09.855: E/AndroidRuntime(468):     at java.lang.reflect.Method.invokeNative(Native Method)
01-22 17:50:09.855: E/AndroidRuntime(468):     at java.lang.reflect.Method.invoke(Method.java:521)
01-22 17:50:09.855: E/AndroidRuntime(468):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
01-22 17:50:09.855: E/AndroidRuntime(468):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
01-22 17:50:09.855: E/AndroidRuntime(468):     at dalvik.system.NativeStart.main(Native Method)

Unfortunatelly, I cannot reproduce this with my emulator, with runs Android 4.0.3.

Usually when this error message appears, one can hunt down the cause of the bug by inspecting the generated APK with baksmali. Disassembling the APK with register information (use "--register-info ALL" and "-d dir" where dir points to android's {core,framework,...}.jar) should show the instruction at which the register v0 is filled with a non-reference. Follow the control-flow backwards from the instruction at 0x0959 in the method Lcom/android/email/MessagingController;.synchronizeMailboxSynchronous (Lcom/android/email/Account;Ljava/lang/String;)V. I guess that the check-cast itself is correct, but some other instruction is not.

FastHierarchy Inaccuracy in Flowdroid

Using FastHierarchy in a Flowdroid entry point creator yields inaccurate results.

Scala MWE:

def minimalWorkingExample(){
val fastHierarchy = Scene.v.getOrMakeFastHierarchy //make sure it is created before the parallel computations steps in
val sbType = Scene.v.getRefType("java.lang.StringBuffer")
val jBossWsSuperClass = Scene.v.forceResolve("org.jboss.wsf.test.JBossWSTest", SootClass.HIERARCHY) //otherwise we can't load the type
val jBossWsSuperType = jBossWsSuperClass.getType

System.err.println("org.jboss.wsf.test.JBossWSTest is a supertype of StringBuffer? " +
  fastHierarchy.canStoreType(sbType, jBossWsSuperType)
)
}

This gives the following output:

org.jboss.wsf.test.JBossWSTest is a supertype of StringBuffer?true

This is repeated on both invocations of the entry point creator.

Parse.parse throws NullPointerException

The comment above Parse.parse says that you may pass null for the 'sc' argument, but if you do a NullPointerException is thrown (stack trace below). The problem seems to be that Walker.mResolver never gets initialized in this case.

I am working on the develop branch.

java.lang.NullPointerException
at soot.jimple.parser.Walker.outAMethodSignature(Walker.java:1577)
at soot.jimple.parser.analysis.DepthFirstAdapter.caseAMethodSignature(DepthFirstAdapter.java:2985)
at soot.jimple.parser.node.AMethodSignature.apply(AMethodSignature.java:74)
at soot.jimple.parser.analysis.DepthFirstAdapter.caseANonstaticInvokeExpr(DepthFirstAdapter.java:2666)
at soot.jimple.parser.node.ANonstaticInvokeExpr.apply(ANonstaticInvokeExpr.java:64)
at soot.jimple.parser.analysis.DepthFirstAdapter.caseAInvokeStatement(DepthFirstAdapter.java:2044)
at soot.jimple.parser.node.AInvokeStatement.apply(AInvokeStatement.java:39)
at soot.jimple.parser.analysis.DepthFirstAdapter.caseAFullMethodBody(DepthFirstAdapter.java:1392)
at soot.jimple.parser.node.AFullMethodBody.apply(AFullMethodBody.java:55)
at soot.jimple.parser.analysis.DepthFirstAdapter.caseAMethodMember(DepthFirstAdapter.java:663)
at soot.jimple.parser.node.AMethodMember.apply(AMethodMember.java:70)
at soot.jimple.parser.analysis.DepthFirstAdapter.caseAFileBody(DepthFirstAdapter.java:470)
at soot.jimple.parser.node.AFileBody.apply(AFileBody.java:45)
at soot.jimple.parser.Walker.caseAFile(Walker.java:145)
at soot.jimple.parser.node.AFile.apply(AFile.java:60)
at soot.jimple.parser.analysis.DepthFirstAdapter.caseStart(DepthFirstAdapter.java:34)
at soot.jimple.parser.node.Start.apply(Start.java:36)
at soot.jimple.parser.Parse.parse(Parse.java:80)

Publish Soot to Maven

Maven and Maven-related (SBT, Ivy, Buildr, etc.) users wishing to use Soot as a library in their programs have to resort to maven kung-fu to handle the dependency.

Soot should be published to a major Maven repository in order to facilitate usage by those users.

Dexpler can't find libraries

Hi there. I've been trying to use soot & dexpler to convert a set of apks into jimple. So far, I can convert about half of these successfully the way I would expect. The other half all fail with soot classpath issues, and after looking at these for a while, I have found that the missing classes are all located in .jar files that the original source projects depended on. I have been able to fix a number of these by going in and adding the .jar files from the source projects to the soot classpath.

So my question is, is this the intended behavior of dexpler right now? Should I have to manually include all referenced libraries on the soot classpath? Or is there some other way to include libraries directly from the apk somehow?

Thanks!

exception while using soot.jimple.toolkits.ide.exampleproblems.IFDSReachingDefinitions

Using soot.jimple.toolkits.ide.JimpleIFDSSolver for soot.jimple.toolkits.ide.exampleproblems.IFDSReachingDefinitions
with parameters :


-W -pp
-soot-class-path /usr/lib/jvm/java-6-openjdk/jre/lib/rt.jar:/home/anjali/workspace3/soot/sootclasses-2.3.0.jar:/home/anjali/workspace3/soot/jasminclasses-2.3.0:/home/anjali/workspace3/soot/polyglotclasses-1.3.5.jar
-process-dir /home/anjali/workspace2/abc/c/
-allow-phantom-refs
-d /home/anjali/workspace2/abc/c
-p wjtp.ifds enabled:true


I am getting many exceptions for each thread as follows:

Exception in thread "pool-1-thread-22" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:571)
at java.util.ArrayList.get(ArrayList.java:349)
at java.util.Collections$UnmodifiableList.get(Collections.java:1170)
at soot.SootMethod.getParameterType(SootMethod.java:262)
at soot.jimple.toolkits.ide.exampleproblems.IFDSReachingDefinitions$1$2.computeTargets(IFDSReachingDefinitions.java:108)
at soot.jimple.toolkits.ide.exampleproblems.IFDSReachingDefinitions$1$2.computeTargets(IFDSReachingDefinitions.java:1)
at heros.ZeroedFlowFunctions$ZeroedFlowFunction.computeTargets(ZeroedFlowFunctions.java:58)
at heros.solver.IDESolver.processCall(IDESolver.java:293)
at heros.solver.IDESolver.access$0(IDESolver.java:279)
at heros.solver.IDESolver$PathEdgeProcessingTask.run(IDESolver.java:692)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:679)


However, for simple java program with only few variables,
it seems to generate proper csv file as output. I have attached the input file in -process-dir for your reference here https://gist.github.com/Anjali2019/5703782

Centralize and Update Web Site

Currently, there is a big gap between the Sable website and the contents in github. This is creating confusion for users. Also, some external sites (e.g. Waterloo) also refer to Soot. All of this should be centralized to one spot.

Computing analysis summary information for libraries

(copy-pasted from GSOC application)
Explanations:
Though Soot started as an optimization framework for Java programs, it is nowadays used for various types of static analyses including compiler research and dataflow analysis for security certification. However, since most programs are based on large libraries like the JDK or third-party components consisting of thousands of classes and millions of lines of code, such analyses can be rather time-consuming on the complete code base. In this project, we aim at modularizing the analysis. As most libraries are changed rarely, there is no need to recompute their part of the analysis every time the user’s application changes. We want to precompute summaries for these libraries and store them on disk as “black boxes” that just need to be loaded and used whenever user’s program is analyzed, cutting down the total runtime from hours (and even days in some cases) to a matter of minutes.
This project gives you the opportunity to take part in cutting-edge research on Java static analysis and work on a improving a widely-used framework which is well known inside the research community. For outstanding results, publishing a joint research paper on the topic together is possible.

Expected Results:
Soot shall be able to store analysis results of static analyses conducted on libraries on disk without creating undue overhead. It should be possible to efficiently load these summaries back into the Soot data objects during analyses. Thus, the summaries of libraries should be used in place of the library source code to perform the program analysis. The analysis outcome must still be correct, e.i., library summaries must produce the same result as the analysis on the complete code base including the libraries.

Knowledge prerequisite:
Very good Java knowledge and experience with writing Java code, the ability to understand a large and complex existing code base written and Java. Previous knowledge on static analysis and/or Soot is helpful, but not required - if not present, we expect the student to read the corresponding research papers (provided by us) before the coding period starts.

Improve Logging

Soot's logging defaults to standard output and has only two levels: default and debug. Further, users of Soot as a library may use logging frameworks and their logs are thus not unified.
A more flexible logging method is desirable.

Soot should log using SLF4J to output log messages. This allows the users to use whichever logging back-end they wish.

Improve Bytecode Loading

(Added at the suggestion of Almo)
The bytecode loading and conversion to Jimple is time consuming and memory intensive. An improved implementation would be desirable.

use-original-names RuntimeException "no defs for value"

When running Soot on jasper-runtime-5.5.23.jar, the following exception occurs only if use-original-names is enabled:

Exception in thread "main" java.lang.RuntimeException: no defs for value: l5! in <org.apache.jasper.runtime.ProtectedFunctionMapper: void mapFunction(java.lang.String,java.lang.Class,java.lang.String,java.lang.Class[])>
at soot.Body.validateUses(Body.java:336)
at soot.Body.validate(Body.java:233)
at soot.jimple.JimpleBody.validate(JimpleBody.java:66)
at soot.PackManager.runBodyPacks(PackManager.java:834)
at soot.PackManager.runBodyPacks(PackManager.java:516)
at soot.PackManager.runBodyPacks(PackManager.java:423)
at soot.PackManager.runPacksNormally(PackManager.java:400)
at soot.PackManager.runPacks(PackManager.java:341)
at soot.Main.run(Main.java:198)
at soot.Main.main(Main.java:141)
at Main.main(Main.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

The body of the method is:

this := @this: org.apache.jasper.runtime.ProtectedFunctionMapper
fnQName := @parameter0: java.lang.String
c := @parameter1: java.lang.Class
methodName := @parameter2: java.lang.String
args := @parameter3: java.lang.Class[]
$z0 = staticinvoke <org.apache.jasper.security.SecurityUtil: boolean isPackageProtectionEnabled()>()
if $z0 == 0 goto virtualinvoke c.<java.lang.Class: java.lang.reflect.Method getDeclaredMethod(java.lang.String,java.lang.Class[])>(methodName, args)
$r0 = new org.apache.jasper.runtime.ProtectedFunctionMapper$2
specialinvoke $r0.<org.apache.jasper.runtime.ProtectedFunctionMapper$2: void <init>(org.apache.jasper.runtime.ProtectedFunctionMapper,java.lang.Class,java.lang.String,java.lang.Class[])>(this, c, methodName, args)
$r1 = staticinvoke <java.security.AccessController: java.lang.Object doPrivileged(java.security.PrivilegedExceptionAction)>($r0)
method = (java.lang.reflect.Method) $r1
goto [?= $r9 = this.<org.apache.jasper.runtime.ProtectedFunctionMapper: java.util.HashMap fnmap>]
$r2 := @caughtexception
ex = $r2
$r3 = new java.lang.RuntimeException
$r4 = new java.lang.StringBuffer
specialinvoke $r4.<java.lang.StringBuffer: void <init>()>()
$r4 = virtualinvoke $r4.<java.lang.StringBuffer: java.lang.StringBuffer append(java.lang.String)>("Invalid function mapping - no such method: ")
$r5 = virtualinvoke ex.<java.security.PrivilegedActionException: java.lang.Exception getException()>()
$r6 = virtualinvoke $r5.<java.lang.Exception: java.lang.String getMessage()>()
$r4 = virtualinvoke $r4.<java.lang.StringBuffer: java.lang.StringBuffer append(java.lang.String)>($r6)
$r7 = virtualinvoke $r4.<java.lang.StringBuffer: java.lang.String toString()>()
specialinvoke $r3.<java.lang.RuntimeException: void <init>(java.lang.String)>($r7)
throw $r3
virtualinvoke c.<java.lang.Class: java.lang.reflect.Method getDeclaredMethod(java.lang.String,java.lang.Class[])>(methodName, args)
goto [?= $r9 = this.<org.apache.jasper.runtime.ProtectedFunctionMapper: java.util.HashMap fnmap>]
$r8 := @caughtexception
e = $r8
$r3 = new java.lang.RuntimeException
$r4 = new java.lang.StringBuffer
specialinvoke $r4.<java.lang.StringBuffer: void <init>()>()
$r4 = virtualinvoke $r4.<java.lang.StringBuffer: java.lang.StringBuffer append(java.lang.String)>("Invalid function mapping - no such method: ")
$r6 = virtualinvoke e.<java.lang.NoSuchMethodException: java.lang.String getMessage()>()
$r4 = virtualinvoke $r4.<java.lang.StringBuffer: java.lang.StringBuffer append(java.lang.String)>($r6)
$r7 = virtualinvoke $r4.<java.lang.StringBuffer: java.lang.String toString()>()
specialinvoke $r3.<java.lang.RuntimeException: void <init>(java.lang.String)>($r7)
throw $r3
$r9 = this.<org.apache.jasper.runtime.ProtectedFunctionMapper: java.util.HashMap fnmap>
virtualinvoke $r9.<java.util.HashMap: java.lang.Object put(java.lang.Object,java.lang.Object)>(fnQName, l5)
return

Phantom Classes Marked as Non-Phantom

As reported by Tony Yan
There's likely to be a bug in Scene.getSootClass() on handling of
phantom classes:

if (allowsPhantomRefs() || className.equals(SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME)) {
SootClass c = new SootClass(className);
c.setPhantom(true);
addClass(c);
return c;

}

addClass(c) would contains a call c.setLibraryClass() which does
c.setPhantom(false). Thus, the returned class is falsely flagged as
non-phantom. A fix is to re-order the two calls:
addClass(c);
c.setPhantom(true);"

Test case:

public class Main {
  public static void main(String[] args) {
String[] sootArgs = {
  "-allow-phantom-refs",
  "-f", "n",
  "-cp", WhateverJarsYouNeed,
  "-process-dir", "./bin",
};
PackManager.v().getPack("jtp").add(new Transform("jtp.Main", new
BodyTransformer() {

  protected void internalTransform(Body b, String s, Map m) {
    boolean act =
soot.Scene.v().getSootClass("ImpossibleToExistClass").isPhantom();
    System.out.println("Expected: true, Actual: " + act);
    System.exit(0);
  }
}));

soot.Main.main(sootArgs);
}
}

A visual debugger for static analyses

(copy-pasted from GSOC application)
Explanations:
In the past year, we have developed Heros, a plugin into Soot which allows for inter-procedural data-flow analyses. While the framework eases the definition of such analyses, implementing the analyses correctly is still a tricky task. Hence, we are looking for a visualization that would aid analysis designers in depicting the analysis results by overlaying them over the analyzed program. Thus, the visualization plays the role of a debugger for static analyses. A visual debugger should be integrated into Eclipse. We have already implemented basic support to run Soot and Heros through Eclipse run configuration. Therefore a student could focus on the visualization part and on extracting necessary analysis information from Heros.
Note: previously we also proposed this topic as a thesis topic; you can find the writeup here

Expected Results:
A debugger that visualizes data flows facts overlayed over the analyzed program’s code, as the data are computed by the Heros solver within Soot.

Knowledge prerequisite:
Good Java programming skills; knowledge about Debuggers and/or Eclipse are helpful

Dexpler fails with ClassCastException during jmplify

On the "v2_com.starfinanz.smob.android.sfinanzstatus_1_20727_Sparkasse.apk" from Google Play, the dexpler component fails to correctly load some classes and instead throws a ClassCastException:

Exception in thread "main" java.lang.ClassCastException: soot.RefType cannot be cast to soot.ArrayType
at soot.jimple.toolkits.typing.integer.ConstraintCollector.caseAssignStmt(ConstraintCollector.java:237)
at soot.jimple.internal.JAssignStmt.apply(JAssignStmt.java:221)
at soot.jimple.toolkits.typing.integer.ConstraintCollector.collect(ConstraintCollector.java:48)
at soot.jimple.toolkits.typing.integer.TypeResolver.collect_constraints_1(TypeResolver.java:227)
at soot.jimple.toolkits.typing.integer.TypeResolver.resolve_step_1(TypeResolver.java:180)
at soot.jimple.toolkits.typing.integer.TypeResolver.resolve(TypeResolver.java:140)
at soot.jimple.toolkits.typing.fast.TypeResolver.inferTypes(TypeResolver.java:140)
at soot.jimple.toolkits.typing.TypeAssigner.internalTransform(TypeAssigner.java:102)
at soot.BodyTransformer.transform(BodyTransformer.java:51)
at soot.BodyTransformer.transform(BodyTransformer.java:58)
at soot.BodyTransformer.transform(BodyTransformer.java:63)
at soot.dexpler.DexBody.jimplify(DexBody.java:537)
at soot.dexpler.DexMethod$1.getBody(DexMethod.java:236)
at soot.SootMethod.getBodyFromMethodSource(SootMethod.java:89)
at soot.SootMethod.retrieveActiveBody(SootMethod.java:322)
at soot.jimple.toolkits.callgraph.OnFlyCallGraphBuilder.processNewMethod(OnFlyCallGraphBuilder.java:532)
at soot.jimple.toolkits.callgraph.OnFlyCallGraphBuilder.processReachables(OnFlyCallGraphBuilder.java:427)
at soot.jimple.toolkits.callgraph.CallGraphBuilder.build(CallGraphBuilder.java:84)
at soot.jimple.toolkits.callgraph.CHATransformer.internalTransform(CHATransformer.java:43)
at soot.SceneTransformer.transform(SceneTransformer.java:39)
at soot.Transform.apply(Transform.java:89)
at soot.RadioScenePack.internalApply(RadioScenePack.java:57)
at soot.jimple.toolkits.callgraph.CallGraphPack.internalApply(CallGraphPack.java:49)
at soot.Pack.apply(Pack.java:114)
at soot.PackManager.runWholeProgramPacks(PackManager.java:460)
at soot.PackManager.runPacksNormally(PackManager.java:369)
at soot.PackManager.runPacks(PackManager.java:335)
at soot.jimple.infoflow.android.SetupApplication.runSootBasedPhases(SetupApplication.java:203)
at soot.jimple.infoflow.android.SetupApplication.calculateSourcesSinksEntrypoints(SetupApplication.java:127)
at soot.jimple.infoflow.android.TestApps.Test.main(Test.java:72)

In this example, it happens during Soot's "cg" phase in the attempt to load the class hierarchies. I can provide you with the APK file on request, Github does not seem to allow file attachments to bug reports.

@Alexandre-Bartel Could you please take a look at this?

G.reset() does not reset Dex resolver

When loading Android DEX files, the DexResolver class maintains its own caches for already-resolved classes. These caches are not reset when calling G.reset(), so if I analyze an APK file, update it, call G.reset() and analyze it again, I still get the old classes from before the update even though I resetted soot. Calling both G.reset and DecResolver.reset() fixes the issue.

Can someone please check G.reset() and see if there are other caches missing? It would be great to centralize them all in one place for relieving the user from having to think of all of them.

toDex: "arbitrarily rejecting large method" with connectbot APK

As reported by Shengqian on the Soot-list, running an APK from connectbot through Soot without modifications produces an APK with a large method. The generated APK yields a VerifiyError if installed on an emulator for Android 2.2:

W/dalvikvm(  481): VFY: arbitrarily rejecting large method (regs=1333 count=13292)
W/dalvikvm(  481): VFY:  rejected Lde/mud/terminal/vt320;.putChar (CZ)V
W/dalvikvm(  481): Verifier rejected class Lde/mud/terminal/vt320;
D/AndroidRuntime(  481): Shutting down VM
W/dalvikvm(  481): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
E/AndroidRuntime(  481): FATAL EXCEPTION: main
E/AndroidRuntime(  481): java.lang.VerifyError: de.mud.terminal.vt320
E/AndroidRuntime(  481):    at org.connectbot.service.TerminalBridge.<init>(Unknown Source)
E/AndroidRuntime(  481):    at org.connectbot.service.TerminalManager.openConnection(Unknown Source)
E/AndroidRuntime(  481):    at org.connectbot.service.TerminalManager.openConnection(Unknown Source)
E/AndroidRuntime(  481):    at org.connectbot.ConsoleActivity$1.onServiceConnected(Unknown Source)
E/AndroidRuntime(  481):    at android.app.ActivityThread$PackageInfo$ServiceDispatcher.doConnected(ActivityThread.java:1247)
E/AndroidRuntime(  481):    at android.app.ActivityThread$PackageInfo$ServiceDispatcher$RunConnection.run(ActivityThread.java:1264)
E/AndroidRuntime(  481):    at android.os.Handler.handleCallback(Handler.java:587)
E/AndroidRuntime(  481):    at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime(  481):    at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime(  481):    at android.app.ActivityThread.main(ActivityThread.java:4627)
E/AndroidRuntime(  481):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(  481):    at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime(  481):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
E/AndroidRuntime(  481):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
E/AndroidRuntime(  481):    at dalvik.system.NativeStart.main(Native Method)
W/ActivityManager(   59):   Force finishing activity org.connectbot/.ConsoleActivity

Unfortunatelly, I cannot reproduce this with my emulator, with runs Android 4.0.3, as this error was converted into a warning in later versions of the dalvik verifier. See the current method dvmVerifyCodeFlow(VerifierData* vdata) in CodeVerify:

if (meth->registersSize * insnsSize > 4*1024*1024) {
    LOG_VFY_METH(meth, "VFY: warning: method is huge (regs=%d insnsSize=%d)", meth->registersSize, insnsSize);
    /* might be bogus data, might be some huge generated method */
}

I'm not sure if there is anything we can do in this particular case. The toDex implementation certainly can be improved or optimized in terms of register usage and instruction count, though...

Documentation on how to build soot and the eclipse plugin

Hi Folks,

Would it be possible to add some instructions on how to build soot and the Eclipse plugin from source in an easily accessible place?

The readme file in github points to the mcgill page that points back to the github page.

I cannot run the ant script. I get the following error:

determine-jastadd-uptodate:

BUILD FAILED
/home/becker/src/soot/build.xml:88: /home/becker/src/JastAddExtensions/SootJastAddJ does not exist.

When I try to create an Eclipse project I get lots of errors and cannot easily fix them. After spending a lot of time trying to get all the libraries in the right place, I was able to compile but I am not sure what I did anymore since I tried again in a new Eclipse and got the same problems as before.

Marcel

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.