secure-software-engineering / tamiflex

TamiFlex facilitates static analysis of programs that use reflection and custom class loaders
42 stars 13 forks source link

Problem using Booster and the play-out agent #1

Open gkastrinis opened 9 years ago

gkastrinis commented 9 years ago

I am trying to run the play-out agent on a jar, get the reflection log and then use the booster jar to create a new jar. During those steps I encounter various issues.

Reflect.jar is produced from this file https://bitbucket.org/yanniss/doop-benchmarks/src/f9b3ea7e8d0e909777b2ee459b614b80c8b75e74/demos/src/hello/Reflect.java?at=default against jre1.6.


> java -version
java version "1.7.0_75"
Java(TM) SE Runtime Environment (build 1.7.0_75-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.75-b04, mixed mode)
>  java -javaagent:poa-2.0.1.jar -jar Reflect.jar
============================================================
TamiFlex Play-Out Agent Version 2.0.1
Loaded properties from /home/gkastrinis/.tamiflex/poa.properties
============================================================
Hey
Excepted exception.
Test30: Expected exception.
Reachable Test31 okay
Exception in thread "Thread-0" de.bodden.tamiflex.normalizer.ClassRenamer$NoHashedNameException: $Proxy
        at de.bodden.tamiflex.normalizer.Hasher$2$1.remapStringConstant(Hasher.java:90)
        at de.bodden.tamiflex.normalizer.RemappingStringConstantAdapter.visitLdcInsn(RemappingStringConstantAdapter.java:32)
        at org.objectweb.asm.ClassReader.accept(Unknown Source)
        at org.objectweb.asm.ClassReader.accept(Unknown Source)
        at de.bodden.tamiflex.normalizer.Hasher.generateHashNumber(Hasher.java:99)
        at de.bodden.tamiflex.playout.ClassDumper.writeClassesToDisk(ClassDumper.java:82)
        at de.bodden.tamiflex.playout.Agent$1.run(Agent.java:122)

If instead I use java 8, it works ok.

>  java8 -version
openjdk version "1.8.0_31"
OpenJDK Runtime Environment (build 1.8.0_31-b13)
OpenJDK 64-Bit Server VM (build 25.31-b07, mixed mode)
>  java8 -javaagent:poa-2.0.1.jar -jar Reflect.jar
============================================================
TamiFlex Play-Out Agent Version 2.0.1
Loaded properties from /home/gkastrinis/.tamiflex/poa.properties
============================================================
Hey
Excepted exception.
Test30: Expected exception.
Reachable Test31 okay

============================================================
TamiFlex Play-Out Agent Version 2.0.1
Found no new log entries.
Log file written to: /home/gkastrinis/tamiflex/out/refl.log
============================================================

Then I try to use the results with the booster jar.

>  java8 -jar booster-2.0.1.jar -p cg reflection-log:out/refl.log -cp out -main-class Reflect Reflect
TamiFlex Booster Version 2.0.1
Soot started on Mon Mar 23 15:29:07 EET 2015
Exception in thread "main" java.lang.RuntimeException: Line: 'Class.getDeclaredField;<Test33: java.lang.Object o>;Test33.run;782;isAccessible=false;'
        at soot.Scene.addReflectionTraceClasses(Scene.java:1033)
        at soot.Scene.loadBasicClasses(Scene.java:985)
        at soot.Scene.loadNecessaryClasses(Scene.java:1060)
        at soot.Main.run(Main.java:167)
        at soot.Main.main(Main.java:141)
        at de.bodden.tamiflex.booster.ReflInliner.main(ReflInliner.java:53)
Caused by: java.lang.RuntimeException: Unknown entry kind: Class.getDeclaredField
        at soot.Scene.addReflectionTraceClasses(Scene.java:1030)
        ... 5 more

Am I missing some step in the process? Thanks in advance.

jyotigajrani commented 8 years ago

I did the same and got success in poa step using oracle java 8. The command that I used is: java -javaagent:poa.jar Main

But when i use booster with following command, I get exception:

java -jar booster-2.0.3.jar -p cg reflection-log:out/refl.log -cp out -main-class Main Main


ad.r r0;
virtualinvoke <java.lang.Class: java.lang.reflect.Field[] getFields()>;
store.r $r54;
staticget <java.lang.System: java.io.PrintStream out>;
push "Public Fields are: ";
virtualinvoke <java.io.PrintStream: void println(java.lang.String)>;
load.r $r54;
arraylength;
store.i i1;
push 0;
store.i i0;
Block 11:
[preds: 9 ] [succs: 12 ]
load.r $r54;
load.r r2;
load.r r19;
virtualinvoke <java.lang.reflect.Method: java.lang.Object invoke(java.lang.Object,java.lang.Object[])>;
pop;

computed blockHeight == 0 recorded blockHeight = 1
    at soot.baf.JasminClass.calculateStackHeight(JasminClass.java:1898)
    at soot.baf.JasminClass.calculateStackHeight(JasminClass.java:1903)
    at soot.baf.JasminClass.calculateStackHeight(JasminClass.java:1903)
    at soot.baf.JasminClass.calculateStackHeight(JasminClass.java:1903)
    at soot.baf.JasminClass.calculateStackHeight(JasminClass.java:1903)
    at soot.baf.JasminClass.calculateStackHeight(JasminClass.java:1903)
    at soot.baf.JasminClass.calculateStackHeight(JasminClass.java:1903)
    at soot.baf.JasminClass.calculateStackHeight(JasminClass.java:1903)
    at soot.baf.JasminClass.emitMethodBody(JasminClass.java:321)
    at soot.AbstractJasminClass.emitMethod(AbstractJasminClass.java:697)
    at soot.AbstractJasminClass.<init>(AbstractJasminClass.java:576)
    at soot.baf.JasminClass.<init>(JasminClass.java:91)
    at soot.PackManager.writeClass(PackManager.java:893)
    at soot.PackManager.writeOutput(PackManager.java:475)
    at soot.PackManager.writeOutput(PackManager.java:400)
    at soot.Main.run(Main.java:199)
    at soot.Main.main(Main.java:141)
    at de.bodden.tamiflex.booster.ReflInliner.main(ReflInliner.java:53)

What is the reason for this and how can i resolve it ? Thanks @ericbodden

ericbodden commented 8 years ago

Hello I can explain the error regarding Class.getDeclaredField. The Booster can only deal with certain kinds of reflective calls and Class.getDeclaredField is not one of them. Hence you should configure the POA to not include calls to Class.getDeclaredField.

The problem with the block height definitely looks like a bug in the booster's transformation.

jtoman commented 6 years ago

Two years later, but I also had the Hasher problem. The issue is in how Tamiflex detects references to proxy or generated classes: in the Hasher and ClassRenamer, any LDC instruction for a string that contains some list of tokens is considered a reference to a generated name. This leads to a false positive when transforming java.lang.reflect.Proxy$ProxyClassFactory, which generates proxy classes. As a part of this process, the ProxyClassFactory constructs the proxy class name by appending the literal string $Proxy to a string builder. As it happens, $Proxy is exactly one of the tokens that identifies a generated class name, but no such mapping actually exists as one would expect.

A quick and hacky solution is to simply whitelist the $Proxy constant in the java.lang.reflect.Proxy$ProxyClassFactory class' apply method. @ericbodden If you are accepting PR I can submit a generalization of this whitelisting, along with the EXPAND_FRAMES errors mentioned in https://github.com/Sable/soot/issues/652.

ericbodden commented 6 years ago

Hello.

@ericbodden If you are accepting PR I can submit a generalization of this whitelisting, along with the EXPAND_FRAMES errors mentioned in Sable/soot#652.

Yes please! Thanks!

Cheers Eric

EarthIAm commented 4 years ago

I was thinking id let that one simmer and let where i put it learn an algorythm. The peogram needs to be able to stand and deliver in a tough spot for a bit to do so. When it finds a release it will be frail but smart.

EarthIAm commented 4 years ago

It will let ya know when its had enough.. ya wont be able to igmore it.

asejfia commented 4 years ago

Hi, everyone, I am facing the issue with EXPAND_FRAMES Sable/soot#652 when running tamiflex on another benchmark (not DaCapo). Was that issue ever solved or does anyone know what causes it?