diff --git a/jode/Makefile.am b/jode/Makefile.am index 304113b..b0ee681 100644 --- a/jode/Makefile.am +++ b/jode/Makefile.am @@ -1,5 +1,5 @@ ## Input file for automake to generate the Makefile.in used by configure -SUBDIRS = jode doc test +SUBDIRS = jode bin doc test EXTRA_DIST = TODO diff --git a/jode/acinclude.m4 b/jode/acinclude.m4 index a7ef9df..8434847 100644 --- a/jode/acinclude.m4 +++ b/jode/acinclude.m4 @@ -6,8 +6,9 @@ dnl dnl JODE_CHECK_JAVA(path) AC_DEFUN(JODE_CHECK_JAVA, [ - AC_PATH_PROG(JAVAC, javac, "", $PATH:$1/bin) - AC_PATH_PROG(JAR, jar, "", $PATH:$1/bin) + AC_PATH_PROG(JAVA, java, "", $1/bin:$1/jre/bin:$PATH) + AC_PATH_PROG(JAVAC, javac, "", $1/bin:$PATH) + AC_PATH_PROG(JAR, jar, "", $1/bin:$PATH) for path in $1/lib $1/jre/lib $1/shared; do for classlib in classes.zip rt.jar; do AC_CHECK_FILES($path/$classlib, diff --git a/jode/bin/.cvsignore b/jode/bin/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/jode/bin/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/jode/bin/Makefile.am b/jode/bin/Makefile.am new file mode 100644 index 0000000..da0c744 --- /dev/null +++ b/jode/bin/Makefile.am @@ -0,0 +1,4 @@ +## Input file for automake to generate the Makefile.in used by configure + +bin_SCRIPTS = jode + diff --git a/jode/bin/jode.in b/jode/bin/jode.in new file mode 100644 index 0000000..75bad3b --- /dev/null +++ b/jode/bin/jode.in @@ -0,0 +1,14 @@ +#!@SHELL@ +prefix=@prefix@ + +case $1 in + [Ss]wi*) CLAZZ=jode.swingui.Main; shift ;; + [Dd]ec*) CLAZZ=jode.Decompiler; shift ;; + [Oo]bf*) CLAZZ=jode.obfuscator.Main; shift ;; + *) CLAZZ=jode.Decompiler ;; +esac + + +CP=`echo $CLASSPATH | sed s/:/,/` +CLASSPATH=@datadir@/jode-@VERSION@.jar:@CLASSPATH@ \ +@JAVA@ $CLAZZ --classpath $CP $* diff --git a/jode/configure.in b/jode/configure.in index beb8e1c..75fb50e 100644 --- a/jode/configure.in +++ b/jode/configure.in @@ -108,21 +108,32 @@ JODE_CHECK_CLASS(javax.swing.JFrame, $CLASSPATH:$CLASSLIB, AC_MSG_RESULT($JAVAX_SWING) AC_SUBST(JAVAX_SWING) if test x"$JAVAX_SWING" != x; then - SWING_CLASSES="jode/swingui/Main.class" + SWINGUI="swingui" else AC_MSG_WARN(Swing is not in classpath ... skipping swingui) - SWING_CLASSES="" + SWINGUI="" fi -AC_SUBST(SWING_CLASSES) +AC_SUBST(SWINGUI) AC_SUBST(CLASSPATH) AC_SUBST(JAVAC) AC_OUTPUT(Makefile jode/Makefile -doc/Makefile -test/Makefile +jode/bytecode/Makefile +jode/decompiler/Makefile +jode/expr/Makefile +jode/flow/Makefile +jode/jvm/Makefile +jode/obfuscator/Makefile +jode/swingui/Makefile +jode/type/Makefile +jode/util/Makefile jode/GlobalOptions.java jode/swingui/Main.java -jode/swingui/PackagesTreeModel.java) +jode/swingui/PackagesTreeModel.java +bin/Makefile +bin/jode +doc/Makefile +test/Makefile) diff --git a/jode/jode/Makefile.am b/jode/jode/Makefile.am index 289f87c..d39cc04 100644 --- a/jode/jode/Makefile.am +++ b/jode/jode/Makefile.am @@ -1,231 +1,54 @@ ## Input file for automake to generate the Makefile.in used by configure -EXTRA_DIST = \ - AssertError.java \ - bytecode/BinaryInfo.java \ - bytecode/BytecodeInfo.java \ - bytecode/ClassFormatException.java \ - bytecode/ClassInfo.java \ - bytecode/ConstantPool.java \ - bytecode/FieldInfo.java \ - bytecode/GrowableConstantPool.java \ - bytecode/Handler.java \ - bytecode/InnerClassInfo.java \ - bytecode/Instruction.java \ - bytecode/LineNumber.java \ - bytecode/LocalVariableInfo.java \ - bytecode/MethodInfo.java \ - bytecode/Opcodes.java \ - bytecode/Reference.java \ - bytecode/SearchPath.java \ - decompiler/Analyzer.java \ - decompiler/ClassAnalyzer.java \ - decompiler/ClassDeclarer.java \ - decompiler/DeadCodeAnalysis.java \ - decompiler/Declarable.java \ - decompiler/FieldAnalyzer.java \ - decompiler/ImportHandler.java \ - decompiler/LocalInfo.java \ - decompiler/LocalVarEntry.java \ - decompiler/LocalVariableRangeList.java \ - decompiler/LocalVariableTable.java \ - decompiler/MethodAnalyzer.java \ - decompiler/Opcodes.java \ - decompiler/OuterValueListener.java \ - decompiler/Scope.java \ - decompiler/TabbedPrintWriter.java \ - Decompiler.java \ - expr/ArrayLengthOperator.java \ - expr/ArrayLoadOperator.java \ - expr/ArrayStoreOperator.java \ - expr/BinaryOperator.java \ - expr/CheckCastOperator.java \ - expr/CheckNullOperator.java \ - expr/ClassFieldOperator.java \ - expr/CombineableOperator.java \ - expr/CompareBinaryOperator.java \ - expr/CompareToIntOperator.java \ - expr/CompareUnaryOperator.java \ - expr/ConstOperator.java \ - expr/ConstantArrayOperator.java \ - expr/ConstructorOperator.java \ - expr/ConvertOperator.java \ - expr/Expression.java \ - expr/GetFieldOperator.java \ - expr/IIncOperator.java \ - expr/IfThenElseOperator.java \ - expr/InstanceOfOperator.java \ - expr/InvokeOperator.java \ - expr/LValueExpression.java \ - expr/LocalLoadOperator.java \ - expr/LocalStoreOperator.java \ - expr/LocalVarOperator.java \ - expr/MatchableOperator.java \ - expr/MonitorEnterOperator.java \ - expr/MonitorExitOperator.java \ - expr/NewArrayOperator.java \ - expr/NewOperator.java \ - expr/NoArgOperator.java \ - expr/NopOperator.java \ - expr/Operator.java \ - expr/OuterLocalOperator.java \ - expr/PopOperator.java \ - expr/PrePostFixOperator.java \ - expr/PutFieldOperator.java \ - expr/ShiftOperator.java \ - expr/SimpleOperator.java \ - expr/StoreInstruction.java \ - expr/StringAddOperator.java \ - expr/ThisOperator.java \ - expr/UnaryOperator.java \ - flow/BreakBlock.java \ - flow/BreakableBlock.java \ - flow/CaseBlock.java \ - flow/CatchBlock.java \ - flow/CombineIfGotoExpressions.java \ - flow/CompleteSynchronized.java \ - flow/ConditionalBlock.java \ - flow/ContinueBlock.java \ - flow/CreateAssignExpression.java \ - flow/CreateCheckNull.java \ - flow/CreateClassField.java \ - flow/CreateConstantArray.java \ - flow/CreateExpression.java \ - flow/CreateForInitializer.java \ - flow/CreateIfThenElseOperator.java \ - flow/CreateNewConstructor.java \ - flow/CreatePrePostIncExpression.java \ - flow/DescriptionBlock.java \ - flow/EmptyBlock.java \ - flow/FinallyBlock.java \ - flow/FlowBlock.java \ - flow/IfThenElseBlock.java \ - flow/InstructionBlock.java \ - flow/InstructionContainer.java \ - flow/JsrBlock.java \ - flow/Jump.java \ - flow/LoopBlock.java \ - flow/RetBlock.java \ - flow/ReturnBlock.java \ - flow/SequentialBlock.java \ - flow/SlotSet.java \ - flow/SpecialBlock.java \ - flow/StructuredBlock.java \ - flow/SwitchBlock.java \ - flow/SynchronizedBlock.java \ - flow/ThrowBlock.java \ - flow/TransformConstructors.java \ - flow/TransformExceptionHandlers.java \ - flow/TryBlock.java \ - flow/VariableSet.java \ - flow/VariableStack.java \ - GlobalOptions.java.in \ - JodeApplet.java \ - JodeWindow.java \ - jvm/CodeVerifier.java \ - jvm/Interpreter.java \ - jvm/InterpreterException.java \ - jvm/NewObject.java \ - jvm/RuntimeEnvironment.java \ - jvm/SimpleRuntimeEnvironment.java \ - jvm/SyntheticAnalyzer.java \ - jvm/Value.java \ - jvm/VerifyException.java \ - obfuscator/ClassBundle.java \ - obfuscator/ClassIdentifier.java \ - obfuscator/CodeAnalyzer.java \ - obfuscator/CodeTransformer.java \ - obfuscator/ConstantAnalyzer.java \ - obfuscator/ConstantRuntimeEnvironment.java \ - obfuscator/FieldIdentifier.java \ - obfuscator/Identifier.java \ - obfuscator/IdentifierMatcher.java \ - obfuscator/LocalIdentifier.java \ - obfuscator/LocalOptimizer.java \ - obfuscator/LocalizeFieldTransformer.java \ - obfuscator/Main.java \ - obfuscator/MethodIdentifier.java \ - obfuscator/ModifierMatcher.java \ - obfuscator/NameSwapper.java \ - obfuscator/PackageIdentifier.java \ - obfuscator/RemovePopAnalyzer.java \ - obfuscator/Renamer.java \ - obfuscator/SimpleAnalyzer.java \ - obfuscator/StrongRenamer.java \ - obfuscator/TranslationTable.java \ - obfuscator/WildCard.java \ - swingui/Main.java \ - swingui/Main.java.in \ - swingui/PackagesTreeModel.java.in \ - swingui/PackagesTreeModel.java \ - type/ArrayType.java \ - type/ClassInterfacesType.java \ - type/IntegerType.java \ - type/MethodType.java \ - type/NullType.java \ - type/RangeType.java \ - type/ReferenceType.java \ - type/Type.java \ - util/AbstractCollection.java \ - util/AbstractList.java \ - util/AbstractMap.java \ - util/AbstractSequentialList.java \ - util/AbstractSet.java \ - util/ArrayEnum.java \ - util/ArrayList.java \ - util/Arrays.java \ - util/BasicMapEntry.java \ - util/Bucket.java \ - util/Collection.java \ - util/Collections.java \ - util/Comparable.java \ - util/Comparator.java \ - util/ConcurrentModificationException.java \ - util/HashMap.java \ - util/HashSet.java \ - util/Iterator.java \ - util/LinkedList.java \ - util/List.java \ - util/ListIterator.java \ - util/Map.java \ - util/Set.java \ - util/SimpleMap.java \ - util/SimpleSet.java \ - util/SortedMap.java \ - util/SortedSet.java \ - util/TreeMap.java \ - util/TreeSet.java \ - util/UnsupportedOperationException.java +SUBDIRS = bytecode type util jvm expr flow decompiler obfuscator @SWINGUI@ JAR = @JAR@ JAVAC = @JAVAC@ JIKES = @JIKES@ CLASSPATH = @CLASSPATH@ CLASSLIB = @CLASSLIB@ -BUILD_CLASSPATH = $(top_srcdir):$(top_builddir):.:$(CLASSPATH) +BUILD_CLASSPATH = $(top_srcdir):$(top_builddir):.:$(CLASSPATH):$(CLASSLIB) VPATH=$(srcdir):$(top_srcdir):$(top_builddir) -MY_CLASSES = jode/Decompiler.class jode/JodeApplet.class jode/JodeWindow.class jode/obfuscator/Main.class @SWING_CLASSES@ +MY_JAVA_FILES = \ + AssertError.java \ + Decompiler.java \ + GlobalOptions.java \ + JodeApplet.java \ + JodeWindow.java -pkgdata_DATA = jode.jar +noinst_DATA = $(MY_JAVA_FILES:.java=.class) +EXTRA_DIST = $(MY_JAVA_FILES) + + +JARFILE = jode-@VERSION@.jar +data_DATA = $(JARFILE) if HAVE_JIKES -@QUOTE@-include .java.deps +@QUOTE@-include $(top_builddir)/jode/.java.deps %.class: %.java - $(JIKES) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) +M=.java.deps -d . $< + $(JIKES) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) +M=$(top_builddir)/jode/.java.deps -d $(top_builddir) $< else %.class: %.java - $(JAVAC) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) -depend -d . $< + $(JAVAC) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) -depend -d $(top_builddir) $< endif clean-local: - @rm -rf jode - @rm -f jode.jar .java.deps - -jode.jar: $(MY_CLASSES) - CLASSPATH= $(JAR) -cf jode.jar jode + @rm -f *.class + @rm -f $(JARFILE) .java.deps + +$(JARFILE): $(noinst_DATA) + CLASSPATH=$(top_builddir):$(CLASSPATH) $(JAVA) -mx80m \ + jode.obfuscator.Main --dest $(JARFILE) \ + --revtable rename.table \ + --rename=none --breakserial --strip=unreach -v -v \ + --preserve 'jode.Decompiler.main.*' \ + --preserve 'jode.JodeApplet..*' \ + --preserve 'jode.JodeWindow.main.*' \ + --preserve 'jode.obfuscator.Main.main.*' \ + --preserve 'jode.swingui.Main.main.*' jode diff --git a/jode/jode/bytecode/.cvsignore b/jode/jode/bytecode/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/jode/jode/bytecode/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/jode/jode/bytecode/ClassInfo.java b/jode/jode/bytecode/ClassInfo.java index c8742ed..e0482cb 100644 --- a/jode/jode/bytecode/ClassInfo.java +++ b/jode/jode/bytecode/ClassInfo.java @@ -231,6 +231,11 @@ public class ClassInfo extends BinaryInfo { } public void read(DataInputStream input, int howMuch) throws IOException { + /* Since we have to read the whole class anyway, we load all + * info, that we may need later and that does not take much memory. + */ + howMuch |= FIELDS | METHODS | HIERARCHY | INNERCLASSES | OUTERCLASSES; + howMuch &= ~status; /* header */ if (input.readInt() != 0xcafebabe) throw new ClassFormatException("Wrong magic"); @@ -261,11 +266,13 @@ public class ClassInfo extends BinaryInfo { } /* fields */ - if ((howMuch & FIELDS) != 0) { + if ((howMuch & (FIELDS | ALL_ATTRIBUTES)) != 0) { int count = input.readUnsignedShort(); - fields = new FieldInfo[count]; + if ((howMuch & FIELDS) != 0) + fields = new FieldInfo[count]; for (int i=0; i< count; i++) { - fields[i] = new FieldInfo(this); + if ((howMuch & FIELDS) != 0) + fields[i] = new FieldInfo(this); fields[i].read(cpool, input, howMuch); } } else { @@ -278,11 +285,13 @@ public class ClassInfo extends BinaryInfo { } /* methods */ - if ((howMuch & METHODS) != 0) { + if ((howMuch & (METHODS | ALL_ATTRIBUTES)) != 0) { int count = input.readUnsignedShort(); - methods = new MethodInfo[count]; + if ((howMuch & METHODS) != 0) + methods = new MethodInfo[count]; for (int i=0; i< count; i++) { - methods[i] = new MethodInfo(this); + if ((howMuch & METHODS) != 0) + methods[i] = new MethodInfo(this); methods[i].read(cpool, input, howMuch); } } else { @@ -296,6 +305,7 @@ public class ClassInfo extends BinaryInfo { /* attributes */ readAttributes(cpool, input, howMuch); + status |= howMuch; } public void reserveSmallConstants(GrowableConstantPool gcp) { @@ -546,7 +556,6 @@ public class ClassInfo extends BinaryInfo { new DataInputStream(classpath.getFile(name.replace('.', '/') + ".class")); read(input, howMuch); - status |= howMuch; } catch (IOException ex) { String message = ex.getMessage(); @@ -645,7 +654,7 @@ public class ClassInfo extends BinaryInfo { public FieldInfo findField(String name, String typeSig) { if ((status & FIELDS) == 0) loadInfo(FIELDS); - for (int i=0; i< methods.length; i++) + for (int i=0; i< fields.length; i++) if (fields[i].getName().equals(name) && fields[i].getType().equals(typeSig)) return fields[i]; diff --git a/jode/jode/bytecode/FieldInfo.java b/jode/jode/bytecode/FieldInfo.java index 4facd8f..d67f409 100644 --- a/jode/jode/bytecode/FieldInfo.java +++ b/jode/jode/bytecode/FieldInfo.java @@ -159,6 +159,7 @@ public class FieldInfo extends BinaryInfo { } public Object getConstant() { + clazzInfo.loadInfo(ALL_ATTRIBUTES); return constant; } diff --git a/jode/jode/bytecode/Makefile.am b/jode/jode/bytecode/Makefile.am new file mode 100644 index 0000000..322a226 --- /dev/null +++ b/jode/jode/bytecode/Makefile.am @@ -0,0 +1,46 @@ +## Input file for automake to generate the Makefile.in used by configure + +JAR = @JAR@ +JAVAC = @JAVAC@ +JIKES = @JIKES@ +CLASSPATH = @CLASSPATH@ +CLASSLIB = @CLASSLIB@ +BUILD_CLASSPATH = $(top_srcdir):$(top_builddir):$(CLASSPATH):$(CLASSLIB) + +MY_JAVA_FILES = \ + BinaryInfo.java \ + BytecodeInfo.java \ + ClassFormatException.java \ + ClassInfo.java \ + ConstantPool.java \ + FieldInfo.java \ + GrowableConstantPool.java \ + Handler.java \ + InnerClassInfo.java \ + Instruction.java \ + LineNumber.java \ + LocalVariableInfo.java \ + MethodInfo.java \ + Opcodes.java \ + Reference.java \ + SearchPath.java + +noinst_DATA = $(MY_JAVA_FILES:.java=.class) +EXTRA_DIST = $(MY_JAVA_FILES) + +if HAVE_JIKES + +@QUOTE@-include $(top_builddir)/jode/.java.deps + +%.class: %.java + $(JIKES) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) +M=$(top_builddir)/jode/.java.deps -d $(top_builddir) $< + +else + +%.class: %.java + $(JAVAC) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) -depend -d $(top_builddir) $< + +endif + +clean-local: + @rm -f *.class diff --git a/jode/jode/bytecode/MethodInfo.java b/jode/jode/bytecode/MethodInfo.java index 8e41301..37d2dfe 100644 --- a/jode/jode/bytecode/MethodInfo.java +++ b/jode/jode/bytecode/MethodInfo.java @@ -211,10 +211,12 @@ public class MethodInfo extends BinaryInfo { } public void setBytecode(BytecodeInfo newBytecode) { + clazzInfo.loadInfo(ALL_ATTRIBUTES); bytecode = newBytecode; } public void setExceptions(String[] newExceptions) { + clazzInfo.loadInfo(ALL_ATTRIBUTES); exceptions = newExceptions; } diff --git a/jode/jode/decompiler/.cvsignore b/jode/jode/decompiler/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/jode/jode/decompiler/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/jode/jode/decompiler/Makefile.am b/jode/jode/decompiler/Makefile.am new file mode 100644 index 0000000..d20893b --- /dev/null +++ b/jode/jode/decompiler/Makefile.am @@ -0,0 +1,46 @@ +## Input file for automake to generate the Makefile.in used by configure + +JAR = @JAR@ +JAVAC = @JAVAC@ +JIKES = @JIKES@ +CLASSPATH = @CLASSPATH@ +CLASSLIB = @CLASSLIB@ +BUILD_CLASSPATH = $(top_srcdir):$(top_builddir):$(CLASSPATH):$(CLASSLIB) + +MY_JAVA_FILES = \ + Analyzer.java \ + ClassAnalyzer.java \ + ClassDeclarer.java \ + DeadCodeAnalysis.java \ + Declarable.java \ + FieldAnalyzer.java \ + ImportHandler.java \ + LocalInfo.java \ + LocalVarEntry.java \ + LocalVariableRangeList.java \ + LocalVariableTable.java \ + MethodAnalyzer.java \ + Opcodes.java \ + OuterValueListener.java \ + Scope.java \ + TabbedPrintWriter.java + +noinst_DATA = $(MY_JAVA_FILES:.java=.class) +EXTRA_DIST = $(MY_JAVA_FILES) + +if HAVE_JIKES + +@QUOTE@-include $(top_builddir)/jode/.java.deps + +%.class: %.java + $(JIKES) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) +M=$(top_builddir)/jode/.java.deps -d $(top_builddir) $< + +else + +%.class: %.java + $(JAVAC) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) -depend -d $(top_builddir) $< + +endif + +clean-local: + @rm -f *.class diff --git a/jode/jode/expr/.cvsignore b/jode/jode/expr/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/jode/jode/expr/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/jode/jode/expr/Makefile.am b/jode/jode/expr/Makefile.am new file mode 100644 index 0000000..2dd7352 --- /dev/null +++ b/jode/jode/expr/Makefile.am @@ -0,0 +1,73 @@ +## Input file for automake to generate the Makefile.in used by configure + +JAR = @JAR@ +JAVAC = @JAVAC@ +JIKES = @JIKES@ +CLASSPATH = @CLASSPATH@ +CLASSLIB = @CLASSLIB@ +BUILD_CLASSPATH = $(top_srcdir):$(top_builddir):$(CLASSPATH):$(CLASSLIB) + +MY_JAVA_FILES = \ + ArrayLengthOperator.java \ + ArrayLoadOperator.java \ + ArrayStoreOperator.java \ + BinaryOperator.java \ + CheckCastOperator.java \ + CheckNullOperator.java \ + ClassFieldOperator.java \ + CombineableOperator.java \ + CompareBinaryOperator.java \ + CompareToIntOperator.java \ + CompareUnaryOperator.java \ + ConstOperator.java \ + ConstantArrayOperator.java \ + ConstructorOperator.java \ + ConvertOperator.java \ + Expression.java \ + GetFieldOperator.java \ + IIncOperator.java \ + IfThenElseOperator.java \ + InstanceOfOperator.java \ + InvokeOperator.java \ + LValueExpression.java \ + LocalLoadOperator.java \ + LocalStoreOperator.java \ + LocalVarOperator.java \ + MatchableOperator.java \ + MonitorEnterOperator.java \ + MonitorExitOperator.java \ + NewArrayOperator.java \ + NewOperator.java \ + NoArgOperator.java \ + NopOperator.java \ + Operator.java \ + OuterLocalOperator.java \ + PopOperator.java \ + PrePostFixOperator.java \ + PutFieldOperator.java \ + ShiftOperator.java \ + SimpleOperator.java \ + StoreInstruction.java \ + StringAddOperator.java \ + ThisOperator.java \ + UnaryOperator.java + +noinst_DATA = $(MY_JAVA_FILES:.java=.class) +EXTRA_DIST = $(MY_JAVA_FILES) + +if HAVE_JIKES + +@QUOTE@-include $(top_builddir)/jode/.java.deps + +%.class: %.java + $(JIKES) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) +M=$(top_builddir)/jode/.java.deps -d $(top_builddir) $< + +else + +%.class: %.java + $(JAVAC) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) -depend -d $(top_builddir) $< + +endif + +clean-local: + @rm -f *.class diff --git a/jode/jode/flow/.cvsignore b/jode/jode/flow/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/jode/jode/flow/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/jode/jode/flow/Makefile.am b/jode/jode/flow/Makefile.am new file mode 100644 index 0000000..eed8d21 --- /dev/null +++ b/jode/jode/flow/Makefile.am @@ -0,0 +1,70 @@ +## Input file for automake to generate the Makefile.in used by configure + +JAR = @JAR@ +JAVAC = @JAVAC@ +JIKES = @JIKES@ +CLASSPATH = @CLASSPATH@ +CLASSLIB = @CLASSLIB@ +BUILD_CLASSPATH = $(top_srcdir):$(top_builddir):$(CLASSPATH):$(CLASSLIB) + +MY_JAVA_FILES = \ + BreakBlock.java \ + BreakableBlock.java \ + CaseBlock.java \ + CatchBlock.java \ + CombineIfGotoExpressions.java \ + CompleteSynchronized.java \ + ConditionalBlock.java \ + ContinueBlock.java \ + CreateAssignExpression.java \ + CreateCheckNull.java \ + CreateClassField.java \ + CreateConstantArray.java \ + CreateExpression.java \ + CreateForInitializer.java \ + CreateIfThenElseOperator.java \ + CreateNewConstructor.java \ + CreatePrePostIncExpression.java \ + DescriptionBlock.java \ + EmptyBlock.java \ + FinallyBlock.java \ + FlowBlock.java \ + IfThenElseBlock.java \ + InstructionBlock.java \ + InstructionContainer.java \ + JsrBlock.java \ + Jump.java \ + LoopBlock.java \ + RetBlock.java \ + ReturnBlock.java \ + SequentialBlock.java \ + SpecialBlock.java \ + StructuredBlock.java \ + SwitchBlock.java \ + SynchronizedBlock.java \ + ThrowBlock.java \ + TransformConstructors.java \ + TransformExceptionHandlers.java \ + TryBlock.java \ + VariableSet.java \ + VariableStack.java + +noinst_DATA = $(MY_JAVA_FILES:.java=.class) +EXTRA_DIST = $(MY_JAVA_FILES) + +if HAVE_JIKES + +@QUOTE@-include $(top_builddir)/jode/.java.deps + +%.class: %.java + $(JIKES) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) +M=$(top_builddir)/jode/.java.deps -d $(top_builddir) $< + +else + +%.class: %.java + $(JAVAC) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) -depend -d $(top_builddir) $< + +endif + +clean-local: + @rm -f *.class diff --git a/jode/jode/flow/TransformExceptionHandlers.java b/jode/jode/flow/TransformExceptionHandlers.java index 78b48a6..14c3331 100644 --- a/jode/jode/flow/TransformExceptionHandlers.java +++ b/jode/jode/flow/TransformExceptionHandlers.java @@ -323,13 +323,16 @@ public class TransformExceptionHandlers { } public void checkAndRemoveMonitorExit(FlowBlock tryFlow, LocalInfo local, + int startOutExit, int endOutExit, int startMonExit, int endMonExit) { FlowBlock subRoutine = null; + FlowBlock exitBlock = null; Iterator succs = tryFlow.getSuccessors().iterator(); dest_loop: while (succs.hasNext()) { + boolean isFirstJump = true; for (Jump jumps = tryFlow.getJumps((FlowBlock) succs.next()); - jumps != null; jumps = jumps.next) { + jumps != null; jumps = jumps.next, isFirstJump = false) { StructuredBlock prev = jumps.prev; @@ -390,28 +393,59 @@ public class TransformExceptionHandlers { continue; } - /* The block is a jsr that is not preceeded by another jsr. - * This must be the monitorexit subroutine. - */ - if (prev instanceof JsrBlock && subRoutine == null) { - - subRoutine = jumps.destination; - subRoutine.analyze(startMonExit, endMonExit); - transformSubRoutine(subRoutine.block); - - if (subRoutine.block instanceof InstructionBlock) { - Expression instr = - ((InstructionBlock)subRoutine.block) - .getInstruction(); - if (isMonitorExit(instr, local)) { - tryFlow.mergeAddr(subRoutine); - continue dest_loop; - } - } - } + if (isFirstJump) { + /* This is the first jump to that destination. + * Check if the destination does the monitorExit + */ - /* Now we have a jump that is not preceded by a monitorexit. - * Complain! + /* The block is a jsr that is not preceeded by + * another jsr. This must be the monitorexit + * subroutine. + */ + if (prev instanceof JsrBlock && subRoutine == null) { + + subRoutine = jumps.destination; + subRoutine.analyze(startMonExit, endMonExit); + transformSubRoutine(subRoutine.block); + + if (subRoutine.block instanceof InstructionBlock) { + Expression instr = + ((InstructionBlock)subRoutine.block) + .getInstruction(); + if (isMonitorExit(instr, local)) { + tryFlow.mergeAddr(subRoutine); + continue dest_loop; + } + } + } + + /* Now we have a jump that is not preceded by a + * monitorexit. There's a last chance: the jump + * jumps directly to the correct monitorexit + * instruction, which lies outside the try/catch + * block. + */ + if (exitBlock == null + && jumps.destination.getAddr() >= startOutExit + && jumps.destination.getNextAddr() <= endOutExit) { + jumps.destination.analyze(startOutExit, endOutExit); + + StructuredBlock sb = jumps.destination.block; + if (sb instanceof SequentialBlock) + sb = sb.getSubBlocks()[0]; + if (sb instanceof InstructionBlock) { + Expression instr = ((InstructionBlock)sb) + .getInstruction(); + if (isMonitorExit(instr, local)) { + sb.removeBlock(); + exitBlock = jumps.destination; + continue dest_loop; + } + } + } + } + + /* Complain! */ DescriptionBlock msg = new DescriptionBlock("ERROR: NO MONITOREXIT"); @@ -476,11 +510,13 @@ public class TransformExceptionHandlers { LocalInfo local = ((LocalLoadOperator)monexit.getSubExpressions()[0]) .getLocalInfo(); - tryFlow.mergeAddr(catchFlow); checkAndRemoveMonitorExit - (tryFlow, local, catchFlow.getNextAddr(), endHandler); - + (tryFlow, local, + tryFlow.getNextAddr(), catchFlow.getAddr(), + catchFlow.getNextAddr(), endHandler); + + tryFlow.mergeAddr(catchFlow); SynchronizedBlock syncBlock = new SynchronizedBlock(local); TryBlock tryBlock = (TryBlock) tryFlow.block; syncBlock.replace(tryBlock); @@ -636,12 +672,13 @@ public class TransformExceptionHandlers { TryBlock tryBlock = (TryBlock)tryFlow.block; if (tryBlock.getSubBlocks()[0] instanceof TryBlock) { - /* remove the nested tryBlock */ + /* remove the surrounding tryBlock */ TryBlock innerTry = (TryBlock)tryBlock.getSubBlocks()[0]; innerTry.gen = tryBlock.gen; innerTry.replace(tryBlock); tryBlock = innerTry; - tryFlow.lastModified = innerTry; + tryFlow.lastModified = tryBlock; + tryFlow.block = tryBlock; } FinallyBlock newBlock = new FinallyBlock(); newBlock.setCatchBlock(finallyBlock); @@ -784,22 +821,23 @@ public class TransformExceptionHandlers { FlowBlock tryFlow = exc.start; tryFlow.checkConsistent(); - if ((GlobalOptions.debuggingFlags - & GlobalOptions.DEBUG_ANALYZE) != 0) - GlobalOptions.err.println - ("analyzeTry(" - + exc.start.getAddr() + ", " + exc.endAddr+")"); - while (tryFlow.analyze(tryFlow.getAddr(), exc.endAddr)); - if (last == null + if (last == null || exc.type == null || last.start.getAddr() != exc.start.getAddr() || last.endAddr != exc.endAddr) { /* The last handler does catch another range. * Create a new try block. */ + if ((GlobalOptions.debuggingFlags + & GlobalOptions.DEBUG_ANALYZE) != 0) + GlobalOptions.err.println + ("analyzeTry(" + + exc.start.getAddr() + ", " + exc.endAddr+")"); + while (tryFlow.analyze(tryFlow.getAddr(), exc.endAddr)); + TryBlock tryBlock = new TryBlock(tryFlow); - } else if (! (tryFlow.block instanceof TryBlock)) - throw new AssertError("no TryBlock"); + } else if (!(tryFlow.block instanceof TryBlock)) + throw new AssertError("no TryBlock"); FlowBlock catchFlow = exc.handler; boolean isMultiUsed = catchFlow.predecessors.size() != 0; @@ -823,8 +861,8 @@ public class TransformExceptionHandlers { FlowBlock newFlow = new FlowBlock(catchFlow.method, catchFlow.getAddr(), 0); newFlow.setBlock(jump); - catchFlow.prevByAddr.setNextByAddr(newFlow); - newFlow.setNextByAddr(catchFlow); + catchFlow.prevByAddr.nextByAddr = newFlow; + newFlow.nextByAddr = catchFlow; catchFlow = newFlow; } else { if ((GlobalOptions.debuggingFlags diff --git a/jode/jode/jvm/.cvsignore b/jode/jode/jvm/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/jode/jode/jvm/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/jode/jode/jvm/Makefile.am b/jode/jode/jvm/Makefile.am new file mode 100644 index 0000000..42c17f1 --- /dev/null +++ b/jode/jode/jvm/Makefile.am @@ -0,0 +1,39 @@ +## Input file for automake to generate the Makefile.in used by configure + +JAR = @JAR@ +JAVAC = @JAVAC@ +JIKES = @JIKES@ +CLASSPATH = @CLASSPATH@ +CLASSLIB = @CLASSLIB@ +BUILD_CLASSPATH = $(top_srcdir):$(top_builddir):$(CLASSPATH):$(CLASSLIB) + +MY_JAVA_FILES = \ + CodeVerifier.java \ + Interpreter.java \ + InterpreterException.java \ + NewObject.java \ + RuntimeEnvironment.java \ + SimpleRuntimeEnvironment.java \ + SyntheticAnalyzer.java \ + Value.java \ + VerifyException.java + +noinst_DATA = $(MY_JAVA_FILES:.java=.class) +EXTRA_DIST = $(MY_JAVA_FILES) + +if HAVE_JIKES + +@QUOTE@-include $(top_builddir)/jode/.java.deps + +%.class: %.java + $(JIKES) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) +M=$(top_builddir)/jode/.java.deps -d $(top_builddir) $< + +else + +%.class: %.java + $(JAVAC) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) -depend -d $(top_builddir) $< + +endif + +clean-local: + @rm -f *.class diff --git a/jode/jode/obfuscator/.cvsignore b/jode/jode/obfuscator/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/jode/jode/obfuscator/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/jode/jode/obfuscator/ClassBundle.java b/jode/jode/obfuscator/ClassBundle.java index 20c087a..013d19b 100644 --- a/jode/jode/obfuscator/ClassBundle.java +++ b/jode/jode/obfuscator/ClassBundle.java @@ -139,8 +139,10 @@ public class ClassBundle { analyze(); } - public void analyzeIdentifier(Identifier i) { - toAnalyze.add(i); + public void analyzeIdentifier(Identifier ident) { + if (ident == null) + throw new NullPointerException(); + toAnalyze.add(ident); } public void analyze() { diff --git a/jode/jode/obfuscator/ClassIdentifier.java b/jode/jode/obfuscator/ClassIdentifier.java index 0885c80..86f659b 100644 --- a/jode/jode/obfuscator/ClassIdentifier.java +++ b/jode/jode/obfuscator/ClassIdentifier.java @@ -40,6 +40,7 @@ import jode.util.Iterator; import jode.util.List; import jode.util.LinkedList; import jode.util.Map; +import jode.util.UnsupportedOperationException; ///#endif import java.lang.reflect.Modifier; @@ -57,7 +58,6 @@ public class ClassIdentifier extends Identifier { String superName; String[] ifaceNames; - List identifiers; List fieldIdents, methodIdents; List knownSubClasses = new LinkedList(); List virtualReachables = new LinkedList(); @@ -82,6 +82,7 @@ public class ClassIdentifier extends Identifier { String fullName = getFullName() + "."; for (Iterator i = getChilds(); i.hasNext(); ) { Identifier ident = (Identifier) i.next(); + System.err.println("checking "+ident); if (wildcard.matches(fullName + ident.getName()) || wildcard.matches(fullName + ident.getName() + "." +ident.getType())) { @@ -94,8 +95,24 @@ public class ClassIdentifier extends Identifier { } } - public void preserveIdentifier(String name, String typeSig) { - preserveMatchingIdentifier(new WildCard(name+"."+typeSig)); + private FieldIdentifier findField(String name, String typeSig) { + for (Iterator i = fieldIdents.iterator(); i.hasNext(); ) { + FieldIdentifier ident = (FieldIdentifier) i.next(); + if (ident.getName().equals(name) + && ident.getType().equals(typeSig)) + return ident; + } + return null; + } + + private MethodIdentifier findMethod(String name, String typeSig) { + for (Iterator i = methodIdents.iterator(); i.hasNext(); ) { + MethodIdentifier ident = (MethodIdentifier) i.next(); + if (ident.getName().equals(name) + && ident.getType().equals(typeSig)) + return ident; + } + return null; } public void reachableIdentifier(String name, String typeSig, @@ -109,6 +126,20 @@ public class ClassIdentifier extends Identifier { found = true; } } + if (!found) { + // This means that the method is inherited from parent and + // must be marked as reachable there, (but not virtual). + // Consider following: + // A method in Collection and AbstractCollection is not reachable + // but it is reachable in Set and not implemented in AbstractSet + // In that case the method must be marked reachable in + // AbstractCollection. + ClassIdentifier superIdent = Main.getClassBundle() + .getClassIdentifier(info.getSuperclass().getName()); + if (superIdent != null) + superIdent.reachableIdentifier(name, typeSig, false); + } + if (isVirtual) { for (Iterator i = knownSubClasses.iterator(); i.hasNext(); ) ((ClassIdentifier)i.next()) @@ -117,13 +148,13 @@ public class ClassIdentifier extends Identifier { } } - public void chainIdentifier(Identifier chainIdent) { + public void chainMethodIdentifier(Identifier chainIdent) { String name = chainIdent.getName(); String typeSig = chainIdent.getType(); - for (Iterator i = getChilds(); i.hasNext(); ) { + for (Iterator i = methodIdents.iterator(); i.hasNext(); ) { Identifier ident = (Identifier) i.next(); - if (ident.getName().equals(ident.getName()) - && (ident.getType().equals(typeSig))) + if (ident.getName().equals(name) + && ident.getType().equals(typeSig)) chainIdent.addShadow(ident); } } @@ -246,33 +277,28 @@ public class ClassIdentifier extends Identifier { * a compatible class. */ public void preserveSerializable() { - preserveIdentifier("writeObject", "(Ljava.io.ObjectOutputStream)V"); - preserveIdentifier("readObject", "(Ljava.io.ObjectOutputStream)V"); + Identifier method + = findMethod("writeObject", "(Ljava.io.ObjectOutputStream)V"); + if (method != null) + method.setPreserved(); + method = findMethod("readObject", "(Ljava.io.ObjectInputStream)V"); + if (method != null) + method.setPreserved(); if ((Main.options & Main.OPTION_PRESERVESERIAL) != 0) { setPreserved(); - boolean hasSerialUID = false; - for (Iterator i = getFieldIdents().iterator(); i.hasNext(); ) { - Identifier ident = (Identifier) i.next(); - if ("serialVersionUID".equals(ident.getName()) - && "J".equals(ident.getType())) { - ident.setReachable(); - ident.setPreserved(); - hasSerialUID = true; - break; - } - } - if (!hasSerialUID) { + Identifier UIDident = findField("serialVersionUID", "J"); + if (UIDident == null) { /* add a field serializableVersionUID if not existent */ long serialVersion = calcSerialVersionUID(); FieldInfo UIDField = new FieldInfo (info, "serialVersionUID", "J", Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL); UIDField.setConstant(new Long(serialVersion)); - FieldIdentifier fident = new FieldIdentifier(this, UIDField); - fident.setPreserved(); - fident.setReachable(); - fieldIdents.add(fident); + UIDident = new FieldIdentifier(this, UIDField); + fieldIdents.add(UIDident); } + UIDident.setReachable(); + UIDident.setPreserved(); for (Iterator i=getFieldIdents().iterator(); i.hasNext(); ) { FieldIdentifier ident = (FieldIdentifier) i.next(); if ((ident.info.getModifiers() @@ -358,7 +384,7 @@ public class ClassIdentifier extends Identifier { | Modifier.FINAL) & modif) == 0 && !(mid.getName().equals(""))) { // chain the preserved/same name lists. - chainIdentifier(mid); + chainMethodIdentifier(mid); } } } else { @@ -371,8 +397,10 @@ public class ClassIdentifier extends Identifier { if (((Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL) & modif) == 0 && !topmethods[i].getName().equals("")) { - preserveIdentifier + Identifier method = findMethod (topmethods[i].getName(), topmethods[i].getType()); + if (method != null) + method.setPreserved(); } } } @@ -393,10 +421,8 @@ public class ClassIdentifier extends Identifier { Collections.shuffle(Arrays.asList(finfos), rand); Collections.shuffle(Arrays.asList(minfos), rand); } - identifiers = new ArrayList(finfos.length + minfos.length); - fieldIdents = identifiers.subList(0, 0); - methodIdents = identifiers.subList(0, 0); - identifiers = Collections.unmodifiableList(identifiers); + fieldIdents = new ArrayList(finfos.length); + methodIdents = new ArrayList(minfos.length); for (int i=0; i< finfos.length; i++) fieldIdents.add(new FieldIdentifier(this, finfos[i])); @@ -665,36 +691,30 @@ public class ClassIdentifier extends Identifier { transformSuperIfaces(); transformInnerClasses(); - int newFieldCount = 0, newMethodCount = 0; - if ((Main.stripping & Main.STRIP_UNREACH) != 0) { - for (Iterator i = fieldIdents.iterator(); i.hasNext(); ) { - Identifier ident = (Identifier) i.next(); - if (!ident.isReachable()) - i.remove(); - } - for (Iterator i = methodIdents.iterator(); i.hasNext(); ) { - Identifier ident = (Identifier) i.next(); - if (!ident.isReachable()) - i.remove(); - } - } - FieldInfo[] newFields = new FieldInfo[fieldIdents.size()]; - MethodInfo[] newMethods = new MethodInfo[methodIdents.size()]; - newFieldCount = newMethodCount = 0; + Collection newFields = new ArrayList(fieldIdents.size()); + Collection newMethods = new ArrayList(methodIdents.size()); for (Iterator i = fieldIdents.iterator(); i.hasNext(); ) { FieldIdentifier ident = (FieldIdentifier)i.next(); - ident.doTransformations(); - newFields[newFieldCount++] = ident.info; + if ((Main.stripping & Main.STRIP_UNREACH) == 0 + || ident.isReachable()) { + ident.doTransformations(); + newFields.add(ident.info); + } } for (Iterator i = methodIdents.iterator(); i.hasNext(); ) { MethodIdentifier ident = (MethodIdentifier)i.next(); - ident.doTransformations(); - newMethods[newMethodCount++] = ident.info; + if ((Main.stripping & Main.STRIP_UNREACH) == 0 + || ident.isReachable()) { + ident.doTransformations(); + newMethods.add(ident.info); + } } - info.setFields(newFields); - info.setMethods(newMethods); + info.setFields((FieldInfo[]) newFields.toArray + (new FieldInfo[newFields.size()])); + info.setMethods((MethodInfo[]) newMethods.toArray + (new MethodInfo[newMethods.size()])); } public void storeClass(DataOutputStream out) throws IOException { @@ -702,7 +722,7 @@ public class ClassIdentifier extends Identifier { GlobalOptions.err.println("Writing "+this); info.write(out); info = null; - identifiers = null; + fieldIdents = methodIdents = null; } public Identifier getParent() { @@ -746,7 +766,28 @@ public class ClassIdentifier extends Identifier { } public Iterator getChilds() { - return identifiers.iterator(); + final Iterator fieldIter = fieldIdents.iterator(); + final Iterator methodIter = methodIdents.iterator(); + + return new Iterator() { + boolean fieldsNext = fieldIter.hasNext(); + public boolean hasNext() { + return fieldsNext ? true : methodIter.hasNext(); + } + + public Object next() { + if (fieldsNext) { + Object result = fieldIter.next(); + fieldsNext = fieldIter.hasNext(); + return result; + } + return methodIter.next(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + }; } public String toString() { @@ -754,24 +795,13 @@ public class ClassIdentifier extends Identifier { } public Identifier getIdentifier(String fieldName, String typeSig) { - for (Iterator i = identifiers.iterator(); i.hasNext(); ) { + for (Iterator i = getChilds(); i.hasNext(); ) { Identifier ident = (Identifier) i.next(); if (ident.getName().equals(fieldName) && ident.getType().startsWith(typeSig)) return ident; } - for (int i=0; i < ifaceNames.length; i++) { - ClassIdentifier ifaceident = Main.getClassBundle() - .getClassIdentifier(ifaceNames[i]); - if (ifaceident != null) { - Identifier ident - = ifaceident.getIdentifier(fieldName, typeSig); - if (ident != null) - return ident; - } - } - if (superName != null) { ClassIdentifier superident = Main.getClassBundle() .getClassIdentifier(superName); diff --git a/jode/jode/obfuscator/ConstantAnalyzer.java b/jode/jode/obfuscator/ConstantAnalyzer.java index 27d5619..9889ed5 100644 --- a/jode/jode/obfuscator/ConstantAnalyzer.java +++ b/jode/jode/obfuscator/ConstantAnalyzer.java @@ -448,10 +448,17 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer { (clName.substring(1, clName.length()-1) .replace('/','.')); } - while (clazz != null - && clazz.findMethod(ref.getName(), - ref.getType()) == null) - clazz = clazz.getSuperclass(); + if (instr.opcode >= opc_invokevirtual) { + while (clazz != null + && clazz.findMethod(ref.getName(), + ref.getType()) == null) + clazz = clazz.getSuperclass(); + } else { + while (clazz != null + && clazz.findField(ref.getName(), + ref.getType()) == null) + clazz = clazz.getSuperclass(); + } if (clazz == null) { GlobalOptions.err.println("WARNING: Can't find reference: " @@ -1371,6 +1378,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer { } public void analyzeCode(MethodIdentifier listener, BytecodeInfo bytecode) { + this.listener = listener; this.bytecode = bytecode; working = true; if (constInfos == null) diff --git a/jode/jode/obfuscator/FieldIdentifier.java b/jode/jode/obfuscator/FieldIdentifier.java index dd881ae..cae8bfc 100644 --- a/jode/jode/obfuscator/FieldIdentifier.java +++ b/jode/jode/obfuscator/FieldIdentifier.java @@ -111,6 +111,8 @@ public class FieldIdentifier extends Identifier{ } public void addFieldListener(Identifier ident) { + if (ident == null) + throw new NullPointerException(); if (!fieldListeners.contains(ident)) fieldListeners.add(ident); } diff --git a/jode/jode/obfuscator/Identifier.java b/jode/jode/obfuscator/Identifier.java index c92a6ea..95e58a3 100644 --- a/jode/jode/obfuscator/Identifier.java +++ b/jode/jode/obfuscator/Identifier.java @@ -179,14 +179,13 @@ public abstract class Identifier { if (GlobalOptions.verboseLevel > 4) GlobalOptions.err.println(toString() + " is preserved"); } else { - Identifier rep = getRepresentative(); if (rep.wasAliased) return; rep.wasAliased = true; // set alias to empty string, so it won't conflict! - alias = ""; + rep.alias = ""; String newAlias = null; next_alias: for (;;) { @@ -198,7 +197,7 @@ public abstract class Identifier { ptr = ptr.right; } setAlias(newAlias.toString()); - return; + break; } } for (Iterator i = getChilds(); i.hasNext(); ) diff --git a/jode/jode/obfuscator/Main.java b/jode/jode/obfuscator/Main.java index 861c19f..a9b88d4 100644 --- a/jode/jode/obfuscator/Main.java +++ b/jode/jode/obfuscator/Main.java @@ -184,7 +184,7 @@ public class Main { } public static CodeAnalyzer createCodeAnalyzer() { - return new ConstantAnalyzer() /*XXX*/; + return new SimpleAnalyzer() /*XXX*/; } static CodeTransformer[] codeTransformers = { diff --git a/jode/jode/obfuscator/Makefile.am b/jode/jode/obfuscator/Makefile.am new file mode 100644 index 0000000..2cf76b8 --- /dev/null +++ b/jode/jode/obfuscator/Makefile.am @@ -0,0 +1,53 @@ +## Input file for automake to generate the Makefile.in used by configure + +JAR = @JAR@ +JAVAC = @JAVAC@ +JIKES = @JIKES@ +CLASSPATH = @CLASSPATH@ +CLASSLIB = @CLASSLIB@ +BUILD_CLASSPATH = $(top_srcdir):$(top_builddir):$(CLASSPATH):$(CLASSLIB) + +MY_JAVA_FILES = \ + ClassBundle.java \ + ClassIdentifier.java \ + CodeAnalyzer.java \ + CodeTransformer.java \ + ConstantAnalyzer.java \ + ConstantRuntimeEnvironment.java \ + FieldIdentifier.java \ + Identifier.java \ + IdentifierMatcher.java \ + LocalIdentifier.java \ + LocalOptimizer.java \ + Main.java \ + MethodIdentifier.java \ + ModifierMatcher.java \ + NameSwapper.java \ + PackageIdentifier.java \ + RemovePopAnalyzer.java \ + Renamer.java \ + SimpleAnalyzer.java \ + StrongRenamer.java \ + TranslationTable.java \ + WildCard.java +# LocalizeFieldTransformer.java + +noinst_DATA = $(MY_JAVA_FILES:.java=.class) +EXTRA_DIST = $(MY_JAVA_FILES) + +if HAVE_JIKES + +@QUOTE@-include $(top_builddir)/jode/.java.deps + +%.class: %.java + $(JIKES) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) +M=$(top_builddir)/jode/.java.deps -d $(top_builddir) $< + +else + +%.class: %.java + $(JAVAC) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) -depend -d $(top_builddir) $< + +endif + +clean-local: + @rm -f *.class diff --git a/jode/jode/obfuscator/ModifierMatcher.java b/jode/jode/obfuscator/ModifierMatcher.java index 1119c09..806b863 100644 --- a/jode/jode/obfuscator/ModifierMatcher.java +++ b/jode/jode/obfuscator/ModifierMatcher.java @@ -107,7 +107,7 @@ public class ModifierMatcher implements IdentifierMatcher, Cloneable { if (implies(and, xor, andMasks[i], xorMasks[i])) continue next_i; - for (int j=0; j= opc_invokevirtual) { + while (clazz != null + && clazz.findMethod(ref.getName(), + ref.getType()) == null) + clazz = clazz.getSuperclass(); + } else { + while (clazz != null + && clazz.findField(ref.getName(), + ref.getType()) == null) + clazz = clazz.getSuperclass(); + } + + if (clazz == null) { + GlobalOptions.err.println("WARNING: Can't find reference: " + +ref); + realClazzName = clName; + } else + realClazzName = "L" + clazz.getName().replace('.', '/') + ";"; + } + if (!realClazzName.equals(ref.getClazz())) { + ref = Reference.getReference(realClazzName, + ref.getName(), ref.getType()); + instr.objData = ref; + } + return ident; + } + + /** * Reads the opcodes out of the code info and determine its * references @@ -54,52 +113,21 @@ public class SimpleAnalyzer implements CodeAnalyzer, Opcodes { /* fall through */ case opc_getstatic: case opc_getfield: { - Reference ref = (Reference) instr.objData; - Identifier ident = Main.getClassBundle().getIdentifier(ref); - String clName = ref.getClazz(); - String realClazzName; + Identifier ident = canonizeReference(instr); if (ident != null) { - ClassIdentifier clazz = (ClassIdentifier)ident.getParent(); - realClazzName = "L" + (clazz.getFullName() - .replace('.', '/')) + ";"; if (instr.opcode == opc_putstatic || instr.opcode == opc_putfield) { FieldIdentifier fi = (FieldIdentifier) ident; if (fi != null && !fi.isNotConstant()) fi.setNotConstant(); + } else if (instr.opcode == opc_invokevirtual + || instr.opcode == opc_invokeinterface) { + ((ClassIdentifier) ident.getParent()) + .reachableIdentifier(ident.getName(), + ident.getType(), true); } else { - clazz.reachableIdentifier - (ref.getName(), ref.getType(), - instr.opcode == opc_invokevirtual - || instr.opcode == opc_invokeinterface); + ident.setReachable(); } - } else { - /* We have to look at the ClassInfo's instead, to - * point to the right method. - */ - ClassInfo clazz; - if (clName.charAt(0) == '[') { - /* Arrays don't define new methods (well clone(), - * but that can be ignored). - */ - clazz = ClassInfo.javaLangObject; - } else { - clazz = ClassInfo.forName - (clName.substring(1, clName.length()-1) - .replace('/','.')); - } - while (clazz != null - && clazz.findMethod(ref.getName(), - ref.getType()) == null) - clazz = clazz.getSuperclass(); - - realClazzName = (clazz != null) ? clName - : "L" + clazz.getName().replace('.', '/') + ";"; - } - if (!realClazzName.equals(ref.getClazz())) { - ref = Reference.getReference(realClazzName, - ref.getName(), ref.getType()); - instr.objData = ref; } break; } diff --git a/jode/jode/swingui/.cvsignore b/jode/jode/swingui/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/jode/jode/swingui/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/jode/jode/swingui/Main.java.in b/jode/jode/swingui/Main.java.in index 50fbeca..077a4f4 100644 --- a/jode/jode/swingui/Main.java.in +++ b/jode/jode/swingui/Main.java.in @@ -266,7 +266,7 @@ public class Main String cp = System.getProperty("java.class.path", ""); cp = cp.replace(File.pathSeparatorChar, SearchPath.pathSeparatorChar); for (int i=0; i