From f85c46fd44fcffe9bc52c836c7e9453b1394e38b Mon Sep 17 00:00:00 2001 From: hoenicke Date: Mon, 3 Jul 2000 13:15:08 +0000 Subject: [PATCH] TODO list updated jcpp javaDeps moved to scripts git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1249 379699f6-c40d-0410-875b-85095c16579e --- jode/TODO | 41 ++++++-- jode/configure.in | 70 +------------- jode/javaDependencies.pl.in | 184 ------------------------------------ jode/jcpp | 173 --------------------------------- 4 files changed, 35 insertions(+), 433 deletions(-) delete mode 100755 jode/javaDependencies.pl.in delete mode 100755 jode/jcpp diff --git a/jode/TODO b/jode/TODO index 96163d2..9ec514b 100644 --- a/jode/TODO +++ b/jode/TODO @@ -1,6 +1,7 @@ This is a list of features, that would be nice to have: Decompiler: + - BUG: public final static null fields aren't initialized (leads to compile error) - outline inlined methods. - remove string decrypt method. - remove synthetic methods if and only if all calls to them are resolved. @@ -8,15 +9,39 @@ Decompiler: ~ decompile jode.jvm.Interpreter (hand optimized bytecode) Obfuscator: - - flow obfuscation/optimization. - - warn about Class.forName and list occurences. + - Detect Class.forName() calls with constant parameters and rename + these constants. Detect class$ methods with constant parameters. + Warn about all other occurences of Class.forName() + + This should be put into the constant analyzer. The simple + analyzer should only do the warnings. + - Transforming the class hierarchy, e.g. combining two totally + unrelated classes together into one class or make some class + to implement some interfaces, that it previously didn't. + - Doing flow obfuscation, i.e. do some tests, that one knows to + succeed always, and jump to funny position if the test fails. + The tests should use undecidable properties, so that a + deobfuscator cannot remove them again. DeObfuscator: - - generate nice names: - - classes: derive name from super. - - fields: derive name from type. - - give synthetic methods the right attribute and name (e.g. class$) - - detect inner classes and give suitable names. + - Deobfuscator should detect inner/anonymous classes and mark them + as such. It should be possible with the renaming table to mark + inner classes as well. Inner classes are easy to detect; there + constructor has a special form. And the information is very + useful for the decompiler. + + This should be done with some generalize interface similar to (or + instead of) Transformer + + - Deobfuscator should generate nicer names. This should be a + special Renamer. The renamer should analyze short methods and + call them getXXX, isXXX, setXXX if apropriate, detect synthetic + methods and similar. Class names should be derived from super + class or interface (e.g. Enumeration), fields should be derived + from their type, maybe also from their assignments. + + One can build more renamer, each handles some special cases and + calls the next one, if it can't handle an identifier. User Interface: - make a nice user interface: @@ -29,4 +54,4 @@ User Interface: - visual obfuscation/deobfuscation (like klassmaster?, better?) Internal: - - clean up package hierarchy, esp. expr, flow and decompiler. \ No newline at end of file + - clean up package hierarchy, esp. expr, flow and decompiler. diff --git a/jode/configure.in b/jode/configure.in index c106d94..d8d1cb6 100644 --- a/jode/configure.in +++ b/jode/configure.in @@ -157,9 +157,9 @@ AC_SUBST(SWINGUI) AC_SUBST(CLASSPATH) AC_SUBST(JAVAC) +AC_SUBST(JAR) AC_OUTPUT(Makefile -javaDependencies.pl jode/Makefile jode/bytecode/Makefile jode/decompiler/Makefile @@ -171,75 +171,9 @@ jode/obfuscator/modules/Makefile jode/swingui/Makefile jode/type/Makefile jode/util/Makefile -jode/bytecode/BinaryInfo.java -jode/bytecode/BytecodeInfo.java -jode/bytecode/ClassInfo.java -jode/bytecode/Reference.java -jode/decompiler/ImportHandler.java -jode/decompiler/ClassAnalyzer.java -jode/decompiler/FieldAnalyzer.java -jode/decompiler/MethodAnalyzer.java -jode/decompiler/DeadCodeAnalysis.java -jode/expr/Expression.java -jode/expr/FieldOperator.java -jode/expr/InvokeOperator.java -jode/expr/LocalVarOperator.java -jode/expr/Operator.java -jode/expr/CheckNullOperator.java -jode/flow/RetBlock.java -jode/flow/InstructionContainer.java -jode/flow/LoopBlock.java -jode/flow/SequentialBlock.java -jode/flow/SlotSet.java -jode/flow/StructuredBlock.java -jode/flow/SynchronizedBlock.java -jode/flow/VariableSet.java -jode/flow/CatchBlock.java -jode/flow/IfThenElseBlock.java -jode/flow/InstructionBlock.java -jode/flow/FlowBlock.java -jode/flow/TransformExceptionHandlers.java -jode/jvm/CodeVerifier.java -jode/jvm/Interpreter.java -jode/jvm/SyntheticAnalyzer.java -jode/obfuscator/ClassBundle.java -jode/obfuscator/ClassIdentifier.java -jode/obfuscator/ConstantRuntimeEnvironment.java -jode/obfuscator/FieldIdentifier.java -jode/obfuscator/Identifier.java -jode/obfuscator/LocalIdentifier.java -jode/obfuscator/Main.java -jode/obfuscator/MethodIdentifier.java -jode/obfuscator/OptionHandler.java -jode/obfuscator/PackageIdentifier.java -jode/obfuscator/Renamer.java -jode/obfuscator/ScriptParser.java -jode/obfuscator/TranslationTable.java -jode/obfuscator/modules/ConstantAnalyzer.java -jode/obfuscator/modules/KeywordRenamer.java -jode/obfuscator/modules/LocalOptimizer.java -jode/obfuscator/modules/LocalizeFieldTransformer.java -jode/obfuscator/modules/ModifierMatcher.java -jode/obfuscator/modules/MultiIdentifierMatcher.java -jode/obfuscator/modules/NameSwapper.java -jode/obfuscator/modules/RemovePopAnalyzer.java -jode/obfuscator/modules/SerializePreserver.java -jode/obfuscator/modules/SimpleAnalyzer.java -jode/obfuscator/modules/StrongRenamer.java -jode/obfuscator/modules/UniqueRenamer.java -jode/obfuscator/modules/WildCard.java -jode/swingui/Main.java -jode/swingui/PackagesTreeModel.java -jode/swingui/HierarchyTreeModel.java -jode/type/Type.java -jode/util/SimpleSet.java -jode/util/SimpleMap.java -jode/util/UnifyHash.java -jode/GlobalOptions.java bin/Makefile bin/jode bin/jode.bat doc/Makefile -doc/download.html test/Makefile, -[chmod 755 javaDependencies.pl bin/jode]) +[chmod 755 bin/jode]) diff --git a/jode/javaDependencies.pl.in b/jode/javaDependencies.pl.in deleted file mode 100755 index 8577fe8..0000000 --- a/jode/javaDependencies.pl.in +++ /dev/null @@ -1,184 +0,0 @@ -#!@PERL@ -s -w -# -# javaDependencies Copyright (C) 1999 Jochen Hoenicke. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -# -# $Id$ - -# This scripts create Makefile dependencies out of class files. It -# simply scans the constant pool of the class files, finding all -# references to other classes and adding a dependency to that class. -# -# It doesn't do a perfect job, since it can't handle dependencies to -# constant values in different classes: The compiler inlines the -# constant and thus doesn't include a reference to the class. -# -# Usage: -# javaDependencies.pl -classpath [-dependdir [-subdir ]] -# [-depfile ] -# -# -# cp: colon separated paths to the java files we should depend on. -# depdir: if set, use this path as path to the java files when printing -# dependencies, not the path where the java files were found. -# useful, if you want to make use of VPATH settings in Makefile. -# subdir: if set, this is the path from depdir to the current directory. -# Use it to remove unneccessary ../../$subdir/ -# depfile: the name of the dependency file, default is "Makefile.dep". -# class: The class files (not inner classes) for which the dependencies -# should be generated. We will also look for inner and anon -# classes. - -my $buff; - -sub readInBuff ($) { - my $count = $_[0]; - my $offset = 0; - while ($count > 0) { - my $result; - $result = read FILE, $buff, $count, $offset or return 0; - $offset += $result; - $count -= $result; - } - $offset; -} - -sub readUTF () { - readInBuff 2 or die "Can't read UTF8 length"; - my $ulength = unpack("n", $buff) & 0xffff; - return "" if $ulength == 0; - readInBuff $ulength or die "Can't read UTF8 string $ulength"; - unpack("a$ulength", $buff); -} - -$depfile = "Makefile.dep" if (!defined($depfile)); -open DEPFILE, ">$depfile"; -print DEPFILE < 3; - die "Wrong minor $major" if $major != 45; - - readInBuff 2 or die "Can't read cpool length"; - - - my ($length) = unpack("n", $buff) & 0xffff; - - my $number; - my @strings = (); - my @clazzes; - for ($number = 1; $number < $length; $number++) { - - readInBuff 1 or die "Can't read constant tag"; - my ($tag) = unpack("C", $buff); - - #print STDERR "$number/$length: $tag"; - tags: - for ($tag) { - /^1$/ && do { - # UTF 8 - $strings[$number] = &readUTF(); - #print STDERR ": $strings[$number]"; - last tags; - }; - - /^(3|4|9|10|11|12)$/ && do { - # INTEGER, FLOAT, FIELDREF, METHODREF, IFACEREF, NAMEANDTYPE - readInBuff 4; - last tags; - }; - - /^(5|6)$/ && do { - # LONG, DOUBLE - readInBuff 8; - $number++; - last tags; - }; - - /^7$/ && do { - # CLASS - readInBuff 2; - push @clazzes, (unpack("n", $buff) & 0xffff); - last tags; - }; - - /^8$/ && do { - # STRING - readInBuff 2; - last tags; - }; - die "Unknown tag: $tag, $number/$length, $filename"; - } - #print STDERR "\n"; - } - - - my @deplist = (); - clazz: - for $c (@clazzes) { - $clzz = $strings[$c]; - next if $clzz =~ /^\[/; - next if defined $done{"$clzz"}; - $done{$clzz} = 1; - - my $p; - for $p (split ':', $classpath) { - if (-e "$p/$clzz.java") { - my $path="$p/"; - if (defined $dependdir) { - $path = "$dependdir/"; - if (defined $subdir) { - my $currsubdir = "$subdir/"; - while ($currsubdir =~ m<^([A-Za-z0-9]+)/+(.*)>) { - $currsubdir = $2; - my $firstcomp = $1; - if ($clzz =~ m<$firstcomp/(.*)>) { - my $remain = $1; - if ($path =~ m<^(|.*/)\.\./+$>) { - $path = $1; - $clzz = $remain; - } - } - } - } - } - push @deplist, "$path$clzz.java"; - next clazz; - } - } - } - if (@deplist) { - print DEPFILE "$clazz: " . join (" ", @deplist) . "\n"; - } - } -} -close DEPFILE; diff --git a/jode/jcpp b/jode/jcpp deleted file mode 100755 index cbbc847..0000000 --- a/jode/jcpp +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/perl -# -# jcpp Copyright (C) 1999 Jochen Hoenicke. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -# -# $Id$ - -# This is a program to allow conditional compiled code in java files. -# The key idea is, not to run the file always through the -# preprocessor, but to modify the java files directly and make use of -# comments. -# -# The comments all have the form /// to distinguish them from normal -# comments. You should not use such comments yourself. -# -# Usage is simple: jcpp -Ddefine1 -Ddefine2 first.java second.java -# The files should contain comments of the form -# -# ///#ifdef JDK12 -# jdk1.2 code -# ///#else -# jdk1.1 code -# ///#endif -# -# After running jcpp the false branch is commented out. If the true -# branch was commented out it will get commented in. - -my @files; -my %defs; - -for (@ARGV) { - if ($_ =~ /^-D([^=]*)$/) { - $defs{$1} = 1; - } elsif ($_ =~ /^-D([^=]*)=([^=]*)$/) { - $defs{$1} = $2; - } else { - push @files, $_; - } -} - -for (@files) { - # Number of nested #if directives. Initially 0, will be increased - # on every #if directive and decreased on every #endif directive. - my $level = 0; - - # The number of the outermost level, whose #if directive was - # false. This is 0, if there wasn't an false #if directive, yet. - # As long as it is != 0, we comment every line, and ignore - # directives except for increasing/decreasing $level. - my $falselevel = 0; - - # Tells if an error occured and the transformation shouldn't - # be done. - my $error = 0; - my $changes = 0; - - my $file = $_; - open OLD, "<$file" or do { - print STDERR "Can't open file $file\n"; - next; - }; - open NEW, ">$file.tmp" or do { - print STDERR "Can't open tmp file $file.tmp\n"; - next; - }; - my $linenr = 0; - LINE: - while () { - $linenr++; - if (m'^///#') { - # This is a directive. First we print it out. - print NEW $_; - if (m'^///# *if') { - $level++; - if (m'^///# *ifdef (\S*)$') { - # If there was an outer false #if directive, we ignore the - # condition. - next LINE if ($falselevel); - - my $label=$1; - - # An ifdef directive, look if -D is defined. - $falselevel = $level - unless (defined $defs{$label}); - } elsif (m'^///# *ifndef (\S*)$') { - # If there was an outer false #if directive, we ignore the - # condition. - next LINE if ($falselevel); - - my $label=$1; - # An ifndef directive, look if -D is defined - $falselevel = $level - if (defined $defs{$label}); - } - } elsif (m'^///# *else') { - # An else directive. We switch from true to false and - # if level is falselevel we switch from false to true - if ($level == 0) { - # An else outside of any directives; warn. - print STDERR "$file: $linenr: unmatched $_"; - $error = 1; - } elsif ($falselevel == $level) { - $falselevel = 0; - } elsif ($falselevel == 0) { - $falselevel = $level; - } - } elsif (m'^///# *endif') { - # set $falselevel to 0, if the false branch is over now. - $falselevel = 0 if ($falselevel == $level); - # decrease level. - if ($level == 0) { - print STDERR "$file: $linenr: unmatched $_"; - $error = 1; - } else { - $level--; - } - } else { - print STDERR "$file: $linenr: ignoring unknown directive $_"; - $error = 1; - } - } elsif (m'^///(.*)') { - $line = $1; - if ($falselevel == 0 && $level > 0) { - # remove comments in true branch, but not in outermost level. - print NEW "$line\n"; - $changes = 1; - } else { - # print out the full line with comments: - print NEW $_; - } - } else { - if ($falselevel != 0) { - # add comments in false branch - print NEW "///$_"; - $changes = 1; - } else { - print NEW $_; - } - } - } - - if ($level != 0 || $falselevel != 0) { - # something got wrong - print STDERR "$file: unmatched directives: level $level, ". - "falselevel $falselevel\n"; - $error = 1; - } - - if ($error == 0) { - if ($changes == 0) { - unlink "$file.tmp"; - } else { - (rename "$file", "$file.orig" - and rename "$file.tmp", "$file") - or print STDERR "$file: Couldn't rename files.\n"; - } - } else { - print STDERR "$file: errors occured, file not transformed.\n"; - } -}