soot-oss / soot

Soot - A Java optimization framework
GNU Lesser General Public License v2.1
2.86k stars 705 forks source link

Soot error in transforming java bytecode compiled from android source #420

Closed flankerhqd closed 9 years ago

flankerhqd commented 9 years ago

Hi: I encoutered the following exceptions when running soot on compiled android source's bytecode.

java.lang.RuntimeException: Failed to apply jb to <android.os.FileBridge: void run()>
    at soot.asm.AsmMethodSource.getBody(AsmMethodSource.java:1800)
    at soot.SootMethod.getBodyFromMethodSource(SootMethod.java:91)
    at soot.SootMethod.retrieveActiveBody(SootMethod.java:322)
    at soot.PackManager.retrieveAllBodies(PackManager.java:1144)
    at soot.PackManager.runPacksNormally(PackManager.java:458)
    at soot.PackManager.runPacks(PackManager.java:391)
    at soot.Main.run(Main.java:248)
    at soot.Main.main(Main.java:152)
Caused by: java.lang.RuntimeException: Exception reference used other than as the first statement of an exception handler.
    at soot.jimple.toolkits.typing.fast.AugEvalFunction.eval_(AugEvalFunction.java:159)
    at soot.jimple.toolkits.typing.fast.AugEvalFunction.eval(AugEvalFunction.java:41)
    at soot.jimple.toolkits.typing.fast.TypeResolver.applyAssignmentConstraints(TypeResolver.java:483)
    at soot.jimple.toolkits.typing.fast.TypeResolver.inferTypes(TypeResolver.java:153)
    at soot.jimple.toolkits.typing.TypeAssigner.internalTransform(TypeAssigner.java:131)
    at soot.BodyTransformer.transform(BodyTransformer.java:51)
    at soot.Transform.apply(Transform.java:105)
    at soot.JimpleBodyPack.applyPhaseOptions(JimpleBodyPack.java:66)
    at soot.JimpleBodyPack.internalApply(JimpleBodyPack.java:89)
    at soot.Pack.apply(Pack.java:126)
    at soot.asm.AsmMethodSource.getBody(AsmMethodSource.java:1798)
    ... 7 more

Command line is as follows, reproduced with lasted nightly build of soot java -jar soot-trunk.jar -process-dir classes.jar -pp -allow-phantom-refs

classes.jar can be found at http://tool.flanker017.me/classes.jar, which is actually compiled out from android framework.

flankerhqd commented 9 years ago

Dex compiled out can be transformed successfully.

StevenArzt commented 9 years ago

This is a misunderstanding. You class file references Android-specific exception types, but on your Soot classpath, you only have a Java JDK due to the -pp command-line option. This means that Soot is unable to resolve these exception types and cannot build a hierarchy from them.

In your code, there is an exception handler for multiple types. In such a case, Soot needs to find a common super type for all those exceptions to apply to the exception local. This however fails as there is no hierarchy.

The only thing we could do is to check if one of the exception types is a phantom class, and, if so, always use java.lang.Throwable as the type of the exception local. This could however get us into situation in which we produce invalid code. Assume that closest original common base class of two exceptions caught with the same handler is not java.lang.Throwable, but some class A. In that case, it would be totally valid to call some method a.foo() on the exception local as all exceptions caught there must be of type A or one of its subtypes. If we assign Throwable as a type to get away from situation in which we don't know the proper type, we would have a call to Throwable.foo() which would be invalid.

flankerhqd commented 9 years ago

@StevenArzt Thanks for your explaination!