This commit was manufactured by cvs2svn to create tag 'mergedstable'.

git-svn-id: https://svn.code.sf.net/p/jode/code/tags/mergedstable@1060 379699f6-c40d-0410-875b-85095c16579e
mergedstable
(no author) 26 years ago
parent 4375465cdc
commit 8d1b0b36d2
  1. 9
      jode/.cvsignore
  2. 1
      jode/AUTHORS
  3. 0
      jode/ChangeLog
  4. 33
      jode/INSTALL
  5. 5
      jode/Makefile.am
  6. 10
      jode/NEWS
  7. 106
      jode/README
  8. 44
      jode/acinclude.m4
  9. 2
      jode/bin/.cvsignore
  10. 4
      jode/bin/Makefile.am
  11. 14
      jode/bin/jode.in
  12. 139
      jode/configure.in
  13. 2
      jode/doc/.cvsignore
  14. 5
      jode/doc/Makefile.am
  15. 4
      jode/doc/jode-applet.html
  16. 1
      jode/doc/jode-obfuscator.html
  17. 3
      jode/doc/jode-unix.html
  18. 2
      jode/doc/jode-useapplet.html
  19. 2
      jode/doc/jode-win.html
  20. 5
      jode/doc/jode.html
  21. 4
      jode/jode/.cvsignore
  22. 2
      jode/jode/Decompiler.java
  23. 41
      jode/jode/GlobalOptions.java.in
  24. 54
      jode/jode/Makefile.am
  25. 2
      jode/jode/bytecode/.cvsignore
  26. 25
      jode/jode/bytecode/ClassInfo.java
  27. 1
      jode/jode/bytecode/FieldInfo.java
  28. 46
      jode/jode/bytecode/Makefile.am
  29. 2
      jode/jode/bytecode/MethodInfo.java
  30. 2
      jode/jode/decompiler/.cvsignore
  31. 46
      jode/jode/decompiler/Makefile.am
  32. 2
      jode/jode/expr/.cvsignore
  33. 73
      jode/jode/expr/Makefile.am
  34. 2
      jode/jode/flow/.cvsignore
  35. 2
      jode/jode/flow/FlowBlock.java
  36. 70
      jode/jode/flow/Makefile.am
  37. 120
      jode/jode/flow/TransformExceptionHandlers.java
  38. 2
      jode/jode/jvm/.cvsignore
  39. 39
      jode/jode/jvm/Makefile.am
  40. 2
      jode/jode/obfuscator/.cvsignore
  41. 6
      jode/jode/obfuscator/ClassBundle.java
  42. 164
      jode/jode/obfuscator/ClassIdentifier.java
  43. 16
      jode/jode/obfuscator/ConstantAnalyzer.java
  44. 2
      jode/jode/obfuscator/FieldIdentifier.java
  45. 5
      jode/jode/obfuscator/Identifier.java
  46. 2
      jode/jode/obfuscator/Main.java
  47. 53
      jode/jode/obfuscator/Makefile.am
  48. 19
      jode/jode/obfuscator/ModifierMatcher.java
  49. 106
      jode/jode/obfuscator/SimpleAnalyzer.java
  50. 2
      jode/jode/swingui/.cvsignore
  51. 16
      jode/jode/swingui/Main.java.in
  52. 32
      jode/jode/swingui/Makefile.am
  53. 19
      jode/jode/swingui/PackagesTreeModel.java.in
  54. 2
      jode/jode/type/.cvsignore
  55. 38
      jode/jode/type/Makefile.am
  56. 2
      jode/jode/util/.cvsignore
  57. 60
      jode/jode/util/Makefile.am
  58. 2
      jode/test/.cvsignore
  59. 0
      jode/test/Makefile.am

@ -0,0 +1,9 @@
Makefile
Makefile.in
configure
config.log
config.cache
config.status
stamp-h
libtool
aclocal.m4

@ -0,0 +1 @@
Jochen Hoenicke <Jochen.Hoenicke@Informatik.Uni-Oldenburg.DE>

@ -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

@ -0,0 +1,5 @@
## Input file for automake to generate the Makefile.in used by configure
SUBDIRS = jode bin doc test
EXTRA_DIST = TODO

@ -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

@ -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 <code>-g</code>) and there are often more ways to write
the same thing. But it does its job quite well.</P>
<h2>Quick Test</h2>
I have now an applet interface to the decompiler.
<a href="jode-applet.html">Check it out</a>.
<h2>How to get it</h2>
<P>You can donwload the files in zip form.
The <a href="jode_src.zip">sources</a> contain only the
<code>java</code> files, the <a href="jode_cls.zip">classes</a>
contain only the <code>class</code> files. </p>
<p>I also have a <a href="jode.tar.gz">tar.gz file</a> containing only
the <code>RCS</code> directories. This is the form I maintain the
project, but you probably need unix and a few tools to use them.</p>
<p>There are also some <a href="snapshot/">snapshots</a> that have new
features like inner and anonymous classes. </p>
<p><a href=".">Click here</a> to browse the files online.
</p>
<h2>How to use it</h2>
<p>I have some simple step by step pages. There are three
possibilities:
<ul>
<li> <a href="jode-useapplet.html"> Using the applet version</a>.
This can make problem due to java's security policy, but is the
simplest way and works on most platforms.
</li>
<li> If you use Windows, you should look on <a
href="jode-win.html">this page</a>.</li>
<li> Unix users should look on <a href="jode-unix.html">this page</a>.
</ul>
<h2>Known bugs</h2>
<p>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. </p>
<p>Sometimes this program may exit with an <code>Exception</code> 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 <code>jode.test</code> files, I would
be very interested in a bug report (including the <code>class</code>
file, if possible).</p>
<p>Sometimes it generates some <code>GOTO</code> expression and
labels. This can't be compiled, but shouldn't happen any more with
javac or jikes.</p>
<p>It doesn't handle inner and anonymous classes, yet. You can
decompile them separately, though (use `<code>+$</code>' 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. </p>
<p><b>New!</b> The latest <a href="snapshot">snapshot</a> can handle
inner and anonymous classes.</p>
<h2>Why did I wrote it?</h2>
<p>Someday I found <code>guavad</code>, a disassembler for java byte
code (it does similar things like <code>javap&nbsp;-c</code>). 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 <a href="../perl/dasm_to_java.perl"><code>perl</code> script</a>
that does the same. At the end of the next day I had a working
decompiler.</p>
<p>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 <code>java</code> now,
because it suited best.</p>
<p>Just for the records: the java code is now more than 50 times
bigger than the original perl script and is still growing.</p>
<h2>License</h2>
<p>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. <A HREF="http://www.gnu.org/copyleft/gpl.html"> Look
here for the complete license</a>.</p>
<hr>
<p><A HREF="mailto:Jochen.Hoenicke@Informatik.Uni-Oldenburg.DE">
http://www.informatik.uni-oldenburg.de/~delwi/jode/jode.html</A>, last
updated on <em>17-Jun-1999</em>.</p>
</body>
</html>

@ -0,0 +1,44 @@
dnl
dnl Add macros
dnl JODE_CHECK_JAVA
dnl
dnl JODE_CHECK_JAVA(path)
AC_DEFUN(JODE_CHECK_JAVA,
[
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,
[ 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
])

@ -0,0 +1,2 @@
Makefile
Makefile.in

@ -0,0 +1,4 @@
## Input file for automake to generate the Makefile.in used by configure
bin_SCRIPTS = jode

@ -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 $*

@ -0,0 +1,139 @@
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
SWINGUI="swingui"
else
AC_MSG_WARN(Swing is not in classpath ... skipping swingui)
SWINGUI=""
fi
AC_SUBST(SWINGUI)
AC_SUBST(CLASSPATH)
AC_SUBST(JAVAC)
AC_OUTPUT(Makefile
jode/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
bin/Makefile
bin/jode
doc/Makefile
test/Makefile)

@ -0,0 +1,2 @@
Makefile
Makefile.in

@ -0,0 +1,5 @@
## Input file for automake to generate the Makefile.in used by configure
EXTRA_DIST = \
jode.html jode-applet.html jode-obfuscator.html jode-unix.html \
jode-useapplet.html jode-win.html

@ -5,11 +5,11 @@
<body>
<a href="../index.html">Home</a> <a href="jode.html">Up</a>
<a href="jode.html">Up</a>
<h1>Test Applet</h1>
<applet code="jode/JodeApplet.class" archive="jode_cls.zip" width=640 height=400>
<applet code="jode/JodeApplet.class" archive="jode-applet.jar" width=640 height=400>
<param name=classpath
value="http://www.informatik.uni-oldenburg.de/~delwi/jode/jode_cls.zip">
<param name=class value="jode.JodeApplet">

@ -4,6 +4,7 @@
<title>Using the obfuscator</title>
</head>
<body>
<a href="jode.html">Up</a>
The obfuscator currently takes a lot of options (I plan to use an
extra file containing the options). You should therefore create a

@ -4,7 +4,8 @@
<title>Using the decompiler under Unix</title>
</head>
<body>
<a href="../index.html">Home</a> <a href="jode.html">Up</a> <br>
<a href="jode.html">Up</a>
<h1>Step by Step</h1>

@ -4,7 +4,7 @@
<title>Using the decompiler as applet (locally)</title>
</head>
<body>
<a href="../index.html">Home</a> <a href="jode.html">Up</a> <br>
<a href="jode.html">Up</a>
<h1>Step by Step</h1>

@ -4,7 +4,7 @@
<title>Using the decompiler under Windows</title>
</head>
<body>
<a href="../index.html">Home</a> <a href="jode.html">Up</a> <br>
<a href="jode.html">Up</a>
<h1>Step by Step</h1>

@ -12,7 +12,9 @@ java-decompiler, reverse engineering, free, GPL">
</head>
<body>
<a href="../index.html">Home</a>
<a href="http://www.informatik.uni-oldenbur.de/~delwi/jode/jode.html">
An uptodate version of this page is located here.</a><p>
<h2>What is it?</h2>
<P>This is a decompiler for java I have written in my spare time. It
@ -43,7 +45,6 @@ features like inner and anonymous classes. </p>
</p>
<h2>How to use it</h2>
<p>I have some simple step by step pages. There are three

@ -0,0 +1,4 @@
Makefile
Makefile.in
.java.deps
jode.jar

@ -155,6 +155,8 @@ public class Decompiler {
} else if (params[i].equals("--import")) {
importPackageLimit = Integer.parseInt(params[++i]);
importClassLimit = Integer.parseInt(params[++i]);
} else if (params[i].equals("--classpath")) {
classPath = params[++i];
} else if (params[i].equals("--cp")) {
classPath = params[++i];
} else if (params[i].equals("--")) {

@ -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+">";
@ -54,34 +54,40 @@ public class GlobalOptions {
public static void usageDebugging() {
err.println("Debugging option: --debug=flag1,flag2,...");
err.println("possible flags:");
err.println("\tbytecode " +
err.println(" bytecode " +
"show bytecode, as it is read from class file.");
err.println("\tverifier " +
err.println(" verifier " +
"show result of bytecode verification.");
err.println("\ttypes " +
err.println(" types " +
"show type intersections");
err.println("\tflow " +
err.println(" flow " +
"show flow block merging.");
err.println("\tanalyze " +
"show analyzation order of flow blocks.");
err.println("\tinout " +
"show T1/T2 in/out set analysis.");
err.println("\tlvt " +
err.println(" analyze " +
"show T1/T2 analyzation of flow blocks.");
err.println(" inout " +
"show in/out set analysis.");
err.println(" lvt " +
"dump LocalVariableTable.");
err.println("\tcheck " +
err.println(" check " +
"do time consuming sanity checks.");
err.println("\tlocals " +
err.println(" locals " +
"dump local merging information.");
err.println("\tconstructors " +
err.println(" constructors " +
"dump constructor simplification.");
err.println("\tinterpreter " +
err.println(" interpreter " +
"debug execution of interpreter.");
System.exit(0);
}
public static void setDebugging(String debuggingString) {
if (debuggingString.length() == 0 || debuggingString.equals("help"))
/**
* Parse the argument given to the debugging flag.
* @return true, if the argument parsed without problems.
*/
public static boolean setDebugging(String debuggingString) {
if (debuggingString.length() == 0 || debuggingString.equals("help")) {
usageDebugging();
return false;
}
StringTokenizer st = new StringTokenizer(debuggingString, ",");
next_token:
@ -94,7 +100,8 @@ public class GlobalOptions {
}
}
err.println("Illegal debugging flag: "+token);
usageDebugging();
return false;
}
return true;
}
}

@ -0,0 +1,54 @@
## Input file for automake to generate the Makefile.in used by configure
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):$(CLASSLIB)
VPATH=$(srcdir):$(top_srcdir):$(top_builddir)
MY_JAVA_FILES = \
AssertError.java \
Decompiler.java \
GlobalOptions.java \
JodeApplet.java \
JodeWindow.java
noinst_DATA = $(MY_JAVA_FILES:.java=.class)
EXTRA_DIST = $(MY_JAVA_FILES)
JARFILE = jode-@VERSION@.jar
data_DATA = $(JARFILE)
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
@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.<init>.*' \
--preserve 'jode.JodeWindow.main.*' \
--preserve 'jode.obfuscator.Main.main.*' \
--preserve 'jode.swingui.Main.main.*' jode

@ -0,0 +1,2 @@
Makefile
Makefile.in

@ -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];

@ -159,6 +159,7 @@ public class FieldInfo extends BinaryInfo {
}
public Object getConstant() {
clazzInfo.loadInfo(ALL_ATTRIBUTES);
return constant;
}

@ -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

@ -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;
}

@ -0,0 +1,2 @@
Makefile
Makefile.in

@ -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

@ -0,0 +1,2 @@
Makefile
Makefile.in

@ -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

@ -0,0 +1,2 @@
Makefile
Makefile.in

@ -1522,6 +1522,8 @@ public class FlowBlock {
public void simplify() {
block.simplify();
if (nextByAddr != null)
nextByAddr.simplify();
}
/**

@ -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

@ -77,6 +77,12 @@ public class TransformExceptionHandlers {
/* ...Last sort by typecode signature. Shouldn't happen to often.
*/
if (type == second.type)
return 0;
if (type == null)
return -1;
if (second.type == null)
return 1;
return type.getTypeSignature()
.compareTo(second.type.getTypeSignature());
}
@ -364,13 +370,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.successors.values().iterator();
dest_loop:
while (succs.hasNext()) {
boolean isFirstJump = true;
for (Jump jumps = (Jump) succs.next();
jumps != null; jumps = jumps.next) {
jumps != null; jumps = jumps.next, isFirstJump = false) {
StructuredBlock prev = jumps.prev;
@ -431,28 +440,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");
@ -517,11 +557,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);
@ -677,12 +719,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);
@ -826,26 +869,27 @@ public class TransformExceptionHandlers {
FlowBlock tryFlow = exc.start;
tryFlow.checkConsistent();
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_ANALYZE) != 0)
GlobalOptions.err.println
("analyzeTry("
+ exc.start.addr + ", " + exc.endAddr+")");
while (tryFlow.analyze(tryFlow.addr, exc.endAddr));
if (last == null
if (last == null || exc.type == null
|| last.start.addr != exc.start.addr
|| 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.addr + ", " + exc.endAddr+")");
while (tryFlow.analyze(tryFlow.addr, 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;
if (!isMultiUsed) {
if (!isMultiUsed && next != null) {
for (Iterator j = handlers.tailSet(next).iterator();
j.hasNext();) {
Handler h = (Handler) j.next();
@ -865,8 +909,8 @@ public class TransformExceptionHandlers {
FlowBlock newFlow = new FlowBlock(catchFlow.method,
catchFlow.addr, 0);
newFlow.setBlock(jump);
catchFlow.prevByAddr.setNextByAddr(newFlow);
newFlow.setNextByAddr(catchFlow);
catchFlow.prevByAddr.nextByAddr = newFlow;
newFlow.nextByAddr = catchFlow;
catchFlow = newFlow;
} else {
if ((GlobalOptions.debuggingFlags

@ -0,0 +1,2 @@
Makefile
Makefile.in

@ -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

@ -0,0 +1,2 @@
Makefile
Makefile.in

@ -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() {

@ -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("<init>"))) {
// 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("<init>")) {
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);

@ -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)

@ -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);
}

@ -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(); )

@ -184,7 +184,7 @@ public class Main {
}
public static CodeAnalyzer createCodeAnalyzer() {
return new ConstantAnalyzer() /*XXX*/;
return new SimpleAnalyzer() /*XXX*/;
}
static CodeTransformer[] codeTransformers = {

@ -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

@ -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<andMasks.length; j++) {
for (int j=0; j < andMasks.length; j++) {
if (j != i
&& implies(and | andMasks[j], xor | xorMasks[j],
andMasks[i], xorMasks[i]))
@ -120,12 +120,21 @@ public class ModifierMatcher implements IdentifierMatcher, Cloneable {
int[] ands = new int[newCount];
int[] xors = new int[newCount];
int index = 0;
next_i:
for (int i=0; i < newCount; i++) {
int bothAnd = andMasks[i] & and;
if ((xorMasks[i] & bothAnd) == (and & bothAnd)) {
ands[index++] = andMasks[i] | and;
xors[index++] = xorMasks[i] | xor;
if (implies(and, xor, andMasks[i], xorMasks[i]))
continue next_i;
for (int j=0; j < andMasks.length; j++) {
if (j != i
&& implies(and | andMasks[j], xor | xorMasks[j],
andMasks[i], xorMasks[i]))
continue next_i;
}
ands[index] = andMasks[i] | and;
xors[index] = xorMasks[i] | xor;
index++;
}
return new ModifierMatcher(ands, xors);
}

@ -18,10 +18,69 @@
*/
package jode.obfuscator;
import jode.bytecode.*;
import jode.bytecode.Handler;
import jode.bytecode.Opcodes;
import jode.bytecode.ClassInfo;
import jode.bytecode.BytecodeInfo;
import jode.bytecode.Instruction;
import jode.bytecode.Reference;
import jode.GlobalOptions;
import jode.type.Type;
public class SimpleAnalyzer implements CodeAnalyzer, Opcodes {
public Identifier canonizeReference(Instruction instr) {
Reference ref = (Reference) instr.objData;
Identifier ident = Main.getClassBundle().getIdentifier(ref);
String clName = ref.getClazz();
String realClazzName;
if (ident != null) {
ClassIdentifier clazz = (ClassIdentifier)ident.getParent();
realClazzName = "L" + (clazz.getFullName()
.replace('.', '/')) + ";";
} 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('/','.'));
}
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: "
+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;
}

@ -0,0 +1,2 @@
Makefile
Makefile.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.*;
@ -270,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<params.length; i++) {
if (params[i].equals("--cp"))
if (params[i].equals("--classpath"))
cp = params[++i];
else
return;

@ -0,0 +1,32 @@
## 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 = \
Main.java \
PackagesTreeModel.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

@ -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;

@ -0,0 +1,2 @@
Makefile
Makefile.in

@ -0,0 +1,38 @@
## 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 = \
ArrayType.java \
ClassInterfacesType.java \
IntegerType.java \
MethodType.java \
NullType.java \
RangeType.java \
ReferenceType.java \
Type.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

@ -0,0 +1,2 @@
Makefile
Makefile.in

@ -0,0 +1,60 @@
## 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 = \
SimpleMap.java \
SimpleSet.java \
ArrayEnum.java \
AbstractCollection.java \
AbstractList.java \
AbstractMap.java \
AbstractSequentialList.java \
AbstractSet.java \
ArrayList.java \
Arrays.java \
BasicMapEntry.java \
Bucket.java \
Collection.java \
Collections.java \
Comparable.java \
Comparator.java \
ConcurrentModificationException.java \
HashMap.java \
HashSet.java \
Iterator.java \
LinkedList.java \
List.java \
ListIterator.java \
Map.java \
Set.java \
SortedMap.java \
SortedSet.java \
TreeMap.java \
TreeSet.java \
UnsupportedOperationException.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

@ -0,0 +1,2 @@
Makefile
Makefile.in
Loading…
Cancel
Save