merged changes from stable tree

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1061 379699f6-c40d-0410-875b-85095c16579e
branch_1_1
jochen 26 years ago
parent 0a8b2be671
commit 75df7ec7f2
  1. 2
      jode/Makefile.am
  2. 5
      jode/acinclude.m4
  3. 2
      jode/bin/.cvsignore
  4. 4
      jode/bin/Makefile.am
  5. 14
      jode/bin/jode.in
  6. 23
      jode/configure.in
  7. 237
      jode/jode/Makefile.am
  8. 2
      jode/jode/bytecode/.cvsignore
  9. 25
      jode/jode/bytecode/ClassInfo.java
  10. 1
      jode/jode/bytecode/FieldInfo.java
  11. 46
      jode/jode/bytecode/Makefile.am
  12. 2
      jode/jode/bytecode/MethodInfo.java
  13. 2
      jode/jode/decompiler/.cvsignore
  14. 46
      jode/jode/decompiler/Makefile.am
  15. 2
      jode/jode/expr/.cvsignore
  16. 73
      jode/jode/expr/Makefile.am
  17. 2
      jode/jode/flow/.cvsignore
  18. 70
      jode/jode/flow/Makefile.am
  19. 112
      jode/jode/flow/TransformExceptionHandlers.java
  20. 2
      jode/jode/jvm/.cvsignore
  21. 39
      jode/jode/jvm/Makefile.am
  22. 2
      jode/jode/obfuscator/.cvsignore
  23. 6
      jode/jode/obfuscator/ClassBundle.java
  24. 164
      jode/jode/obfuscator/ClassIdentifier.java
  25. 16
      jode/jode/obfuscator/ConstantAnalyzer.java
  26. 2
      jode/jode/obfuscator/FieldIdentifier.java
  27. 5
      jode/jode/obfuscator/Identifier.java
  28. 2
      jode/jode/obfuscator/Main.java
  29. 53
      jode/jode/obfuscator/Makefile.am
  30. 19
      jode/jode/obfuscator/ModifierMatcher.java
  31. 106
      jode/jode/obfuscator/SimpleAnalyzer.java
  32. 2
      jode/jode/swingui/.cvsignore
  33. 2
      jode/jode/swingui/Main.java.in
  34. 32
      jode/jode/swingui/Makefile.am
  35. 2
      jode/jode/type/.cvsignore
  36. 38
      jode/jode/type/Makefile.am
  37. 2
      jode/jode/util/.cvsignore
  38. 60
      jode/jode/util/Makefile.am

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

@ -6,8 +6,9 @@ dnl
dnl JODE_CHECK_JAVA(path) dnl JODE_CHECK_JAVA(path)
AC_DEFUN(JODE_CHECK_JAVA, AC_DEFUN(JODE_CHECK_JAVA,
[ [
AC_PATH_PROG(JAVAC, javac, "", $PATH:$1/bin) AC_PATH_PROG(JAVA, java, "", $1/bin:$1/jre/bin:$PATH)
AC_PATH_PROG(JAR, jar, "", $PATH:$1/bin) 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 path in $1/lib $1/jre/lib $1/shared; do
for classlib in classes.zip rt.jar; do for classlib in classes.zip rt.jar; do
AC_CHECK_FILES($path/$classlib, AC_CHECK_FILES($path/$classlib,

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

@ -108,21 +108,32 @@ JODE_CHECK_CLASS(javax.swing.JFrame, $CLASSPATH:$CLASSLIB,
AC_MSG_RESULT($JAVAX_SWING) AC_MSG_RESULT($JAVAX_SWING)
AC_SUBST(JAVAX_SWING) AC_SUBST(JAVAX_SWING)
if test x"$JAVAX_SWING" != x; then if test x"$JAVAX_SWING" != x; then
SWING_CLASSES="jode/swingui/Main.class" SWINGUI="swingui"
else else
AC_MSG_WARN(Swing is not in classpath ... skipping swingui) AC_MSG_WARN(Swing is not in classpath ... skipping swingui)
SWING_CLASSES="" SWINGUI=""
fi fi
AC_SUBST(SWING_CLASSES) AC_SUBST(SWINGUI)
AC_SUBST(CLASSPATH) AC_SUBST(CLASSPATH)
AC_SUBST(JAVAC) AC_SUBST(JAVAC)
AC_OUTPUT(Makefile AC_OUTPUT(Makefile
jode/Makefile jode/Makefile
doc/Makefile jode/bytecode/Makefile
test/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/GlobalOptions.java
jode/swingui/Main.java jode/swingui/Main.java
jode/swingui/PackagesTreeModel.java) jode/swingui/PackagesTreeModel.java
bin/Makefile
bin/jode
doc/Makefile
test/Makefile)

@ -1,231 +1,54 @@
## Input file for automake to generate the Makefile.in used by configure ## Input file for automake to generate the Makefile.in used by configure
EXTRA_DIST = \ SUBDIRS = bytecode type util jvm expr flow decompiler obfuscator @SWINGUI@
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@ JAR = @JAR@
JAVAC = @JAVAC@ JAVAC = @JAVAC@
JIKES = @JIKES@ JIKES = @JIKES@
CLASSPATH = @CLASSPATH@ CLASSPATH = @CLASSPATH@
CLASSLIB = @CLASSLIB@ CLASSLIB = @CLASSLIB@
BUILD_CLASSPATH = $(top_srcdir):$(top_builddir):.:$(CLASSPATH) BUILD_CLASSPATH = $(top_srcdir):$(top_builddir):.:$(CLASSPATH):$(CLASSLIB)
VPATH=$(srcdir):$(top_srcdir):$(top_builddir) 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 if HAVE_JIKES
@QUOTE@-include .java.deps @QUOTE@-include $(top_builddir)/jode/.java.deps
%.class: %.java %.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 else
%.class: %.java %.class: %.java
$(JAVAC) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) -depend -d . $< $(JAVAC) -classpath $(BUILD_CLASSPATH):$(CLASSLIB) -depend -d $(top_builddir) $<
endif endif
clean-local: clean-local:
@rm -rf jode @rm -f *.class
@rm -f jode.jar .java.deps @rm -f $(JARFILE) .java.deps
jode.jar: $(MY_CLASSES) $(JARFILE): $(noinst_DATA)
CLASSPATH= $(JAR) -cf jode.jar jode 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 { 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 */ /* header */
if (input.readInt() != 0xcafebabe) if (input.readInt() != 0xcafebabe)
throw new ClassFormatException("Wrong magic"); throw new ClassFormatException("Wrong magic");
@ -261,11 +266,13 @@ public class ClassInfo extends BinaryInfo {
} }
/* fields */ /* fields */
if ((howMuch & FIELDS) != 0) { if ((howMuch & (FIELDS | ALL_ATTRIBUTES)) != 0) {
int count = input.readUnsignedShort(); int count = input.readUnsignedShort();
fields = new FieldInfo[count]; if ((howMuch & FIELDS) != 0)
fields = new FieldInfo[count];
for (int i=0; i< count; i++) { 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); fields[i].read(cpool, input, howMuch);
} }
} else { } else {
@ -278,11 +285,13 @@ public class ClassInfo extends BinaryInfo {
} }
/* methods */ /* methods */
if ((howMuch & METHODS) != 0) { if ((howMuch & (METHODS | ALL_ATTRIBUTES)) != 0) {
int count = input.readUnsignedShort(); int count = input.readUnsignedShort();
methods = new MethodInfo[count]; if ((howMuch & METHODS) != 0)
methods = new MethodInfo[count];
for (int i=0; i< count; i++) { 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); methods[i].read(cpool, input, howMuch);
} }
} else { } else {
@ -296,6 +305,7 @@ public class ClassInfo extends BinaryInfo {
/* attributes */ /* attributes */
readAttributes(cpool, input, howMuch); readAttributes(cpool, input, howMuch);
status |= howMuch;
} }
public void reserveSmallConstants(GrowableConstantPool gcp) { public void reserveSmallConstants(GrowableConstantPool gcp) {
@ -546,7 +556,6 @@ public class ClassInfo extends BinaryInfo {
new DataInputStream(classpath.getFile(name.replace('.', '/') new DataInputStream(classpath.getFile(name.replace('.', '/')
+ ".class")); + ".class"));
read(input, howMuch); read(input, howMuch);
status |= howMuch;
} catch (IOException ex) { } catch (IOException ex) {
String message = ex.getMessage(); String message = ex.getMessage();
@ -645,7 +654,7 @@ public class ClassInfo extends BinaryInfo {
public FieldInfo findField(String name, String typeSig) { public FieldInfo findField(String name, String typeSig) {
if ((status & FIELDS) == 0) if ((status & FIELDS) == 0)
loadInfo(FIELDS); loadInfo(FIELDS);
for (int i=0; i< methods.length; i++) for (int i=0; i< fields.length; i++)
if (fields[i].getName().equals(name) if (fields[i].getName().equals(name)
&& fields[i].getType().equals(typeSig)) && fields[i].getType().equals(typeSig))
return fields[i]; return fields[i];

@ -159,6 +159,7 @@ public class FieldInfo extends BinaryInfo {
} }
public Object getConstant() { public Object getConstant() {
clazzInfo.loadInfo(ALL_ATTRIBUTES);
return constant; 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) { public void setBytecode(BytecodeInfo newBytecode) {
clazzInfo.loadInfo(ALL_ATTRIBUTES);
bytecode = newBytecode; bytecode = newBytecode;
} }
public void setExceptions(String[] newExceptions) { public void setExceptions(String[] newExceptions) {
clazzInfo.loadInfo(ALL_ATTRIBUTES);
exceptions = newExceptions; 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

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

@ -323,13 +323,16 @@ public class TransformExceptionHandlers {
} }
public void checkAndRemoveMonitorExit(FlowBlock tryFlow, LocalInfo local, public void checkAndRemoveMonitorExit(FlowBlock tryFlow, LocalInfo local,
int startOutExit, int endOutExit,
int startMonExit, int endMonExit) { int startMonExit, int endMonExit) {
FlowBlock subRoutine = null; FlowBlock subRoutine = null;
FlowBlock exitBlock = null;
Iterator succs = tryFlow.getSuccessors().iterator(); Iterator succs = tryFlow.getSuccessors().iterator();
dest_loop: dest_loop:
while (succs.hasNext()) { while (succs.hasNext()) {
boolean isFirstJump = true;
for (Jump jumps = tryFlow.getJumps((FlowBlock) succs.next()); for (Jump jumps = tryFlow.getJumps((FlowBlock) succs.next());
jumps != null; jumps = jumps.next) { jumps != null; jumps = jumps.next, isFirstJump = false) {
StructuredBlock prev = jumps.prev; StructuredBlock prev = jumps.prev;
@ -390,28 +393,59 @@ public class TransformExceptionHandlers {
continue; continue;
} }
/* The block is a jsr that is not preceeded by another jsr. if (isFirstJump) {
* This must be the monitorexit subroutine. /* This is the first jump to that destination.
*/ * Check if the destination does the monitorExit
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. /* The block is a jsr that is not preceeded by
* Complain! * 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 DescriptionBlock msg
= new DescriptionBlock("ERROR: NO MONITOREXIT"); = new DescriptionBlock("ERROR: NO MONITOREXIT");
@ -476,11 +510,13 @@ public class TransformExceptionHandlers {
LocalInfo local = LocalInfo local =
((LocalLoadOperator)monexit.getSubExpressions()[0]) ((LocalLoadOperator)monexit.getSubExpressions()[0])
.getLocalInfo(); .getLocalInfo();
tryFlow.mergeAddr(catchFlow);
checkAndRemoveMonitorExit checkAndRemoveMonitorExit
(tryFlow, local, catchFlow.getNextAddr(), endHandler); (tryFlow, local,
tryFlow.getNextAddr(), catchFlow.getAddr(),
catchFlow.getNextAddr(), endHandler);
tryFlow.mergeAddr(catchFlow);
SynchronizedBlock syncBlock = new SynchronizedBlock(local); SynchronizedBlock syncBlock = new SynchronizedBlock(local);
TryBlock tryBlock = (TryBlock) tryFlow.block; TryBlock tryBlock = (TryBlock) tryFlow.block;
syncBlock.replace(tryBlock); syncBlock.replace(tryBlock);
@ -636,12 +672,13 @@ public class TransformExceptionHandlers {
TryBlock tryBlock = (TryBlock)tryFlow.block; TryBlock tryBlock = (TryBlock)tryFlow.block;
if (tryBlock.getSubBlocks()[0] instanceof TryBlock) { if (tryBlock.getSubBlocks()[0] instanceof TryBlock) {
/* remove the nested tryBlock */ /* remove the surrounding tryBlock */
TryBlock innerTry = (TryBlock)tryBlock.getSubBlocks()[0]; TryBlock innerTry = (TryBlock)tryBlock.getSubBlocks()[0];
innerTry.gen = tryBlock.gen; innerTry.gen = tryBlock.gen;
innerTry.replace(tryBlock); innerTry.replace(tryBlock);
tryBlock = innerTry; tryBlock = innerTry;
tryFlow.lastModified = innerTry; tryFlow.lastModified = tryBlock;
tryFlow.block = tryBlock;
} }
FinallyBlock newBlock = new FinallyBlock(); FinallyBlock newBlock = new FinallyBlock();
newBlock.setCatchBlock(finallyBlock); newBlock.setCatchBlock(finallyBlock);
@ -784,22 +821,23 @@ public class TransformExceptionHandlers {
FlowBlock tryFlow = exc.start; FlowBlock tryFlow = exc.start;
tryFlow.checkConsistent(); 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.start.getAddr() != exc.start.getAddr()
|| last.endAddr != exc.endAddr) { || last.endAddr != exc.endAddr) {
/* The last handler does catch another range. /* The last handler does catch another range.
* Create a new try block. * 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); TryBlock tryBlock = new TryBlock(tryFlow);
} else if (! (tryFlow.block instanceof TryBlock)) } else if (!(tryFlow.block instanceof TryBlock))
throw new AssertError("no TryBlock"); throw new AssertError("no TryBlock");
FlowBlock catchFlow = exc.handler; FlowBlock catchFlow = exc.handler;
boolean isMultiUsed = catchFlow.predecessors.size() != 0; boolean isMultiUsed = catchFlow.predecessors.size() != 0;
@ -823,8 +861,8 @@ public class TransformExceptionHandlers {
FlowBlock newFlow = new FlowBlock(catchFlow.method, FlowBlock newFlow = new FlowBlock(catchFlow.method,
catchFlow.getAddr(), 0); catchFlow.getAddr(), 0);
newFlow.setBlock(jump); newFlow.setBlock(jump);
catchFlow.prevByAddr.setNextByAddr(newFlow); catchFlow.prevByAddr.nextByAddr = newFlow;
newFlow.setNextByAddr(catchFlow); newFlow.nextByAddr = catchFlow;
catchFlow = newFlow; catchFlow = newFlow;
} else { } else {
if ((GlobalOptions.debuggingFlags 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(); analyze();
} }
public void analyzeIdentifier(Identifier i) { public void analyzeIdentifier(Identifier ident) {
toAnalyze.add(i); if (ident == null)
throw new NullPointerException();
toAnalyze.add(ident);
} }
public void analyze() { public void analyze() {

@ -40,6 +40,7 @@ import jode.util.Iterator;
import jode.util.List; import jode.util.List;
import jode.util.LinkedList; import jode.util.LinkedList;
import jode.util.Map; import jode.util.Map;
import jode.util.UnsupportedOperationException;
///#endif ///#endif
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
@ -57,7 +58,6 @@ public class ClassIdentifier extends Identifier {
String superName; String superName;
String[] ifaceNames; String[] ifaceNames;
List identifiers;
List fieldIdents, methodIdents; List fieldIdents, methodIdents;
List knownSubClasses = new LinkedList(); List knownSubClasses = new LinkedList();
List virtualReachables = new LinkedList(); List virtualReachables = new LinkedList();
@ -82,6 +82,7 @@ public class ClassIdentifier extends Identifier {
String fullName = getFullName() + "."; String fullName = getFullName() + ".";
for (Iterator i = getChilds(); i.hasNext(); ) { for (Iterator i = getChilds(); i.hasNext(); ) {
Identifier ident = (Identifier) i.next(); Identifier ident = (Identifier) i.next();
System.err.println("checking "+ident);
if (wildcard.matches(fullName + ident.getName()) if (wildcard.matches(fullName + ident.getName())
|| wildcard.matches(fullName + ident.getName() || wildcard.matches(fullName + ident.getName()
+ "." +ident.getType())) { + "." +ident.getType())) {
@ -94,8 +95,24 @@ public class ClassIdentifier extends Identifier {
} }
} }
public void preserveIdentifier(String name, String typeSig) { private FieldIdentifier findField(String name, String typeSig) {
preserveMatchingIdentifier(new WildCard(name+"."+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, public void reachableIdentifier(String name, String typeSig,
@ -109,6 +126,20 @@ public class ClassIdentifier extends Identifier {
found = true; 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) { if (isVirtual) {
for (Iterator i = knownSubClasses.iterator(); i.hasNext(); ) for (Iterator i = knownSubClasses.iterator(); i.hasNext(); )
((ClassIdentifier)i.next()) ((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 name = chainIdent.getName();
String typeSig = chainIdent.getType(); String typeSig = chainIdent.getType();
for (Iterator i = getChilds(); i.hasNext(); ) { for (Iterator i = methodIdents.iterator(); i.hasNext(); ) {
Identifier ident = (Identifier) i.next(); Identifier ident = (Identifier) i.next();
if (ident.getName().equals(ident.getName()) if (ident.getName().equals(name)
&& (ident.getType().equals(typeSig))) && ident.getType().equals(typeSig))
chainIdent.addShadow(ident); chainIdent.addShadow(ident);
} }
} }
@ -246,33 +277,28 @@ public class ClassIdentifier extends Identifier {
* a compatible class. * a compatible class.
*/ */
public void preserveSerializable() { public void preserveSerializable() {
preserveIdentifier("writeObject", "(Ljava.io.ObjectOutputStream)V"); Identifier method
preserveIdentifier("readObject", "(Ljava.io.ObjectOutputStream)V"); = 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) { if ((Main.options & Main.OPTION_PRESERVESERIAL) != 0) {
setPreserved(); setPreserved();
boolean hasSerialUID = false; Identifier UIDident = findField("serialVersionUID", "J");
for (Iterator i = getFieldIdents().iterator(); i.hasNext(); ) { if (UIDident == null) {
Identifier ident = (Identifier) i.next();
if ("serialVersionUID".equals(ident.getName())
&& "J".equals(ident.getType())) {
ident.setReachable();
ident.setPreserved();
hasSerialUID = true;
break;
}
}
if (!hasSerialUID) {
/* add a field serializableVersionUID if not existent */ /* add a field serializableVersionUID if not existent */
long serialVersion = calcSerialVersionUID(); long serialVersion = calcSerialVersionUID();
FieldInfo UIDField = new FieldInfo FieldInfo UIDField = new FieldInfo
(info, "serialVersionUID", "J", (info, "serialVersionUID", "J",
Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL); Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
UIDField.setConstant(new Long(serialVersion)); UIDField.setConstant(new Long(serialVersion));
FieldIdentifier fident = new FieldIdentifier(this, UIDField); UIDident = new FieldIdentifier(this, UIDField);
fident.setPreserved(); fieldIdents.add(UIDident);
fident.setReachable();
fieldIdents.add(fident);
} }
UIDident.setReachable();
UIDident.setPreserved();
for (Iterator i=getFieldIdents().iterator(); i.hasNext(); ) { for (Iterator i=getFieldIdents().iterator(); i.hasNext(); ) {
FieldIdentifier ident = (FieldIdentifier) i.next(); FieldIdentifier ident = (FieldIdentifier) i.next();
if ((ident.info.getModifiers() if ((ident.info.getModifiers()
@ -358,7 +384,7 @@ public class ClassIdentifier extends Identifier {
| Modifier.FINAL) & modif) == 0 | Modifier.FINAL) & modif) == 0
&& !(mid.getName().equals("<init>"))) { && !(mid.getName().equals("<init>"))) {
// chain the preserved/same name lists. // chain the preserved/same name lists.
chainIdentifier(mid); chainMethodIdentifier(mid);
} }
} }
} else { } else {
@ -371,8 +397,10 @@ public class ClassIdentifier extends Identifier {
if (((Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL) if (((Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL)
& modif) == 0 & modif) == 0
&& !topmethods[i].getName().equals("<init>")) { && !topmethods[i].getName().equals("<init>")) {
preserveIdentifier Identifier method = findMethod
(topmethods[i].getName(), topmethods[i].getType()); (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(finfos), rand);
Collections.shuffle(Arrays.asList(minfos), rand); Collections.shuffle(Arrays.asList(minfos), rand);
} }
identifiers = new ArrayList(finfos.length + minfos.length); fieldIdents = new ArrayList(finfos.length);
fieldIdents = identifiers.subList(0, 0); methodIdents = new ArrayList(minfos.length);
methodIdents = identifiers.subList(0, 0);
identifiers = Collections.unmodifiableList(identifiers);
for (int i=0; i< finfos.length; i++) for (int i=0; i< finfos.length; i++)
fieldIdents.add(new FieldIdentifier(this, finfos[i])); fieldIdents.add(new FieldIdentifier(this, finfos[i]));
@ -665,36 +691,30 @@ public class ClassIdentifier extends Identifier {
transformSuperIfaces(); transformSuperIfaces();
transformInnerClasses(); transformInnerClasses();
int newFieldCount = 0, newMethodCount = 0; Collection newFields = new ArrayList(fieldIdents.size());
if ((Main.stripping & Main.STRIP_UNREACH) != 0) { Collection newMethods = new ArrayList(methodIdents.size());
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;
for (Iterator i = fieldIdents.iterator(); i.hasNext(); ) { for (Iterator i = fieldIdents.iterator(); i.hasNext(); ) {
FieldIdentifier ident = (FieldIdentifier)i.next(); FieldIdentifier ident = (FieldIdentifier)i.next();
ident.doTransformations(); if ((Main.stripping & Main.STRIP_UNREACH) == 0
newFields[newFieldCount++] = ident.info; || ident.isReachable()) {
ident.doTransformations();
newFields.add(ident.info);
}
} }
for (Iterator i = methodIdents.iterator(); i.hasNext(); ) { for (Iterator i = methodIdents.iterator(); i.hasNext(); ) {
MethodIdentifier ident = (MethodIdentifier)i.next(); MethodIdentifier ident = (MethodIdentifier)i.next();
ident.doTransformations(); if ((Main.stripping & Main.STRIP_UNREACH) == 0
newMethods[newMethodCount++] = ident.info; || ident.isReachable()) {
ident.doTransformations();
newMethods.add(ident.info);
}
} }
info.setFields(newFields); info.setFields((FieldInfo[]) newFields.toArray
info.setMethods(newMethods); (new FieldInfo[newFields.size()]));
info.setMethods((MethodInfo[]) newMethods.toArray
(new MethodInfo[newMethods.size()]));
} }
public void storeClass(DataOutputStream out) throws IOException { public void storeClass(DataOutputStream out) throws IOException {
@ -702,7 +722,7 @@ public class ClassIdentifier extends Identifier {
GlobalOptions.err.println("Writing "+this); GlobalOptions.err.println("Writing "+this);
info.write(out); info.write(out);
info = null; info = null;
identifiers = null; fieldIdents = methodIdents = null;
} }
public Identifier getParent() { public Identifier getParent() {
@ -746,7 +766,28 @@ public class ClassIdentifier extends Identifier {
} }
public Iterator getChilds() { 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() { public String toString() {
@ -754,24 +795,13 @@ public class ClassIdentifier extends Identifier {
} }
public Identifier getIdentifier(String fieldName, String typeSig) { 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(); Identifier ident = (Identifier) i.next();
if (ident.getName().equals(fieldName) if (ident.getName().equals(fieldName)
&& ident.getType().startsWith(typeSig)) && ident.getType().startsWith(typeSig))
return ident; 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) { if (superName != null) {
ClassIdentifier superident = Main.getClassBundle() ClassIdentifier superident = Main.getClassBundle()
.getClassIdentifier(superName); .getClassIdentifier(superName);

@ -448,10 +448,17 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
(clName.substring(1, clName.length()-1) (clName.substring(1, clName.length()-1)
.replace('/','.')); .replace('/','.'));
} }
while (clazz != null if (instr.opcode >= opc_invokevirtual) {
&& clazz.findMethod(ref.getName(), while (clazz != null
ref.getType()) == null) && clazz.findMethod(ref.getName(),
clazz = clazz.getSuperclass(); ref.getType()) == null)
clazz = clazz.getSuperclass();
} else {
while (clazz != null
&& clazz.findField(ref.getName(),
ref.getType()) == null)
clazz = clazz.getSuperclass();
}
if (clazz == null) { if (clazz == null) {
GlobalOptions.err.println("WARNING: Can't find reference: " 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) { public void analyzeCode(MethodIdentifier listener, BytecodeInfo bytecode) {
this.listener = listener;
this.bytecode = bytecode; this.bytecode = bytecode;
working = true; working = true;
if (constInfos == null) if (constInfos == null)

@ -111,6 +111,8 @@ public class FieldIdentifier extends Identifier{
} }
public void addFieldListener(Identifier ident) { public void addFieldListener(Identifier ident) {
if (ident == null)
throw new NullPointerException();
if (!fieldListeners.contains(ident)) if (!fieldListeners.contains(ident))
fieldListeners.add(ident); fieldListeners.add(ident);
} }

@ -179,14 +179,13 @@ public abstract class Identifier {
if (GlobalOptions.verboseLevel > 4) if (GlobalOptions.verboseLevel > 4)
GlobalOptions.err.println(toString() + " is preserved"); GlobalOptions.err.println(toString() + " is preserved");
} else { } else {
Identifier rep = getRepresentative(); Identifier rep = getRepresentative();
if (rep.wasAliased) if (rep.wasAliased)
return; return;
rep.wasAliased = true; rep.wasAliased = true;
// set alias to empty string, so it won't conflict! // set alias to empty string, so it won't conflict!
alias = ""; rep.alias = "";
String newAlias = null; String newAlias = null;
next_alias: next_alias:
for (;;) { for (;;) {
@ -198,7 +197,7 @@ public abstract class Identifier {
ptr = ptr.right; ptr = ptr.right;
} }
setAlias(newAlias.toString()); setAlias(newAlias.toString());
return; break;
} }
} }
for (Iterator i = getChilds(); i.hasNext(); ) for (Iterator i = getChilds(); i.hasNext(); )

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

@ -18,10 +18,69 @@
*/ */
package jode.obfuscator; 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; import jode.type.Type;
public class SimpleAnalyzer implements CodeAnalyzer, Opcodes { 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 * Reads the opcodes out of the code info and determine its
* references * references
@ -54,52 +113,21 @@ public class SimpleAnalyzer implements CodeAnalyzer, Opcodes {
/* fall through */ /* fall through */
case opc_getstatic: case opc_getstatic:
case opc_getfield: { case opc_getfield: {
Reference ref = (Reference) instr.objData; Identifier ident = canonizeReference(instr);
Identifier ident = Main.getClassBundle().getIdentifier(ref);
String clName = ref.getClazz();
String realClazzName;
if (ident != null) { if (ident != null) {
ClassIdentifier clazz = (ClassIdentifier)ident.getParent();
realClazzName = "L" + (clazz.getFullName()
.replace('.', '/')) + ";";
if (instr.opcode == opc_putstatic if (instr.opcode == opc_putstatic
|| instr.opcode == opc_putfield) { || instr.opcode == opc_putfield) {
FieldIdentifier fi = (FieldIdentifier) ident; FieldIdentifier fi = (FieldIdentifier) ident;
if (fi != null && !fi.isNotConstant()) if (fi != null && !fi.isNotConstant())
fi.setNotConstant(); fi.setNotConstant();
} else if (instr.opcode == opc_invokevirtual
|| instr.opcode == opc_invokeinterface) {
((ClassIdentifier) ident.getParent())
.reachableIdentifier(ident.getName(),
ident.getType(), true);
} else { } else {
clazz.reachableIdentifier ident.setReachable();
(ref.getName(), ref.getType(),
instr.opcode == opc_invokevirtual
|| instr.opcode == opc_invokeinterface);
} }
} 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; break;
} }

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

@ -266,7 +266,7 @@ public class Main
String cp = System.getProperty("java.class.path", ""); String cp = System.getProperty("java.class.path", "");
cp = cp.replace(File.pathSeparatorChar, SearchPath.pathSeparatorChar); cp = cp.replace(File.pathSeparatorChar, SearchPath.pathSeparatorChar);
for (int i=0; i<params.length; i++) { for (int i=0; i<params.length; i++) {
if (params[i].equals("--cp")) if (params[i].equals("--classpath"))
cp = params[++i]; cp = params[++i];
else else
return; 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

@ -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
Loading…
Cancel
Save