diff --git a/jode/.cvsignore b/jode/.cvsignore new file mode 100644 index 0000000..92379e3 --- /dev/null +++ b/jode/.cvsignore @@ -0,0 +1,9 @@ +Makefile +Makefile.in +configure +config.log +config.cache +config.status +stamp-h +libtool +aclocal.m4 diff --git a/jode/AUTHORS b/jode/AUTHORS new file mode 100644 index 0000000..fc38b9f --- /dev/null +++ b/jode/AUTHORS @@ -0,0 +1 @@ +Jochen Hoenicke \ No newline at end of file diff --git a/jode/ChangeLog b/jode/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/jode/INSTALL b/jode/INSTALL new file mode 100644 index 0000000..2aafeea --- /dev/null +++ b/jode/INSTALL @@ -0,0 +1,33 @@ +Before installing, make sure you have a java compiler (e.g javac or +jikes) and the java 1.1 runtime class library installed. If you want +to run this program you need at least a 1.1 compatible java virtual +machine. There are some bugs in javac included in the SUN JDK 1.1, it +won't work. + +This package was designed to use the GNU standard for configuration +and makefiles. To build and install do the following: + +0). Make sure that you have all libraries that are needed in you +classpath. You need gnu.getopt, and if you have JDK 1.1 you also need +the collection classes and swing for 1.1. + +1). Run "aclocal && autoconf && automake --add-missing". + +2). Run the "configure" script to configure the package. There are +various options you might want to pass to configure to control how the +package is built. "configure --help" will give a complete list. + +If you have jikes, you should specify it with --with-jikes. You can +give a path to the directory where it resides, otherwise it is +searched in the path. + +3). Type "make" to build the package. If you don't have jikes, you +should make clean first, since the dependency problem is not yet +resolved. + +4). Type "make install" to install everything. This doesn't work yet. + +The created jar file is stored in the share directory. + + Jochen + diff --git a/jode/Makefile.am b/jode/Makefile.am new file mode 100644 index 0000000..3cefb32 --- /dev/null +++ b/jode/Makefile.am @@ -0,0 +1,7 @@ +## Input file for automake to generate the Makefile.in used by configure + +SUBDIRS = jode doc test + +EXTRA_DIST = TODO \ + jode.html jode-applet.html jode-obfuscator.html jode-unix.html \ + jode-useapplet.html jode-win.html diff --git a/jode/NEWS b/jode/NEWS new file mode 100644 index 0000000..de761b2 --- /dev/null +++ b/jode/NEWS @@ -0,0 +1,10 @@ +1.0.90 is a prerelease.. +* First version using configure. Jode can now be almost automatically + build, see INSTALL for instructions. +* The decompiler can handler inner and anoymous classes. +* You now need the gnu getopt package. +* You need JDK 1.2 or alternatively the swing and collection packages + for 1.1 + + + diff --git a/jode/README b/jode/README new file mode 100644 index 0000000..c3f70f8 --- /dev/null +++ b/jode/README @@ -0,0 +1,106 @@ +takes class-files as input and produces something similar to the +original java-File. Of course this can't be perfect: There is no way +to produce the comments or the names of local variables (except when +compiled with -g) and there are often more ways to write +the same thing. But it does its job quite well.

+ +

Quick Test

+I have now an applet interface to the decompiler. +Check it out. + +

How to get it

+

You can donwload the files in zip form. +The sources contain only the +java files, the classes +contain only the class files.

+ +

I also have a tar.gz file containing only +the RCS directories. This is the form I maintain the +project, but you probably need unix and a few tools to use them.

+ +

There are also some snapshots that have new +features like inner and anonymous classes.

+ +

Click here to browse the files online. +

+ + + +

How to use it

+ +

I have some simple step by step pages. There are three +possibilities: +

+ +

Known bugs

+ +

There may be situations, where the code doesn't understand complex +expressions. In this many ugly temporary variables are used, but the +code should still be compileable. This does especially happen when +you compile with `-O' flag and javac has inlined some methods.

+ +

Sometimes this program may exit with an Exception or +produce incorrect code. Most time the code can't be compiled, so that +it can be easily spotted. If you have one of these problems (except +those that occur on some of the jode.test files, I would +be very interested in a bug report (including the class +file, if possible).

+ +

Sometimes it generates some GOTO expression and +labels. This can't be compiled, but shouldn't happen any more with +javac or jikes.

+ +

It doesn't handle inner and anonymous classes, yet. You can +decompile them separately, though (use `+$' switch under +jikes), but there is a bug in javac, so that a final variable is twice +initialized. If you encounter this problem just remove the doubled +line by hand.

+ +

New! The latest snapshot can handle +inner and anonymous classes.

+ + +

Why did I wrote it?

+ +

Someday I found guavad, a disassembler for java byte +code (it does similar things like javap -c). I used +it on a class file, and found that it was possible to reconstruct the +original java code. First I did it by hand on some small routines, +but I soon realized that it was a rather stupid task, and that I could +write a perl script +that does the same. At the end of the next day I had a working +decompiler.

+ +

Now while it was working, it was not easy to use. You had to +decompile the code first with a disassembler, cut the method, you +wanted to decompile and then run the perl script on it. So I decided +to get some information of the class files and do this all +automatically. I decided to write it in java now, +because it suited best.

+ +

Just for the records: the java code is now more than 50 times +bigger than the original perl script and is still growing.

+ +

License

+ +

This code is under GNU GPL. That basically means, that you can copy +or modify this code, as long as you put all your modification under +the GPL again. Look +here for the complete license.

+ +
+ +

+http://www.informatik.uni-oldenburg.de/~delwi/jode/jode.html, last +updated on 17-Jun-1999.

+ + + diff --git a/jode/acinclude.m4 b/jode/acinclude.m4 new file mode 100644 index 0000000..a7ef9df --- /dev/null +++ b/jode/acinclude.m4 @@ -0,0 +1,43 @@ +dnl +dnl Add macros +dnl JODE_CHECK_JAVA +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) + for path in $1/lib $1/jre/lib $1/shared; do + for classlib in classes.zip rt.jar; do + AC_CHECK_FILES($path/$classlib, + [ CLASSLIB=$path/$classlib + break 3 + ], [ true ]) + done + done + AC_SUBST(CLASSPATH) + AC_SUBST(CLASSLIB) +]) + +AC_DEFUN(JODE_CHECK_CLASS, +[ + if (IFS=":" + clazz=`echo $1 | sed -e 's/\./\//g' -e 's/\(.*\)/\1.class/'` + jode_found=0 + for path in $2; do + if test -d $path; then + if test -e $path/$clazz; then + exit 0 + fi + elif $UNZIP -v -C $path $clazz &>/dev/null ; then + exit 0 + fi + done; + exit 1) + then + $3 + else + $4 + fi +]) diff --git a/jode/configure.in b/jode/configure.in new file mode 100644 index 0000000..beb8e1c --- /dev/null +++ b/jode/configure.in @@ -0,0 +1,128 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT() + +AM_INIT_AUTOMAKE(jode, 1.0.90) + +dnl Checks for programs. +dnl AC_PROG_CXX +dnl AC_PROG_AWK +dnl AC_PROG_CC +dnl AC_PROG_CPP +dnl AC_PROG_INSTALL +dnl AC_PROG_LN_S +AC_PROG_MAKE_SET +dnl AC_PROG_RANLIB +dnl AC_PATH_PROG(ZIP, zip) +AC_PATH_PROG(UNZIP, unzip) + +dnl Checks for libraries. + +dnl Checks for header files. + +dnl Checks for typedefs, structures, and compiler characteristics. + +dnl Checks for library functions. + +dnl hack to quote Makefile lines +QUOTE="" +AC_SUBST(QUOTE) + +AC_SUBST(SHELL) + +AC_ARG_WITH(java, + [ --with-java specify path to a java-like program ], + [ + if test ${withval} != "" || test ${withval} != "yes" || test ${withval} != "no"; then + # set javac to user input value + JODE_CHECK_JAVA(${withval}) + else + JODE_CHECK_JAVA(/usr/lib/java) + fi + ], + [ + JODE_CHECK_JAVA(/usr/lib/java) + ]) + +dnl jikes can also handle dependancies. +AC_ARG_WITH(jikes, +[ --with-jikes specify location of jikes ], +[ + USER_SPECIFIED_JIKES=true + if test "${withval}" = "yes" || test "${withval}" = ""; then + AC_PATH_PROG(JIKES, jikes, "", $PATH) + else + echo "searching jikes in ${withval}:$PATH" + AC_PATH_PROG(JIKES, jikes, "", ${withval}:$PATH) + fi + if test -n "$JIKES"; then + JAVAC=$JIKES + fi +], +[ + USER_SPECIFIED_JIKES= + AC_PATH_PROG(JIKES, jikes, "", $PATH) +]) +AM_CONDITIONAL(HAVE_JIKES, test x"$JIKES" != x) + +AC_ARG_WITH(javac, + [ --with-javac specify location of javac ], + [ + if test x$USER_SPECIFIED_JIKES == xtrue; then + AC_MSG_ERROR(You must only give one option --with-javac or --with-jikes) + fi + if test ${withval} != "" || test ${withval} != "yes" || test ${withval} != "no"; then + AC_CHECK_FILES(${withval}, + [ JAVAC=${withval} ], + [ AC_MSG_ERROR(${withval} does not exists) ]) + fi +], [ true ]) + +JODE_CHECK_CLASS(java.lang.Object, $CLASSLIB, + [ true ], + [ AC_MSG_ERROR(Please specify location of java class library for jikes) ]) + +AC_MSG_CHECKING(for collection classes) +JODE_CHECK_CLASS(java.util.Set, $CLASSPATH:$CLASSLIB, + [ COLLECTIONS="java.util" ], + [ JODE_CHECK_CLASS(com.sun.java.util.collections.Set, $CLASSPATH:$CLASSLIB, + [ COLLECTIONS="com.sun.java.util.collections" ], + [ AC_MSG_RESULT(no) + AC_MSG_ERROR(You need the Java 1.2 collection classes in your classpath) + ]) + ] ) +AC_MSG_RESULT($COLLECTIONS) +AC_SUBST(COLLECTIONS) + +AC_MSG_CHECKING(for gnu.getopt) +JODE_CHECK_CLASS(gnu.getopt.Getopt, $CLASSPATH:$CLASSLIB, + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + AC_MSG_ERROR(You need gnu getopt for java.) ]) + +AC_MSG_CHECKING(for swing) +JODE_CHECK_CLASS(javax.swing.JFrame, $CLASSPATH:$CLASSLIB, + [ JAVAX_SWING="javax.swing" ], + [ JODE_CHECK_CLASS(com.sun.swing.JFrame, $CLASSPATH:$CLASSLIB, + [ JAVAX_SWING="com.sun.java.swing" ], + [ JAVAX_SWING="no" ]) ] ) +AC_MSG_RESULT($JAVAX_SWING) +AC_SUBST(JAVAX_SWING) +if test x"$JAVAX_SWING" != x; then + SWING_CLASSES="jode/swingui/Main.class" +else + AC_MSG_WARN(Swing is not in classpath ... skipping swingui) + SWING_CLASSES="" +fi +AC_SUBST(SWING_CLASSES) + +AC_SUBST(CLASSPATH) +AC_SUBST(JAVAC) + +AC_OUTPUT(Makefile +jode/Makefile +doc/Makefile +test/Makefile +jode/GlobalOptions.java +jode/swingui/Main.java +jode/swingui/PackagesTreeModel.java) + diff --git a/jode/doc/.cvsignore b/jode/doc/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/jode/doc/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/jode/doc/Makefile.am b/jode/doc/Makefile.am new file mode 100644 index 0000000..e69de29 diff --git a/jode/jode/.cvsignore b/jode/jode/.cvsignore new file mode 100644 index 0000000..9f5ef71 --- /dev/null +++ b/jode/jode/.cvsignore @@ -0,0 +1,4 @@ +Makefile +Makefile.in +.java.deps +jode.jar diff --git a/jode/jode/GlobalOptions.java b/jode/jode/GlobalOptions.java.in similarity index 98% rename from jode/jode/GlobalOptions.java rename to jode/jode/GlobalOptions.java.in index 080692c..0d79e80 100644 --- a/jode/jode/GlobalOptions.java +++ b/jode/jode/GlobalOptions.java.in @@ -22,7 +22,7 @@ import java.io.PrintWriter; import java.util.StringTokenizer; public class GlobalOptions { - public final static String version = "1.0 snapshot 19990629"; + public final static String version = "@VERSION@"; public final static String email = "jochen@gnu.org"; public final static String copyright = "Jode (c) 1998,1999 Jochen Hoenicke <"+email+">"; diff --git a/jode/jode/Makefile.am b/jode/jode/Makefile.am new file mode 100644 index 0000000..289f87c --- /dev/null +++ b/jode/jode/Makefile.am @@ -0,0 +1,231 @@ +## 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 + +JAR = @JAR@ +JAVAC = @JAVAC@ +JIKES = @JIKES@ +CLASSPATH = @CLASSPATH@ +CLASSLIB = @CLASSLIB@ +BUILD_CLASSPATH = $(top_srcdir):$(top_builddir):.:$(CLASSPATH) +VPATH=$(srcdir):$(top_srcdir):$(top_builddir) + +MY_CLASSES = jode/Decompiler.class jode/JodeApplet.class jode/JodeWindow.class jode/obfuscator/Main.class @SWING_CLASSES@ + +pkgdata_DATA = jode.jar + +if HAVE_JIKES + +@QUOTE@-include .java.deps + +%.class: %.java + $(JIKES) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) +M=.java.deps -d . $< + +else + +%.class: %.java + $(JAVAC) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) -depend -d . $< + +endif + +clean-local: + @rm -rf jode + @rm -f jode.jar .java.deps + +jode.jar: $(MY_CLASSES) + CLASSPATH= $(JAR) -cf jode.jar jode diff --git a/jode/jode/swingui/Main.java b/jode/jode/swingui/Main.java.in similarity index 97% rename from jode/jode/swingui/Main.java rename to jode/jode/swingui/Main.java.in index ba871e1..50fbeca 100644 --- a/jode/jode/swingui/Main.java +++ b/jode/jode/swingui/Main.java.in @@ -22,15 +22,11 @@ import jode.GlobalOptions; import jode.decompiler.*; import jode.bytecode.ClassInfo; import jode.bytecode.SearchPath; -///#ifndef OLDSWING -import javax.swing.*; -import javax.swing.event.*; -import javax.swing.tree.*; -///#else -///import com.sun.java.swing.*; -///import com.sun.java.swing.event.*; -///import com.sun.java.swing.tree.*; -///#endif + +import @JAVAX_SWING@.*; +import @JAVAX_SWING@.event.*; +import @JAVAX_SWING@.tree.*; + import java.awt.*; import java.awt.event.*; import java.io.*; diff --git a/jode/jode/swingui/PackagesTreeModel.java b/jode/jode/swingui/PackagesTreeModel.java.in similarity index 91% rename from jode/jode/swingui/PackagesTreeModel.java rename to jode/jode/swingui/PackagesTreeModel.java.in index 6d9c0a2..f27467f 100644 --- a/jode/jode/swingui/PackagesTreeModel.java +++ b/jode/jode/swingui/PackagesTreeModel.java.in @@ -20,19 +20,13 @@ package jode.swingui; import jode.Decompiler; import jode.bytecode.ClassInfo; -///#ifndef OLDSWING -import javax.swing.tree.TreeModel; -import javax.swing.tree.TreePath; -import javax.swing.event.TreeModelListener; -import javax.swing.event.TreeModelEvent; -///#else -///import com.sun.java.swing.tree.TreeModel; -///import com.sun.java.swing.tree.TreePath; -///import com.sun.java.swing.event.TreeModelListener; -///import com.sun.java.swing.event.TreeModelEvent; -///#endif -///#ifdef JDK12 +import @JAVAX_SWING@.tree.TreeModel; +import @JAVAX_SWING@.tree.TreePath; +import @JAVAX_SWING@.event.TreeModelListener; +import @JAVAX_SWING@.event.TreeModelEvent; + +///#ifndef JDK12 ///import java.util.Arrays; ///import java.util.TreeSet; ///import java.util.HashSet; @@ -49,6 +43,7 @@ import jode.util.HashMap; import jode.util.Map; ///#endif + import java.util.Enumeration; import java.util.NoSuchElementException; diff --git a/jode/test/.cvsignore b/jode/test/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/jode/test/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/jode/test/Makefile.am b/jode/test/Makefile.am new file mode 100644 index 0000000..e69de29