Open malaverdiere opened 11 years ago
I forgot to attach the sources and the jars URLs http://mirrors.ibiblio.org/pub/mirrors/maven2/jetty/javax.servlet/5.1.11/javax.servlet-5.1.11.jar http://mirrors.ibiblio.org/pub/mirrors/maven2/tomcat/jasper-runtime/5.5.23/jasper-runtime-5.5.23.jar http://mirrors.ibiblio.org/pub/mirrors/maven2/tomcat/commons-logging/4.0.6/commons-logging-4.0.6.jar http://mirrors.ibiblio.org/pub/mirrors/maven2/tomcat/commons-el/5.5.23/commons-el-5.5.23.jar
Trans.java:
import soot.*;
import soot.jimple.*;
import soot.jimple.toolkits.base.Aggregator;
import soot.jimple.toolkits.scalar.ConstantPropagatorAndFolder;
import soot.jimple.toolkits.scalar.CopyPropagator;
import soot.jimple.toolkits.scalar.DeadAssignmentEliminator;
import soot.jimple.toolkits.scalar.NopEliminator;
import soot.toolkits.graph.*;
import soot.toolkits.scalar.LocalPacker;
import soot.toolkits.scalar.SimpleLocalDefs;
import soot.toolkits.scalar.UnusedLocalEliminator;
import soot.tagkit.LineNumberTag;
import soot.tagkit.SourceLineNumberTag;
import soot.tagkit.SourceLnNamePosTag;
import soot.tagkit.SourceLnPosTag;
import soot.tagkit.Tag;
import soot.util.Chain;
import java.util.*;
//import org.apache.jasper.runtime.JspRuntimeLibrary;
public class Trans extends BodyTransformer{
protected void internalTransform(Body body, String phaseName, Map options)
{
if (body.getMethod().getDeclaringClass().toString().compareTo("org.apache.jasper.runtime.ProtectedFunctionMapper") == 0 && body.getMethod().getName().compareTo("mapFunction") == 0)
{
//System.out.println("====================================================================================");
//System.out.println("\nInstrumenting " + body.getMethod().getSignature());
//System.out.println(body);
//System.out.println("====================================================================================");
}
}
}
Main.java:
import soot.Pack;
import soot.PackManager;
import soot.Scene;
import soot.SootClass;
import soot.Transform;
/* Soot - a J*va Optimization Framework
* Copyright (C) 2008 Eric Bodden
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
public class Main {
public static void main(String[] args)
{
final String jarDir = "/home/marc-andre/MinimalOriginalNameException/";
args = new String[] {
"-exclude", "org.apache.jasper.runtime.",
"-no-bodies-for-excluded",
"-p", "jb", "use-original-names:true",
"-p", "tag.ln", "enabled",
"-keep-line-number",
"-src-prec", "class",
"-validate",
"-prepend-classpath",
"-cp", jarDir+"/javax.servlet-5.1.11.jar;"+jarDir+"/commons-el-5.5.23.jar;"+jarDir+"tcommons-logging-4.0.6.jar;",
"-f", "class",
"-process-dir", "/home/marc-andre/MinimalOriginalNameException/jasper-runtime-5.5.23.jar"
};
Pack jtp = PackManager.v().getPack("jtp");
jtp.add(new Transform("jtp.trans", new Trans()));
Scene.v().addBasicClass("java.lang.StringBuilder", SootClass.SIGNATURES);
soot.Main.main(args);
}
}
The dump of the LocalVariableTable for the particular method will probably show that original names are not correctly reported by the compiler at the bytecode where l5 shows up.
I have added the following code in coffi.Util.resolveFromClassFile:
if (aClass.getName().equals("org.apache.jasper.runtime.ProtectedFunctionMapper")){
boolean foundLVT = false;
for (attribute_info ai: coffiClass.findMethod("mapFunction").attributes){
if (ai instanceof LocalVariableTable_attribute){
System.err.println("org.apache.jasper.runtime.ProtectedFunctionMapper mapFunction:");
System.err.println(ai.toString());
foundLVT = false;
}
if (!foundLVT)
System.err.println("+++++++++++++++++++ WARNING WARNING WARNING Local Variable Table is Empty ++++++++++++++++++++++");
}
}
I am getting that the local variable table is empty.
Hum, how can Coffi retrieve the other names then ?
I think it should be located as a sub-attribute of the CodeAttribute of the class. Here is how it is located in coffi:
Code_attribute ca = method.locate_code_attribute();
LocalVariableTable_attribute la = ca.findLocalVariableTable();
Am I trying to retrieve that information too early?
No, sorry my remark was a bit sarcastic: if the local variable table is empty, how can we explain all the original names we see in the jimple code.
Can you try something like
coffiClass.findMethod("mapFunction").locate_code_attibute().findLocalVariableTable();
I am getting this result
-------------------------- Local variable table: --------------------------
start: 26length: 3name_index: 54descriptor_index: 41index: 5
start: 31length: 34name_index: 55descriptor_index: 56index: 6
start: 74length: 3name_index: 54descriptor_index: 41index: 5
start: 79length: 31name_index: 57descriptor_index: 58index: 6
start: 0length: 122name_index: 47descriptor_index: 48index: 0
start: 0length: 122name_index: 59descriptor_index: 60index: 1
start: 0length: 122name_index: 61descriptor_index: 62index: 2
start: 0length: 122name_index: 63descriptor_index: 60index: 3
start: 0length: 122name_index: 64descriptor_index: 65index: 4
I am putting this chunk of code at the bottom of the method:
if (aClass.getName().equals("org.apache.jasper.runtime.ProtectedFunctionMapper")){
LocalVariableTable_attribute lvt = coffiClass.findMethod("mapFunction").locate_code_attribute().findLocalVariableTable();
if (lvt.local_variable_table_length == 0)
System.err.println("-------------------------- No local variable table -------------------");
else{
System.err.println("-------------------------- Local variable table: --------------------------");
System.err.println(lvt.toString());
}
}
The best would be to look at the bytecode of the class with "javac -c -p", it pretty-prints that part quite well.
Here is for the whole method
public void mapFunction(java.lang.String, java.lang.Class, java.lang.String, java.lang.Class[]);
Code:
0: invokestatic #5 // Method org/apache/jasper/security/SecurityUtil.isPackageProtectionEnabled:()Z
3: ifeq 65
6: new #12 // class org/apache/jasper/runtime/ProtectedFunctionMapper$2
9: dup
10: aload_0
11: aload_2
12: aload_3
13: aload 4
15: invokespecial #13 // Method org/apache/jasper/runtime/ProtectedFunctionMapper$2."<init>":(Lorg/apache/jasper/runtime/ProtectedFunctionMapper;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)V
18: invokestatic #14 // Method java/security/AccessController.doPrivileged:(Ljava/security/PrivilegedExceptionAction;)Ljava/lang/Object;
21: checkcast #15 // class java/lang/reflect/Method
24: astore 5
26: goto 110
29: astore 6
31: new #17 // class java/lang/RuntimeException
34: dup
35: new #18 // class java/lang/StringBuffer
38: dup
39: invokespecial #19 // Method java/lang/StringBuffer."<init>":()V
42: ldc #20 // String Invalid function mapping - no such method:
44: invokevirtual #21 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
47: aload 6
49: invokevirtual #22 // Method java/security/PrivilegedActionException.getException:()Ljava/lang/Exception;
52: invokevirtual #23 // Method java/lang/Exception.getMessage:()Ljava/lang/String;
55: invokevirtual #21 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
58: invokevirtual #24 // Method java/lang/StringBuffer.toString:()Ljava/lang/String;
61: invokespecial #25 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
64: athrow
65: aload_2
66: aload_3
67: aload 4
69: invokevirtual #26 // Method java/lang/Class.getDeclaredMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
72: astore 5
74: goto 110
77: astore 6
79: new #17 // class java/lang/RuntimeException
82: dup
83: new #18 // class java/lang/StringBuffer
86: dup
87: invokespecial #19 // Method java/lang/StringBuffer."<init>":()V
90: ldc #20 // String Invalid function mapping - no such method:
92: invokevirtual #21 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
95: aload 6
97: invokevirtual #28 // Method java/lang/NoSuchMethodException.getMessage:()Ljava/lang/String;
100: invokevirtual #21 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
103: invokevirtual #24 // Method java/lang/StringBuffer.toString:()Ljava/lang/String;
106: invokespecial #25 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
109: athrow
110: aload_0
111: getfield #3 // Field fnmap:Ljava/util/HashMap;
114: aload_1
115: aload 5
117: invokevirtual #29 // Method java/util/HashMap.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
120: pop
121: return
Exception table:
from to target type
6 26 29 Class java/security/PrivilegedActionException
65 74 77 Class java/lang/NoSuchMethodException
I just remembered the -verbose option is necessary too:
LineNumberTable:
line 95: 0
line 97: 6
line 107: 26
line 103: 29
line 104: 31
line 110: 65
line 115: 74
line 111: 77
line 112: 79
line 118: 110
line 119: 121
LocalVariableTable:
Start Length Slot Name Signature
26 3 5 method Ljava/lang/reflect/Method;
31 34 6 ex Ljava/security/PrivilegedActionException;
74 3 5 method Ljava/lang/reflect/Method;
79 31 6 e Ljava/lang/NoSuchMethodException;
0 122 0 this Lorg/apache/jasper/runtime/ProtectedFunctionMapper;
0 122 1 fnQName Ljava/lang/String;
0 122 2 c Ljava/lang/Class;
0 122 3 methodName Ljava/lang/String;
0 122 4 args [Ljava/lang/Class;
As you can see, local 5 doesn't have a name defined at bytecode position 115. Unfortunately, the same def/use local 5 appears at different positions with the name "method", thus the current local naming method creates disjoints Local.
When running Soot on jasper-runtime-5.5.23.jar, the following exception occurs only if use-original-names is enabled:
The body of the method is: