Compare commits

...

64 Commits

Author SHA1 Message Date
hoenicke 12e82bea53 Set copyright to LGPL for jode.type package 14 years ago
hoenicke e10bfec001 Minor fixes 17 years ago
hoenicke 240de78e81 jode/bytecode/ClassInfo.java.in, jode/bytecode/MethodInfo.java, 17 years ago
hoenicke fca129b90a enum -> enumeration (jdk1.5) 19 years ago
hoenicke 26933573bb Ignore minor(major?) number 19 years ago
hoenicke 190eefee2c Check for NullPointer in SyntheticAnalyzer. Based on 19 years ago
hoenicke 90aa079d11 Added patch from Peter Klauser (klp at users.sf.net), to support 19 years ago
hoenicke aae07e1491 A continue was missing that could produce ArrayIndexOutOfBounds 20 years ago
hoenicke 6604df3248 Added patch from Thomas Oldervoll, to continue decompiling 21 years ago
hoenicke 97b5c5bb0f deprecated flags for classinfo 22 years ago
hoenicke f38c62b1cd Set version number to 1.1.2. 22 years ago
hoenicke d1f22a62b4 Fix the exception handlers that Javac 1.4 produces. 22 years ago
hoenicke c761c52679 Changed license of util,bytecode,jvm,expr,flow and decompiler packages 22 years ago
hoenicke a12e86ea8f Don't check for a maximum version anymore. Sun changes it with every 22 years ago
hoenicke 111d5046ea * jode/obfuscator/ClassIdentifier.java.in (transformInnerClasses): 23 years ago
hoenicke a0caad2c2c * jode/flow/CreateAssignExpression.java (createAssignOp): 23 years ago
hoenicke 910456c0b0 Fixes by anonymous for SerializePreserver: 23 years ago
hoenicke 686154fca2 * jode/obfuscator/modules/MultiIdentifierMatcher.java.in 23 years ago
hoenicke 068e85a76d Fixed major/minor naming. Allow minor to be bigger than 45 for newer java 23 years ago
hoenicke ea5e834abe * configure.in: Set version number to 1.1.1. 23 years ago
hoenicke 03497ae1a2 Fixed Java-1.1 and finally/synchronized blocks. 23 years ago
hoenicke c79f6122f5 * configure.in: Changed bash syntax to more compatible (but 23 years ago
hoenicke 805ab8613d * jode/expr/InvokeOperator.java.in (dumpExpression): Fixed the 23 years ago
hoenicke 15e7ec9dc0 More debugging outputs. 23 years ago
hoenicke a018796a04 * jode/obfuscator/Main.java.in (stripping): Initialize to 0 which 23 years ago
hoenicke aca789beed * jode/flow/CatchBlock.java.in (combineLocal): Added more checks 23 years ago
hoenicke a65fd35ceb * jode/obfuscator/modules/SimpleAnalyzer.java.in: 23 years ago
hoenicke fa005e09ee * jode/bytecode/BytecodeInfo.java.in (calculateMaxStack): Handle 23 years ago
hoenicke dd5112302f Added more links. 23 years ago
hoenicke fbcfb06d90 * jode/jvm/SyntheticAnalyzer.java.in: 23 years ago
hoenicke 5a4dbe0b02 Fixed a bug in the obfuscator. 23 years ago
hoenicke af086625d8 More documentation updates. 23 years ago
hoenicke 98bf83e95d Fixed link to sourceforge logo. 23 years ago
hoenicke 7fca8d09e9 Remove .html files, added a-logo.gif 23 years ago
hoenicke 0246d1e5c3 lots of changes, see ChangeLog 23 years ago
hoenicke 23adc4ce78 * jode/jvm/CodeVerifier.java.in (doVerify): Don't check for 23 years ago
hoenicke 736e9595d2 * jode/obfuscator/modules/ConstantAnalyzer.java.in (handleOpcode): 23 years ago
hoenicke d093988656 Reworked usage message. 23 years ago
hoenicke 95b75fa705 Bug fixes from Joe Bronkema. 23 years ago
hoenicke b355dc3395 * acinclude.m4 (JODE_CHECK_CLASS): Changed "test -e" to "-f" since 23 years ago
hoenicke 5e972183a9 * jode/swingui/Main.java.in (AreaWriter): Convert all kinds of 23 years ago
hoenicke c5fae0c7ee Some more bug fixes, see changelog. 24 years ago
hoenicke f1cee9fca4 InvokeOperator (method interpreter): Fixed call to ClassInfo.forName. 24 years ago
hoenicke dbacfa1c7e updated list 24 years ago
hoenicke 1f87c3817c Changed version to 1.2 24 years ago
hoenicke 4aebd22542 Fixed previous patch. 24 years ago
hoenicke 344faa9265 CodeVerifier, ArrayType: merge array types whose elemTypes are incompatible 24 years ago
hoenicke d0a70c3626 SyntheticAnalyzer: Allow the special unifyParam to be the last parameter. 24 years ago
hoenicke cb12d3ead2 Pascal style. 24 years ago
hoenicke 816bca302d Distinguish method scoped classes from inner classes in a better way. 24 years ago
hoenicke 0785a7cd21 Support decompiling complete Zip files 24 years ago
hoenicke 4888c5f98c Set fields to not editable. 24 years ago
hoenicke 3506e82033 Ported a fix (this class could throw an ArrayIndexOutOfBoundsException due, to 24 years ago
hoenicke fb5d918702 Another fix: The fall through for opc_dadd and co. didn't work 24 years ago
hoenicke 7eb1d3f8b5 Forgot to calc stacksize for exception handlers. 24 years ago
hoenicke 7548f53a75 Fixed another stupid bug. 24 years ago
hoenicke ef0a0f214b Reserve locals for method arguments. Important if they are not accessed 24 years ago
hoenicke 0250b87fe1 Removed some old local variables, that were never accessed. 24 years ago
hoenicke f26d8a21e6 Calculate number of stack elements and local variables in prepareWriting. 24 years ago
hoenicke a56a7f0e98 Fixed a bug in configure.in, reported by zzzeek 24 years ago
hoenicke 075db18fcf Accept class version 46.0 (jdk1.2) 24 years ago
hoenicke 356a8c6a61 New implementation to get the alias of a class getClassAlias(). 24 years ago
hoenicke f0392e9371 Don't create doc/download.html anymore 24 years ago
(no author) 6466af0fea This commit was manufactured by cvs2svn to create branch 'branch_1_1'. 24 years ago
  1. 13
      CVSROOT/checkoutlist
  2. 15
      CVSROOT/commitinfo
  3. 11
      CVSROOT/config
  4. 1
      CVSROOT/cvsignore
  5. 23
      CVSROOT/cvswrappers
  6. 21
      CVSROOT/editinfo
  7. 26
      CVSROOT/loginfo
  8. 1
      CVSROOT/modules
  9. 12
      CVSROOT/notify
  10. 13
      CVSROOT/rcsinfo
  11. 20
      CVSROOT/taginfo
  12. 21
      CVSROOT/verifymsg
  13. 2
      jode/AUTHORS
  14. 504
      jode/COPYING.LESSER
  15. 525
      jode/ChangeLog
  16. 17
      jode/INSTALL
  17. 4
      jode/Makefile.am
  18. 8
      jode/NEWS
  19. 97
      jode/README
  20. 5
      jode/THANKS
  21. 13
      jode/TODO
  22. 2
      jode/acinclude.m4
  23. 27
      jode/addHeader.pl
  24. 23
      jode/configure.in
  25. 1
      jode/doc/.cvsignore
  26. 48
      jode/doc/Makefile.am
  27. BIN
      jode/doc/a-logo.gif
  28. 97
      jode/doc/applet.html
  29. 22
      jode/doc/applet.php
  30. 133
      jode/doc/bluesky.html
  31. 92
      jode/doc/download.html
  32. 56
      jode/doc/download.php
  33. 72
      jode/doc/faq.php
  34. 14
      jode/doc/feedback.php
  35. 11
      jode/doc/footer.inc
  36. 55
      jode/doc/header.inc
  37. 84
      jode/doc/history.html
  38. 2
      jode/doc/history.php
  39. 131
      jode/doc/index.html
  40. 44
      jode/doc/index.php
  41. 76
      jode/doc/license.html
  42. 9
      jode/doc/license.php
  43. 123
      jode/doc/links.html
  44. 23
      jode/doc/links.php
  45. 132
      jode/doc/menu.inc
  46. 281
      jode/doc/usage.html
  47. 61
      jode/doc/usage.php
  48. 3
      jode/javaDependencies.pl.in
  49. 8
      jode/jode/AssertError.java
  50. 10
      jode/jode/GlobalOptions.java.in
  51. 8
      jode/jode/bytecode/BinaryInfo.java.in
  52. 324
      jode/jode/bytecode/BytecodeInfo.java.in
  53. 8
      jode/jode/bytecode/ClassFormatException.java
  54. 237
      jode/jode/bytecode/ClassInfo.java.in
  55. 8
      jode/jode/bytecode/ConstantPool.java
  56. 23
      jode/jode/bytecode/FieldInfo.java
  57. 8
      jode/jode/bytecode/GrowableConstantPool.java
  58. 8
      jode/jode/bytecode/Handler.java
  59. 8
      jode/jode/bytecode/InnerClassInfo.java
  60. 8
      jode/jode/bytecode/Instruction.java
  61. 8
      jode/jode/bytecode/LineNumber.java
  62. 8
      jode/jode/bytecode/LocalVariableInfo.java
  63. 20
      jode/jode/bytecode/MethodInfo.java
  64. 8
      jode/jode/bytecode/Opcodes.java
  65. 8
      jode/jode/bytecode/Reference.java.in
  66. 95
      jode/jode/bytecode/SearchPath.java
  67. 8
      jode/jode/bytecode/TypeSignature.java
  68. 8
      jode/jode/decompiler/Analyzer.java
  69. 8
      jode/jode/decompiler/Applet.java
  70. 173
      jode/jode/decompiler/ClassAnalyzer.java.in
  71. 8
      jode/jode/decompiler/ClassDeclarer.java
  72. 8
      jode/jode/decompiler/DeadCodeAnalysis.java.in
  73. 8
      jode/jode/decompiler/Declarable.java
  74. 10
      jode/jode/decompiler/Decompiler.java
  75. 17
      jode/jode/decompiler/FieldAnalyzer.java.in
  76. 8
      jode/jode/decompiler/ImportHandler.java.in
  77. 145
      jode/jode/decompiler/LocalInfo.java
  78. 8
      jode/jode/decompiler/LocalVarEntry.java
  79. 8
      jode/jode/decompiler/LocalVariableRangeList.java
  80. 8
      jode/jode/decompiler/LocalVariableTable.java
  81. 210
      jode/jode/decompiler/Main.java
  82. 95
      jode/jode/decompiler/MethodAnalyzer.java.in
  83. 8
      jode/jode/decompiler/Opcodes.java
  84. 19
      jode/jode/decompiler/Options.java
  85. 9
      jode/jode/decompiler/OuterValueListener.java
  86. 34
      jode/jode/decompiler/OuterValues.java
  87. 8
      jode/jode/decompiler/ProgressListener.java
  88. 8
      jode/jode/decompiler/Scope.java
  89. 124
      jode/jode/decompiler/TabbedPrintWriter.java
  90. 8
      jode/jode/decompiler/Window.java
  91. 8
      jode/jode/expr/ArrayLengthOperator.java
  92. 8
      jode/jode/expr/ArrayLoadOperator.java
  93. 33
      jode/jode/expr/ArrayStoreOperator.java
  94. 8
      jode/jode/expr/BinaryOperator.java
  95. 8
      jode/jode/expr/CheckCastOperator.java
  96. 8
      jode/jode/expr/CheckNullOperator.java.in
  97. 8
      jode/jode/expr/ClassFieldOperator.java
  98. 8
      jode/jode/expr/CombineableOperator.java
  99. 8
      jode/jode/expr/CompareBinaryOperator.java
  100. 9
      jode/jode/expr/CompareToIntOperator.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,13 +0,0 @@
# The "checkoutlist" file is used to support additional version controlled
# administrative files in $CVSROOT/CVSROOT, such as template files.
#
# The first entry on a line is a filename which will be checked out from
# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
# The remainder of the line is an error message to use if the file cannot
# be checked out.
#
# File format:
#
# [<whitespace>]<filename><whitespace><error message><end-of-line>
#
# comment lines begin with '#'

@ -1,15 +0,0 @@
# The "commitinfo" file is used to control pre-commit checks.
# The filter on the right is invoked with the repository and a list
# of files to check. A non-zero exit of the filter program will
# cause the commit to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT. For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".

@ -1,11 +0,0 @@
# Set this to "no" if pserver shouldn't check system users/passwords
#SystemAuth=no
# Set `PreservePermissions' to `yes' to save file status information
# in the repository.
#PreservePermissions=no
# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
# level of the new working directory when using the `cvs checkout'
# command.
#TopLevelAdmin=no

@ -1,23 +0,0 @@
# This file affects handling of files based on their names.
#
# The -t/-f options allow one to treat directories of files
# as a single file, or to transform a file in other ways on
# its way in and out of CVS.
#
# The -m option specifies whether CVS attempts to merge files.
#
# The -k option specifies keyword expansion (e.g. -kb for binary).
#
# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
#
# wildcard [option value][option value]...
#
# where option is one of
# -f from cvs filter value: path to filter
# -t to cvs filter value: path to filter
# -m update methodology value: MERGE or COPY
# -k expansion mode value: b, o, kkv, &c
#
# and value is a single-quote delimited value.
# For example:
#*.gif -k 'b'

@ -1,21 +0,0 @@
# The "editinfo" file is used to allow verification of logging
# information. It works best when a template (as specified in the
# rcsinfo file) is provided for the logging procedure. Given a
# template with locations for, a bug-id number, a list of people who
# reviewed the code before it can be checked in, and an external
# process to catalog the differences that were code reviewed, the
# following test can be applied to the code:
#
# Making sure that the entered bug-id number is correct.
# Validating that the code that was reviewed is indeed the code being
# checked in (using the bug-id number or a seperate review
# number to identify this particular code set.).
#
# If any of the above test failed, then the commit would be aborted.
#
# Actions such as mailing a copy of the report to each reviewer are
# better handled by an entry in the loginfo file.
#
# One thing that should be noted is the the ALL keyword is not
# supported. There can be only one entry that matches a given
# repository.

@ -1,26 +0,0 @@
# The "loginfo" file controls where "cvs commit" log information
# is sent. The first entry on a line is a regular expression which must match
# the directory that the change is being made to, relative to the
# $CVSROOT. If a match is found, then the remainder of the line is a filter
# program that should expect log information on its standard input.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name ALL appears as a regular expression it is always used
# in addition to the first matching regex or DEFAULT.
#
# You may specify a format string as part of the
# filter. The string is composed of a `%' followed
# by a single format character, or followed by a set of format
# characters surrounded by `{' and `}' as separators. The format
# characters are:
#
# s = file name
# V = old version number (pre-checkin)
# v = new version number (post-checkin)
#
# For example:
#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
# or
#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog

@ -1 +0,0 @@
jode jode

@ -1,12 +0,0 @@
# The "notify" file controls where notifications from watches set by
# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
# a regular expression which is tested against the directory that the
# change is being made to, relative to the $CVSROOT. If it matches,
# then the remainder of the line is a filter program that should contain
# one occurrence of %s for the user to notify, and information on its
# standard input.
#
# "ALL" or "DEFAULT" can be used in place of the regular expression.
#
# For example:
#ALL mail %s -s "CVS notification"

@ -1,13 +0,0 @@
# The "rcsinfo" file is used to control templates with which the editor
# is invoked on commit and import.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being made to, relative to the
# $CVSROOT. For the first match that is found, then the remainder of the
# line is the name of the file that contains the template.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".

@ -1,20 +0,0 @@
# The "taginfo" file is used to control pre-tag checks.
# The filter on the right is invoked with the following arguments:
#
# $1 -- tagname
# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
# $3 -- repository
# $4-> file revision [file revision ...]
#
# A non-zero exit of the filter program will cause the tag to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT. For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".

@ -1,21 +0,0 @@
# The "verifymsg" file is used to allow verification of logging
# information. It works best when a template (as specified in the
# rcsinfo file) is provided for the logging procedure. Given a
# template with locations for, a bug-id number, a list of people who
# reviewed the code before it can be checked in, and an external
# process to catalog the differences that were code reviewed, the
# following test can be applied to the code:
#
# Making sure that the entered bug-id number is correct.
# Validating that the code that was reviewed is indeed the code being
# checked in (using the bug-id number or a seperate review
# number to identify this particular code set.).
#
# If any of the above test failed, then the commit would be aborted.
#
# Actions such as mailing a copy of the report to each reviewer are
# better handled by an entry in the loginfo file.
#
# One thing that should be noted is the the ALL keyword is not
# supported. There can be only one entry that matches a given
# repository.

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

@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

@ -0,0 +1,525 @@
2007-07-31 Jochen Hoenicke <hoenicke@gmail.com>
* jode/bytecode/ClassInfo.java.in:
(readAttribute): Never read in known attributes as unknown
attributes. This could happen before when class was first read with
known info and then again with all info.
* jode/bytecode/MethodInfo.java: (readAttribute): Likewise.
* jode/bytecode/FieldInfo.java: (readAttribute): Likewise.
* jode/bytecode/BytecodeInfo.java.in: (readAttribute): Likewise.
* jode/obfuscator/ClassIdentifier.java: (doTransformation): Remove
all unknown attributes. They may contain references to
nonexisting constant pool entries.
* jode/obfuscator/PackageIdentifier.java: (loadClass): Fix a
compile time bug in the last patch.
2005-09-13 Jochen Hoenicke <jochen@gnu.org>
Check for NullPointer in SyntheticAnalyzer. Based on
patch suggessted by Peter Klauser (klp at users.sf.net).
* jode/jvm/SyntheticAnalyzer.java.in:
(checkStaticAccess): Check refField for null pointer.
(checkAccess): Likewise.
2005-09-13 Jochen Hoenicke <jochen@gnu.org>
Added patch from Peter Klauser (klp at users.sf.net), to support
packages with same name as classes in the obfuscator.
* jode/obfuscator/PackageIdentifier.java.in
(loadedPackages): New field, to store packages in separate map.
(getIdentifier): Renamed to...
(getClassIdentifier): ...this (and return only ClassIdentifier).
(setLoadOnDemand): Use loadedPackages.
(loadClass): Likewise.
(loadMatchingClass): Likewise.
(readTable): Likewise.
(getChilds): Likewise.
(contains): Likewise.
2003-06-11 Jochen Hoenicke <jochen@gnu.org>
Added patch from Thomas Oldervoll, to continue decompiling
after errors.
* jode/decompiler/Main.java (decompileClass): Handle all
exceptions and add names of failed classes to a vector.
(printSummary): New function.
(main): call printSummary.
2002-11-24 Jochen Hoenicke <jochen@gnu.org>
* jode/bytecode/ClassInfo.java.in (deprecatedFlag): Added flag
for deprecated classes. Stuart Ballard noticed that this was
missing.
(readAttribute): Read deprecated attribute.
(prepareWriting): Prepare deprecated attribute.
(writeKnownAttributes): Write deprecated attribute.
(isDeprected): New function.
(setDeprecated): Likewise.
2002-06-11 Jochen Hoenicke <jochen@gnu.org>
* configure.in: Set version number to 1.1.2.
* jode/bytecode/BytecodeInfo.java.in (readAttribute): Fix the
exception handlers that javac 1.4 produces: I simply shorten
the start/end interval, so that the catcher is not in the end
interval.
2002-02-25 Jochen Hoenicke <jochen@gnu.org>
* jode/bytecode/ClassInfo.java.in (read): Don't check for a
maximum version anymore. Sun changes it with every release without
changing the bytecode format.
2002-02-08 Jochen Hoenicke <jochen@gnu.org>
* jode/obfuscator/ClassIdentifier.java.in (transformInnerClasses):
Bug fix: Added missing checks for STRIP_UNREACH.
* jode/obfuscator/MethodIdentifier.java.in (doTransformation):
Don't run analyzer on unreachable methods. Previously the
ConstantAnalyzer assumed that the instructions are not reachable
and removed them all leading to illegal bytecode.
2002-02-01 Jochen Hoenicke <jochen@gnu.org>
* jode/flow/CreateAssignExpression.java (createAssignOp):
Bug fix: Check whether store is already a op-assign and break out.
* jode/expr/StoreInstruction.java (isOpAssign): New function to
check whether this is an op-assign.
2002-01-16 Jochen Hoenicke <jochen@gnu.org>
Fixes by anonymous for SerializePreserver:
* jode/obfuscator/ClassIdentifier.java.in (isSerializable):
The Serializable interface lives in java.io not in java.lang.
* jode/obfuscator/modules/SerializePreserver.java.in:
This class needs to implement OptionHandler.
2001-11-29 Jochen Hoenicke <jochen@gnu.org>
* jode/obfuscator/modules/MultiIdentifierMatcher.java.in
(getNextComponent): Fixed a (noncritical) bug, submitted
by Sergio (koker at users.sf.net).
2001-08-12 Jochen Hoenicke <jochen@gnu.org>
* configure.in: Set version number to 1.1.1.
2001-08-12 Jochen Hoenicke <jochen@gnu.org>
* jode/obfuscator/Identifier.java.in (writeTable): New boolean
parameter specifying if reversed or not.
* jode/obfuscator/ClassBundle.java.in: Renamed the table file
variables, added outTableFile.
(setOption): Support outtable, intable and outrevtable.
Support verbose.
(writeTable): Writes table unreversed.
(writeRevTable): New method, Writes table reversed.
* jode/obfuscator/Main.java.in: (rand): New variable.
* jode/obfuscator/PackageIdentifier.java.in: Use Main.rand instead
of definining its own random.
* jode/obfuscator/ClassIdentifier.java.in: likewise.
* jode/flow/FlowBlock.java.in:
(checkConsistent): Allow lastModified in a finally block.
* jode/flow/TransformExceptionHandlers.java.in: Reworked exception
handlers again. This time checked with javac 1.3, javac 1.1 and
jikes.
(checkTryCatchOrder): New method that was previously part of
analyze.
(analyze): Use checkTryCatchOrder. Don't merge try and catch flow
blocks anymore, leave it to the analyzeXXX methods.
(mergeTryCatch): New method.
(analyzeCatchBlock): Get catchFlow as parameter. Call
mergeTryCatch.
(transformSubroutine): Handle POP-only subroutines.
(removeJSR): Don't do special case for catchBlock any more. This
is because catchFlow isn't yet merged when this method is called.
(checkAndRemoveJSR): Likewise.
(checkAndRemoveMonitorExit): Likewise. Merge subroutine only if
we are the only predecessor.
(analyzeSynchronized): Get catchFlow as parameter. Call
mergeTryCatch.
(mergeFinallyBlocks): New method, calls mergeTryCatch and does the
common part of mergeFinally and mergeSpecialFinally.
(analyzeFinally): Simplified, after checking and removing JSR, it
does immediately analyze and transform subroutine to get the
finallyBlock. Then it throws away the catchFlow and calls
mergeFinallyBlocks.
(analyzeSpecialFinally): Simplified, after checking it only handles
the jumps in the try part and then call mergeFinallyBlocks.
2001-08-10 Jochen Hoenicke <jochen@gnu.org>
* configure.in: Changed bash syntax to more compatible (but
slower) syntax. Fixes bug #448909.
2001-08-09 Jochen Hoenicke <jochen@gnu.org>
* jode/expr/InvokeOperator.java.in (dumpExpression): Fixed the
check for null outerExpr.
2001-07-27 Jochen Hoenicke <jochen@gnu.org>
* jode/obfuscator/Main.java.in (stripping): Initialize to 0 which
means strip nothing. This is necessary because there is no way
to turn off stripping.
2001-07-11 Jochen Hoenicke <jochen@gnu.org>
* jode/flow/CatchBlock.java.in (combineLocal): Added more checks
if LocalStoreOperator is of the right form.
2001-07-10 Jochen Hoenicke <jochen@gnu.org>
* jode/obfuscator/modules/SimpleAnalyzer.java.in:
Ported fix from ConstantAnalyzer:
(canonizeReference): for interfaces call canonizeIfaceReference.
(canonizeIfaceReference): new method.
* jode/obfuscator/modules/ConstantAnalyzer.java.in:
made sub class of SimpleAnalyzer.
(canonizeReference): Removed, since its inherited.
(canonizeIfaceReference): dito.
2001-07-08 Jochen Hoenicke <jochen@gnu.org>
* jode/bytecode/BytecodeInfo.java.in (calculateMaxStack): Handle special case for empty method. Previous code would just crash.
2001-06-15 Jochen Hoenicke <jochen@gnu.org>
* jode/jvm/SyntheticAnalyzer.java.in:
(checkGetClass): Ignore nop opcodes.
(checkStaticAccess): Likewise.
(checkAccess): Likewise.
(checkConstructorAccess): Likewise.
* jode/flow/TransformConstructors.java (Constructor): Ignore
OuterValues for static constructor.
* jode/expr/NewArrayOperator.java (dumpExpression): Added
a missing breakOp.
* jode/expr/CompareToIntOperator.java (dumpExpression): Likewise.
2001-06-01 Jochen Hoenicke <jochen@gnu.org>
* jode/obfuscator/modules/ConstantAnalyzer.java.in:
(analyzeCode): set field listener of RuntimeEnvironment.
(replaceWith): Fixed the invoke_xxx case.
* jode/obfuscator/ConstantRuntimeEnvironment.java.in:
(getField): add current field listener to field if constant value
was used.
(currentFieldAnalyzer): New field.
(setFieldAnalyzer): New method.
2001-05-27 Jochen Hoenicke <jochen@gnu.org>
* configure.in: Set version to 1.1.
* jode/decompiler/Main.java (main): Also use bootclasspath if no
classpath given.
* jode/swingui/Main.java (main): Likewise.
* jode/decompiler/MethodAnalyzer.java.in (skipWriting): Don't skip
empty constructor that have a throws clause.
* configure.in: Determine whether jdk1.1 resp. jdk1.2. Call jcpp
in config.status.
* jode/expr/Expression.java.in (makeInitializer): Now takes the
type of the initialization. Changed all callers.
* jode/expr/ConstantArrayOperator.java (makeInitializer): Check
that type is our array type, otherwise we can't omit new Array[].
* jode/decompiler/LocalInfo.java (markFinal): Don't check that
only one write is present. If two writes are in an then and an
else branch of an if, the local can still be final.
* jode/type/ArrayType.java (getSubType): Handle array of integer
types correctly: byte[] is something completely different than
int[].
(getSuperType): Likewise.
* jode/expr/FieldOperator.java.in (getFieldInfo): New function.
(needsCast): A cast is also needed if the field is private or
package scope and the current type can't access the field.
* jode/expr/InvokeOperator.java.in (getMethodInfo): New function.
(needsCast): A cast is also needed if the method is private or
package scope and the current type can't access the method.
* jode/expr/ArrayStoreOperator.java (dumpExpression): Check if a
cast of the array expression is needed.
* jode/expr/TransformConstructors.java
(transformFieldInitializers): Don't allow moving method invocations
that throw a checked exception.
* jode/bytecode/MethodInfo.java (readAttribute): Read Exceptions
attribute even when not all attributes should be read. They are
needed by TransformConstructors, see above.
2001-05-26 Jochen Hoenicke <jochen@gnu.org>
* jode/decompiler/TabbedPrintWriter.java (saveOps): Don't allow
line breaks in not completed expressions since implicit parentheses
would destroy the syntax. No need to put line break option on stack.
(restoreOps): Adapted Stack format.
* jode/decompiler/ClassAnalyzer.java.in (dumpDeclaration): Moved
Code from dumpSource here. Don't put a line break after closing
brace.
(dumpSource): call dumpDeclaration and add a line break.
(dumpBlock): Moved dropInfo(ATTRIBS) here.
* jode/decompiler/ClassAnalyzer.java.in (STRICTFP): New Constant.
(isStrictFP): New function.
(initialize): Set strictfp modifier if a constructor has it set.
(dumpSource): Handle strictfp modifier.
* jode/decompiler/MethodAnalyzer.java.in (STRICTFP): New Constant.
(isStrictFP): New function.
(dumpSource): Handle strictfp modifier.
* jode/jvm/SyntheticAnalyzer.java.in (checkAccess): Check for a
special putfield access, where the set value is returned. Allow
the modifier of field/method to be protected and the class to be
a superclass.
(checkStaticAccess): Likewise.
(ACCESSDUPPUTFIELD): New Constant.
(ACCESSDUPPUTSTATIC): New Constant.
* jode/expr/InvokeOperator.java.in (simplifyAccess): Handle new
synthetics.
* jode/flow/SpecialBlock.java (removePop): Remove pop also for
non void store instructions.
* jode/decompiler/MethodAnalyzer.java.in (skipWriting): Also skip
the new synthetics.
* jode/decompiler/Main.java (main): Call System.exit() after
everything was compiled.
* jode/flow/TransformExceptionHandlers.java.in (removeJSR):
Renamed back from removeBadJSR (see patch from 2001-02-04). The
checkAndRemove* functions mustn't change the successors while they
iterate over them. Instead of removing good jsr they mark them as
good and removeJSR will finally remove them.
(checkAndRemoveJSR): See above.
(checkAndRemoveMonitorExit): See above.
* jode/flow/JsrBlock.java (good): New variable, see above.
(setGood): New method.
(isGood): New method.
2001-05-08 Jochen Hoenicke <jochen@gnu.org>
* jode/jvm/CodeVerifier.java.in (doVerify): Don't check for
uninitialized objects in local or stack slots on backwards jump or
exception blocks. Sun's jdk also doesn't check it, and I never
understood why it is necessary. But see JVM Spec 4.9.4.
2001-05-02 Jochen Hoenicke <jochen@gnu.org>
* jode/obfuscator/modules/ConstantAnalyzer.java.in (handleOpcode):
Added divide by zero checks for opc_irem and opc_lrem.
2001-04-11 Jochen Hoenicke <jochen@gnu.org>
* jode/type/ClassInterfacesType.java (keywords): Reworked keyword
list.
* jode/decompiler/OuterValues.java (implicitOuterClass): New field.
(isImplicitOuterClass): new Method.
(setImplicitOuterClass): new Method.
* jode/flow/TransformConstructors.java (checkAnonymousConstructor):
Check for implicitOuterClass, a new javac 1.3 construct.
* jode/expr/FieldOperator.java.in (dumpSource): Removed this
simplification nonesense. Now Outer.this is never printed as
this.
* jode/expr/InvokeOperator.java.in (dumpSource): Removed this
simplification nonesense. Now Outer.this is never printed as
this.
Handle implicitOuterClass.
2001-04-10 Jochen Hoenicke <jochen@gnu.org>
* jode/decompiler/Main.java (usage): Reworked usage message.
2001-04-09 Jochen Hoenicke <jochen@gnu.org>
* jode/bytecode/SearchPath.java: Bug fixes from Joe Bronkema:
(exists): Don't replace '/' with fileSeparator in original
filename; make a copy instead.
(getFile): likewise.
(isDirectory): likewise.
(listFiles): Reset fileNr when a new directory is read.
2001-02-28 Jochen Hoenicke <jochen@gnu.org>
* acinclude.m4 (JODE_CHECK_CLASS): Changed "test -e" to "-f" since
-e is not supported on all architectures (Solaris) and -f is more
correct anyway.
Reported by Erik Modén.
2001-02-27 Jochen Hoenicke <jochen@gnu.org>
* jode/swingui/Main.java.in (AreaWriter): Convert all kinds of
line breaks (CR+LF, CR, LF) to a LF character, which a JTextArea
understands.
2001-02-08 Jochen Hoenicke <jochen@gnu.org>
* jode/expr/StoreInstruction.java (dumpExpression): Java doesn't
allow parenthesis around left hand side, so use NO_PAREN and don't
call lhs.dumpExpression() with priority.
* jode/expr/PrePostFixOperator.java (dumpExpression): likewise.
* jode/expr/IIncOperator.java (dumpExpression): likewise.
* jode/flow/TransformConstructors.java (jikesAnonInner): Removed,
since it wasn't used: This information is stored in OuterValues
now.
* jode/decompiler/LocalInfo.java (isConstant): Always return true
so that inner classes that access final locals work, even if we
can't decide that the local can be final.
2001-02-05 Jochen Hoenicke <jochen@gnu.org>
* jode/expr/InvokeOperator.java.in (Environment.invokeMethod):
Fixed the call to ClassInfo.forName: it expects a class name, while
ref.getClazz() gives a type signature.
* jode/flow/TransformExceptionHandlers.java.in:
(checkAndRemoveJSR): Only invoke removeBadJSR, if there are
successors left.
(checkAndRemoveMonitorExit): likewise.
2001-02-04 Jochen Hoenicke <jochen@gnu.org>
* jode/expr/IfThenElseOperator.java (simplify): Allow in the class$
simplification the then and else part to be swapped.
* jode/bytecode/ClassInfo.java.in (read): Accept class version
1.3.
* jode/type/ClassInterfacesType.java (keywords): Added the package
and import keywords.
* jode/flow/TransformExceptionHandlers.java.in:
(getPredecessor): New function.
(getMonitorExitSlot): New function.
(skipFinExitChain): New function.
(removeJSR): Replaced by ...
(removeBadJSR): ... this.
(checkAndRemoveJSR): Use the new functions. Much simpler and
handles nested synchronized blocks. It now traces the whole JSR
and monitorexit chain before a jump to the first entry via
skipFinExitChain, then checks and remove the first JSR
resp. monitorexit. JSR jumps are simply ignored now.
(checkAndRemoveMonitorExit): likewise.
* jode/flow/StructuredBlock.java.in (prependBlock): New function.
* jode/flow/CatchBlock.java.in (makeDeclaration): Generate name
of dummyLocal, since nobody else will generate it.
2001-02-03 Jochen Hoenicke <jochen@gnu.org>
* jode/bytecode/BytecodeInfo.java.in (read): Remove bogus
exceptionHandlers, whose catchers just throw the exception again.
This kind of entries are inserted by an obfuscator and would break
JODE.
* jode/util/UnifyHash.java.in (iterateHashCode): Call cleanUp,
to clean unneeded references.
* jode/flow/TransformConstructors.java (transformOneField):
Changed to private. Take field number as parameter. Check that
expression doesn't contain a FieldOperator for a later field of
the same class or a PutFieldOperator. Changed all callers.
2001-02-01 Jochen Hoenicke <jochen@gnu.org>
* jode/jvm/CodeVerifier.java.in (Type.mergeType): If array elem
types can't be merged, return tObject as common super type.
* jode/type/ArrayType.java (getGeneralizedType): If array elem
type can't be intersected, return tObject as common super type.
* jode/flow/TransformExceptionHandlers.java.in: Merged patch from
the 1.2 tree to support javac 1.3 synchronized blocks. Doesn't
handle nested synchronized blocks yet.
* jode/expr/Expression.java.in (dumpExpression): Show runtime
exception when it occurs.
2001-01-31 Jochen Hoenicke <jochen@gnu.org>
* jode/expr/Expression.java.in (updateParentTypes): Call setType,
instead of merging the types. Other childs want to know about the
type change as well.
* jode/decompiler/LocalInfo.java (combineWith): Reorganized a bit,
but no changes.
* jode/expr/InvokeOperator.java.in (dumpExpression): Always print
the ThisOperator if a field is from a parent class of an outer
class is used. And always qualify the this operator if not
innermost.
2001-01-30 Jochen Hoenicke <jochen@gnu.org>
* jode/jvm/SyntheticAnalyzer.java.in (checkConstructorAccess):
Allow the special unifyParam to be the last parameter.
2001-01-30 Jochen Hoenicke <jochen@gnu.org>
* jode/decompiler/TabbedPrintWriter.java: Better gnu style handling:
(openBraceClass) (closeBraceClass)
(openBraceNoIndent) (closeBraceNoIndent): new functions.
(closeBraceNoSpace): Removed.
* jode/decompiler/Options.java (GNU_SPACING): new constant.
(GNU_STYLE): changed to include GNU_SPACING.
* jode/decompiler/ClassAnalyzer.java.in (dumpSource): Use
open/closeBraceClass.
* jode/decompiler/MethodAnalyzer.java.in (dumpSource): Use
open/closeBraceNoIndent. Insert a space for GNU_SPACING.
* jode/decompiler/InvokeOperator.java.in (dumpExpression): Insert
a space for GNU_SPACING, use open/closeBraceClass for inner
classes.
* jode/decompiler/UnaryOperator.java (dumpExpression): Insert
a space for GNU_SPACING.
2001-01-30 Jochen Hoenicke <jochen@gnu.org>
Added pascal style from Rolf Howarth <rolf@squarebox.co.uk>
* jode/decompiler/Options.java (PASCAL_STYLE): new constant.
(BRACE_FLUSH_LEFT): dito.
* jode/decompiler/Decompiler.java (setOption): detect pascal option.
* jode/decompiler/Main.java (main): dito.
* jode/decompiler/TabbedPrintWriter.java (openBrace,
openBraceContinue, closeBrace, closeBraceNoSpace,
closeBraceContinue): handle flush left.
2001-01-30 Jochen Hoenicke <jochen@gnu.org>
* jode/type/NullType.java (intersection): Removed, since the
version in ReferenceType is more correct. Before
tNull.isOfType(tRange(X,tNull)) returned false, which lead to
incorrect behaviour in InvokeOperator.needsCast.
* jode/decompiler/FieldAnalyzer.java.in (dumpSource): Removed the
"= null" hack for final fields; it was not correct, since the
field could be initialized in a constructor.
* jode/decompiler/TabbedPrintWriter.java (BreakPoint.endOp):
Simplified the code, copy options always from child.
* jode/jvm/SyntheticAnalyzer.java.in (unifyParam): new field.
(checkConstructorAccess): Allow the special Parameter, whose
purpose is to distinguish the wrapper from the real constructor
and give him a "$" in the type signature, to appear at every
position. It doesn't appear at position 1 for inner classes.
Store the position in unifyParam.
* jode/expr/InvokeOperator.java (isGetClass): Allow the method to
be declared inside an outer class: We simply check if we can get
the method analyzer.
(simplify): handle unifyParam.
* jode/expr/PopOperator.java (getBreakPenalty): return penalty of
inner expression. (dumpExpression): Call dumpExpression of
subexpression immediately without priority.

@ -1,12 +1,15 @@
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.
Before installing, make sure you have at least version 1.1 of the java
developement kit installed. If you want to run this program you only
need the java runtime environment. Version 1.1 is quite old, I
recommend using Java 2 (jdk1.2 or above).
This package was designed to use the GNU standard for configuration
and makefiles. To build and install do the following:
0). If you have downloaded the code from the CVS repository create
configure and Makefile.in with autoconf-2.13 and automake-1.4. Type
"aclocal; automake -a; autoconf".
1). You need a java development kit (at least version 1.1), some unix
tools and some java packages. Make sure that you have all java
packages that are needed in your classpath. This are gnu.getopt, and
@ -40,7 +43,3 @@ give a path to the directory where it resides, otherwise it is
searched in the path.
3). Type "make" to build the package.
4). Type "make install" to install the package. This doesn't work yet.
Jochen

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

@ -1,6 +1,10 @@
New in 1.0.94
New in 1.1.1
* Only bug fixes
New in 1.1
* break long lines
* small bug fixes
* handle most of javac v8 constructs (jdk 1.3)
* bug fixes
New in 1.0.93
* anonymous and inner class decompilation reworked.

@ -1,12 +1,17 @@
JODE (Java Optimize and Decompile Environment)
This is a decompiler and optimizer for java I have written in my spare
time. The decompiler 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 the java files were compiled with `-g') and
there are often more ways to write the same thing. But jode does its
job quite well.
JODE is a java package containing a decompiler and an optimizer for
java. This package is freely available under the GNU General Public
License.
The decompiler reads in class files 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 the java files were compiled with `-g') and there are often more
ways to write the same thing. However, jode does its job quite well.
The optimizer transforms class files in various ways with
can be controlled by a script file.
Please note that most software licenses forbid to decompile class
files. Use this decompiler only, if you have legal rights to
@ -25,6 +30,15 @@ The features of the decompilers are:
Known bugs of the decompiler:
- Some jdk1.3 synthetic access functions aren't understood. The
produced source contains access$xxx functions, but it still compiles.
- There may be other bugs, that cause Exceptions or invalid code.
If you have such a problems don't hesitate to issue a bug report.
Please include the <code>class</code> file if possible.
Limitations:
- If not all dependent classes can be found, the verifier (which is
run before decompilation starts) may exit with a type error. You
can decompile it with --verify=off, but take the warning serious,
@ -40,18 +54,6 @@ Known bugs of the decompiler:
happen when you compile with `-O' flag and javac has inlined some
methods.
- Sometimes this program may exit with an Exception or produce
incorrect code. If it produced incorrect code the code probably
can't be compiled, so that the error can be easily spotted. If you
have one of these problems (they are very rare now), I would be
very interested in a bug report (including the .class file, if
possible).
- Sometimes it generates some GOTO expression and labels. This
shouldn't happen any more with code produced by javac or jikes.
But some flow obfuscator likes Zelix Klassmaster may provoke this.
In that case you can run the Obfuscator first (to optimize away the
flow obfuscation ;-).
The features of the obfuscator are:
* Modular design, you can plug the obfuscation transformation you need
@ -66,62 +68,23 @@ The features of the obfuscator are:
PRELIMINARIES:
You need java jdk1.2 or above, and the gnu getopt package.
You should also have the jode-x.x.xx.jar file. Read INSTALL how to
compile it yourself.
Jode also works with jdk1.1, but you need the sun collection classes
and swing in that case.
Here are some URLs for the tools and packages you may need:
CYGWIN (unix tools for win95/NT):
http://sourceware.cygnus.com/cygwin/
JDK 1.1:
http://java.sun.com/products/jdk/1.1/index.htm
Collection classes and Swing for JDK 1.1:
http://java.sun.com/beans/infobus/#DOWNLOAD_COLLECTIONS
http://java.sun.com/products/jfc/index.html#download-swing
JDK 1.2:
http://java.sun.com/products/jdk/1.2/index.html
Getopt:
http://www.urbanophile.com/arenn/hacking/download.html#getopt
See INSTALL for installation instructions.
USAGE:
First set the classpath. It should contain the jar file
jode-x.x.xx.jar, the gnu getopt package and the sun collection package
for 1.1. For the swingui program you also need swing in you classpath.
First set the classpath. It should contain the jar file jode-1.1.jar,
the gnu getopt package and the sun collection package for 1.1. For
the swingui program you also need swing in you classpath.
You can then decompile a class file with:
java jode.decompiler.Main --classpath jarfile1.jar,jarfile2.jar org.package.Class
java jode.decompiler.Main --classpath program.jar,libfoo.jar org.package.Class
or a complete package with
java jode.decompiler.Main --classpath libfoo.jar program.jar
For a graphical user interface based on swing try:
java jode.swingui.Main --classpath jarfile1.jar
The obfuscator/deobfuscator can be run with:
The obfuscator/deobfuscator can be run with a script:
java jode.obfuscator.Main obfuscation.jos
See XXXX for more information about the script syntax.
HISTORY:
Someday I found guavad, a disassembler for java byte code (it does
similar things like `javap -c'). I used it on a class file, and found
that it was possible to reconstruct the original java code. First I
did it by hand on some small routines, but I soon realized that it was
a rather stupid task, and that I could write a perl script, that does
the same. At the end of the next day I had the first working
decompiler.
Now while it was working, it was not easy to use. You had to
decompile the code first with a disassembler, cut the method, you
wanted to decompile and then run the perl script on it. So I decided
to get some information of the class files and do this all
automatically. I decided to write it in java now, because it suited
best.
See the web documents for more information about the script syntax.

@ -0,0 +1,5 @@
Joe Bronkema <joseph.d.bronkema at lmco.com>
Rolf Howarth <rolf at squarebox.co.uk> for pascal indentaton style.
Erik Modén <Erik.Moden at emw.ericsson.se>
Martin Schmitz <m.schmitz at e-sign.com> for finding many bugs in the obfuscator.
zzzeek <classic at io.com>

@ -4,12 +4,13 @@ Decompiler:
- outline inlined methods.
- remove string decrypt method.
- remove synthetic methods if and only if all calls to them are resolved.
~ handle try catch more thouroughly/safely.
~ decompile jode.jvm.Interpreter (hand optimized bytecode)
Obfuscator:
- flow obfuscation/optimization.
- warn about Class.forName and list occurences.
- detect Class.forName on constant strings and handle appropriately.
- work around Class.forName, by creating a new version using a hash
table that maps md5 sums of old names to obfuscated names.
DeObfuscator:
- generate nice names:
@ -20,13 +21,15 @@ DeObfuscator:
User Interface:
- make a nice user interface:
~ list classnames: toggable between class hierarchie/package hierarchie.
- list fields/method of selected class.
- show decompilation of selected method.
- show only decompilation of selected method.
- show usage of method/fields.
- syntax highlighting, hyper links etc.
(look at java.swing.JEditorPane or at Java Insight)
- visual obfuscation/deobfuscation (like klassmaster?, better?)
Internal:
- clean up package hierarchy, esp. expr, flow and decompiler.
- clean up package hierarchy, esp. expr, flow and decompiler.
- move to net.sf.jode package.
- make the class names more precise, e.g. StructuredBlock is Statement,
FlowBlock is BasicBlock.

@ -28,7 +28,7 @@ AC_DEFUN(JODE_CHECK_CLASS,
myclasspath=$2;
for path in $myclasspath; do
if test -d $path; then
if test -e $path/$clazz; then
if test -f $path/$clazz; then
exit 0
fi
elif CLASS_CHECK $path $clazz ; then

@ -30,15 +30,30 @@ for (@ARGV) {
my $class = $1;
my $curyear = `date +%Y`;
chomp $curyear;
my $firstcheckin = `rlog $file 2>/dev/null |grep date| tail -1`;
my $firstyear =
($firstcheckin =~ m=date: ([0-9]+)/[0-9]+/[0-9]+=) ? $1 : $curyear;
# my $firstcheckin = `rlog $file 2>/dev/null |grep date| tail -1`;
# my $firstyear =
# ($firstcheckin =~ m=date: ([0-9]+)/[0-9]+/[0-9]+=) ? $1 : $curyear;
# my $lastcheckin = `rlog $file 2>/dev/null |grep date| head -1`;
# my $lastyear =
# ($firstcheckin =~ m=date: ([0-9]+)/[0-9]+/[0-9]+=) ? $1 : $curyear;
open FILE, "<$file";
while (<FILE>) {
$firstyear = $1 if /Copyright \(C\) (\d{4})/;
last if /^package/;
}
$firstyear = $curyear if ! $firstyear;
my $lastyear = $curyear;
my $years = ($firstyear == $lastyear)
? $firstyear : "$firstyear-$lastyear";
my $lesser = "";
my $dotlesser = "";
if ($file =~ m!jode/(util|bytecode|jvm|flow|expr|decompiler
|GlobalOptions|AssertError)!x) {
$lesser = " Lesser";
$dotlesser = ".LESSER";
}
rename "$file", "$file.orig" or do {
print STDERR "Can't open file $file\n";
@ -50,7 +65,7 @@ for (@ARGV) {
/* $class Copyright (C) $years 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
* it under the terms of the GNU$lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -59,8 +74,8 @@ for (@ARGV) {
* 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
* You should have received a copy of the GNU$lesser General Public License
* along with this program; see the file COPYING$dotlesser. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* \$Id\$

@ -1,18 +1,10 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT()
AM_INIT_AUTOMAKE(jode, 1.0.93)
AM_INIT_AUTOMAKE(jode, 1.1.2)
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(PERL, perl)
AC_PATH_PROG(CYGPATH, cygpath)
@ -78,7 +70,7 @@ 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
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
@ -114,6 +106,13 @@ JODE_CHECK_CLASS(java.lang.Object, $CLASSLIB,
[ AC_MSG_RESULT(no)
AC_MSG_ERROR(Please specify location of core java class library) ])
AC_MSG_CHECKING(for java.lang.ref.WeakReference)
JODE_CHECK_CLASS(java.lang.ref.WeakReference, $CLASSLIB,
[ AC_MSG_RESULT(yes)
JCPPFLAGS="-DJDK12" ],
[ AC_MSG_RESULT(no)
JCPPFLAGS="-DJDK11" ])
AC_MSG_CHECKING(for collection classes)
JODE_CHECK_CLASS(java.util.Set, $CLASSPATH:$CLASSLIB,
[ COLLECTIONS="java.util"
@ -240,6 +239,6 @@ bin/Makefile
bin/jode
bin/jode.bat
doc/Makefile
doc/download.html
test/Makefile,
[chmod 755 javaDependencies.pl bin/jode])
[chmod 755 javaDependencies.pl bin/jode],
[$PERL $srcdir/jcpp $JCPPFLAGS \`ls \$CONFIG_FILES | grep '.java\$'\`])

@ -1,2 +1,3 @@
Makefile
Makefile.in
*.html

@ -1,14 +1,46 @@
## Input file for automake to generate the Makefile.in used by configure
EXTRA_DIST = \
applet.html \
download.html.in \
history.html \
jode.html \
license.html \
links.html \
usage.html \
PHP_FILES = \
applet.php \
bluesky.php \
download.php \
faq.php \
feedback.php \
history.php \
index.php \
license.php \
links.php \
usage.php
HTML_FILES = $(PHP_FILES:%.php=$(srcdir)/%.html)
# noinst_DATA = $(HTML_FILES)
EXTRA_DIST = $(PHP_FILES) $(notdir $(HTML_FILES)) \
header.inc \
menu.inc \
footer.inc \
a-logo.gif \
myproject.jos \
dasm_to_java.perl \
gimp/jode-logo.xcf \
jode-logo.gif
.PHONY: public_html_symlink
# The following rules require that you have an apache with php on
# localhost with standard user public_html directories and
# FollowSymLink enabled.
PUBLIC_HTML=$(HOME)/public_html
JODE_PHP_DIR=jode_php
public_html_symlink:
rm -f $(PUBLIC_HTML)/$(JODE_PHP_DIR)
@RELDIR=`pwd | sed s!^$(HOME)!..!`; \
ln -sf $$RELDIR/$(srcdir) $(PUBLIC_HTML)/$(JODE_PHP_DIR); \
echo Created symlink to $$RELDIR/$(srcdir).
footer.inc: public_html_symlink
$(srcdir)/%.html: %.php footer.inc header.inc menu.inc
lynx -source http://localhost/~$(LOGNAME)/$(JODE_PHP_DIR)/$(notdir $<)?extension=html > $@

Binary file not shown.

After

Width:  |  Height:  |  Size: 894 B

@ -1,97 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
<html>
<head>
<title>Java Optimize and Decompile Environment (JODE)</title>
<meta name="date" content="2000-06-30">
<meta name="description" content="JODE - Java Optimize and Decompile Environment.">
<meta name="author" content="Jochen Hoenicke">
<meta name="keywords" content="jode, java, decompiler, obfuscator, deobfuscator, reverse engineering, free, GPL">
</head>
<BODY bgcolor=#FFFFFF topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" marginheight="0" marginwidth="0">
<table cellpadding=4 cellspacing=1 width=100%>
<tr><td>
</td>
<td> <img src="jode-logo.gif" alt="JODE" width=286 height=110></td>
</tr>
<tr>
<td valign="top">
<table cellspacing=0 cellpadding=3 width=100% border=0 bgcolor=eeeef8>
<tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Jode</b></font></td></tr>
<tr><td align="right">
<a href="./"><B>Home</B></a><br>
<a href="http://sourceforge.net/project/?group_id=3790">Project&nbsp;page</a><br>
<br>
<a href="./applet.html">Applet</a><br>
<a href="./download.html">Download</a><br>
<a href="./usage.html">Documentation</a><br>
<a href="./license.html">License</a><br>
<a href="./history.html">History</a><br>
<a href="./links.html">Links</a><br>
<a href="./bluesky.html">Blue&nbsp;Sky</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Feedback</b></font></td></tr>
<tr><td align="right">
<a href="http://sourceforge.net/bugs/?group_id=3790">Bug&nbsp;Tracking</a><br>
<a href="http://sourceforge.net/forum/?group_id=3790">Public&nbsp;Forums</a><br>
<a href="http://lists.sourceforge.net/mailman/listinfo/jode-users">Mailing&nbsp;List</a><br>
<a href="http://sourceforge.net/sendmessage.html?touser=18252">Private&nbsp;Mail</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Download</b></font></td></tr>
<tr><td align="right">
<a href="ftp://jode.sourceforge.net/pub/jode/">FTP&nbsp;server</a><br>
<a href="http://sourceforge.net/project/filelist.html?group_id=3790">Source&nbsp;releases</a></td></tr>
<tr bgcolor="ffffff"><td align="center"><br>Powered by <br>
<a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.html?group_id=3790&type=1" border=0 width=88 height=31 alt="SourceForge"></a><br>
<br>Best viewed with <br>
<a href="http://www.anybrowser.org/campaign/"><img src="a-logo.gif" border=0 width=88 height=31 alt="Any Browser"></a><br>
</td></tr></table>
</td>
<td valign="top">
<h1>The <i>JODE</i> Applet</h1>
Please be patience, loading the applet may take some time.<br><br>
<center>
<applet code="jode/Applet.class" archive="jode-applet.jar" width=540 height=400>
<param name=pagecolor value="ffffff">
<param name=classpath value="http://jode.sourceforge.net/load.html/http%3a//www.informatik.uni-oldenburg.de/~mw/plasma.jar">
<param name=class value="PlasmaApplet">
<p>Sorry you need a java enabled browser to test a java applet ;-)</p>
<p>Don't read the rest, it only contains information about the applet.</p>
</applet>
</center><br>
Press the start button to decompile <a
href="http://www.informatik.uni-oldenburg.de/~mw/plasma.html">Michael's
Plasma applet</a> (and give the decompiler some time to download the
jar file). <br><br>
You may change the classpath to point to a zip or jar file of your
choice, using a similar syntax. Use <code>%3a</code> instead of a
colon `:' in the url. You can also point it to a directory containing
the class-files (include a slash `/' at the end in this case), but
this is not recommended, since it is <i>very</i> slow. You may give
multiple entries in the class path field separated by a comma.<br><br>
You can't use this applet for local files; the class files must be on
a server that is accessible from sourceforge. You can try to give
local filenames directly without the load.html wrapper, but that is
probably forbidden by your browser. Most browser only allow loading
files from the same server as the applet, and this is the reason why
you have to use such a cryptic URL.<br><br>
Save probably doesn't work, because it is forbidden by your browser.<br><br>
</td></tr>
</table>
<TABLE width="100%" border="0" cellspacing="0" cellpadding="2" bgcolor="737b9c">
<TR>
<TD align="center"><FONT color="#ffffff"><SPAN class="titlebar">
All trademarks and copyrights on this page are properties of their respective owners. <br>
Last updated on 8-May-2000,
Copyright &copy; 1998-2000 by Jochen Hoenicke.</SPAN></FONT>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>

@ -1,36 +1,38 @@
<?php require("header.inc"); ?>
<h1>The <i>JODE</i> Applet</h1>
Please be patience, loading the applet may take some time.<br><br>
<p>Please be patience, loading the applet may take some time.</p>
<center>
<applet code="jode/Applet.class" archive="jode-applet.jar" width=540 height=400>
<param name=pagecolor value="ffffff">
<param name=classpath value="http://jode.sourceforge.net/load.php/http%3a//www.informatik.uni-oldenburg.de/~mw/plasma.jar">
<param name=classpath value="http://jode.sourceforge.net/http/www.informatik.uni-oldenburg.de/~mw/plasma.jar">
<param name=class value="PlasmaApplet">
<p>Sorry you need a java enabled browser to test a java applet ;-)</p>
<p>Don't read the rest, it only contains information about the applet.</p>
</applet>
</center><br>
Press the start button to decompile <a
<p> Press the start button to decompile <a
href="http://www.informatik.uni-oldenburg.de/~mw/plasma.html">Michael's
Plasma applet</a> (and give the decompiler some time to download the
jar file). <br><br>
jar file). </p>
You may change the classpath to point to a zip or jar file of your
choice, using a similar syntax. Use <code>%3a</code> instead of a
colon `:' in the url. You can also point it to a directory containing
choice, using a similar syntax. Only http and ftp addresses are supported.
The file must be available from the world wide web. In fact you download it
from Sourceforge and Sourceforge gets it from the given address. This hack
is necessary, because Java's security policy doesn't allow applets to contact
a different server. You can also point the classpath to a directory containing
the class-files (include a slash `/' at the end in this case), but
this is not recommended, since it is <i>very</i> slow. You may give
multiple entries in the class path field separated by a comma.<br><br>
You can't use this applet for local files; the class files must be on
a server that is accessible from sourceforge. You can try to give
local filenames directly without the load.php wrapper, but that is
You can't use this applet for local files. You can try to give
local filenames directly without going through Sourceforge, but that is
probably forbidden by your browser. Most browser only allow loading
files from the same server as the applet, and this is the reason why
you have to use such a cryptic URL.<br><br>
you have to use such a weird URL.<br><br>
Save probably doesn't work, because it is forbidden by your browser.<br><br>
<?php require("footer.inc"); ?>

@ -1,133 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
<html>
<head>
<title>Java Optimize and Decompile Environment (JODE)</title>
<meta name="date" content="2000-06-30">
<meta name="description" content="JODE - Java Optimize and Decompile Environment.">
<meta name="author" content="Jochen Hoenicke">
<meta name="keywords" content="jode, java, decompiler, obfuscator, deobfuscator, reverse engineering, free, GPL">
</head>
<BODY bgcolor=#FFFFFF topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" marginheight="0" marginwidth="0">
<table cellpadding=4 cellspacing=1 width=100%>
<tr><td>
</td>
<td> <img src="jode-logo.gif" alt="JODE" width=286 height=110></td>
</tr>
<tr>
<td valign="top">
<table cellspacing=0 cellpadding=3 width=100% border=0 bgcolor=eeeef8>
<tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Jode</b></font></td></tr>
<tr><td align="right">
<a href="./"><B>Home</B></a><br>
<a href="http://sourceforge.net/project/?group_id=3790">Project&nbsp;page</a><br>
<br>
<a href="./applet.html">Applet</a><br>
<a href="./download.html">Download</a><br>
<a href="./usage.html">Documentation</a><br>
<a href="./license.html">License</a><br>
<a href="./history.html">History</a><br>
<a href="./links.html">Links</a><br>
<a href="./bluesky.html">Blue&nbsp;Sky</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Feedback</b></font></td></tr>
<tr><td align="right">
<a href="http://sourceforge.net/bugs/?group_id=3790">Bug&nbsp;Tracking</a><br>
<a href="http://sourceforge.net/forum/?group_id=3790">Public&nbsp;Forums</a><br>
<a href="http://lists.sourceforge.net/mailman/listinfo/jode-users">Mailing&nbsp;List</a><br>
<a href="http://sourceforge.net/sendmessage.html?touser=18252">Private&nbsp;Mail</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Download</b></font></td></tr>
<tr><td align="right">
<a href="ftp://jode.sourceforge.net/pub/jode/">FTP&nbsp;server</a><br>
<a href="http://sourceforge.net/project/filelist.html?group_id=3790">Source&nbsp;releases</a></td></tr>
<tr bgcolor="ffffff"><td align="center"><br>Powered by <br>
<a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.html?group_id=3790&type=1" border=0 width=88 height=31 alt="SourceForge"></a><br>
<br>Best viewed with <br>
<a href="http://www.anybrowser.org/campaign/"><img src="a-logo.gif" border=0 width=88 height=31 alt="Any Browser"></a><br>
</td></tr></table>
</td>
<td valign="top">
<h1>Blue Sky</h1>
<p>This section contains features that I think would be great to have,
but are also very hard to implement. The name of the section is
inspired, by <a
href="http://www.mozilla.org/blue-sky/">Mozilla</a>.</p>
<p>Currently this are all my own ideas. But if you send me an idea
for an interesting feature, I will add it to this list.</p>
<h2><i>Out</i>line inlined methods</h2>
<p>If java gets called with `<code>-O</code>' switch, it inlines methods,
that are private, final, or static and contain no loops. When
decompiling this it sometimes produces really ugly code. The right
way to solve this would be to <i>out</i>line the code again. This is
possible but requires to find the inlined method. </p>
<p>The name `outline' was suggested by <a
href="http://www.informatik.uni-oldenburg.de/~mw">Michael</a>.
</p>
<h2>Better names of local variables</h2>
<p>The local variable naming is very stupid. Even with pretty it just
names the variable after the type with a unifying number appended. A
method containing very much objects of the same type looks very
ugly. </p>
<p>My plan is looking at the assignments. If we have locals in
assignments
<pre>
int l_1 = array.length
String l_2 = object.getName()
</pre>
we could name them "length" and "name". If we
have assignments:
<pre>
MenuItem local_1 = new MenuItem("Open");
MenuItem local_2 = new MenuItem("Save");
</pre>
good names would be <code>miOpen</code> and <code>miSave</code>. </p>
<p>It is currently possible to assign a <i>(hint name,type)</i> pair
to a local. If the type matches, the local will be named after
<i>hint name</i>. This could be extended by giving them several
weighted hints and constructing the name in an intelligent way. </p>
<h2>Better deobfuscation features</h2>
<p>First there should be a good Renamer: Methods that simply
return a field value should be renamed to get<i>FieldName</i>.
Fields should be named after their type, maybe also by assignments
(see section about local variable names).</p>
<p>The deobfuscator should detect inner and anonymous variables,
synthetic methods and so on, and rename them accordingly.</p>
<h2>Handling of Class.forName in obfuscator</h2>
<p>The obfuscator should detect Class.forName constructs (and
similarly for methods and fields) and if their parameters are constant
it should change the parameter according to the rename function. </p>
<h2>Merging javadoc comments</h2>
<p>It would be nice if the decompiler could merge the javadoc comments
into the class file. More and more people use javadoc to comment the
public api of their java classes. It shouldn't be too difficult to
copy them back into the java code. </p>
<p>This doesn't need to be built into the decompiler. A script that takes
the javadoc pages and the decompiled code can easily merge them.</p>
</td></tr>
</table>
<TABLE width="100%" border="0" cellspacing="0" cellpadding="2" bgcolor="737b9c">
<TR>
<TD align="center"><FONT color="#ffffff"><SPAN class="titlebar">
All trademarks and copyrights on this page are properties of their respective owners. <br>
Last updated on 8-May-2000,
Copyright &copy; 1998-2000 by Jochen Hoenicke.</SPAN></FONT>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>

@ -1,92 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
<html>
<head>
<title>Java Optimize and Decompile Environment (JODE)</title>
<meta name="date" content="2000-06-30">
<meta name="description" content="JODE - Java Optimize and Decompile Environment.">
<meta name="author" content="Jochen Hoenicke">
<meta name="keywords" content="jode, java, decompiler, obfuscator, deobfuscator, reverse engineering, free, GPL">
</head>
<BODY bgcolor=#FFFFFF topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" marginheight="0" marginwidth="0">
<table cellpadding=4 cellspacing=1 width=100%>
<tr><td>
</td>
<td> <img src="jode-logo.gif" alt="JODE" width=286 height=110></td>
</tr>
<tr>
<td valign="top">
<table cellspacing=0 cellpadding=3 width=100% border=0 bgcolor=eeeef8>
<tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Jode</b></font></td></tr>
<tr><td align="right">
<a href="./"><B>Home</B></a><br>
<a href="http://sourceforge.net/project/?group_id=3790">Project&nbsp;page</a><br>
<br>
<a href="./applet.html">Applet</a><br>
<a href="./download.html">Download</a><br>
<a href="./usage.html">Documentation</a><br>
<a href="./license.html">License</a><br>
<a href="./history.html">History</a><br>
<a href="./links.html">Links</a><br>
<a href="./bluesky.html">Blue&nbsp;Sky</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Feedback</b></font></td></tr>
<tr><td align="right">
<a href="http://sourceforge.net/bugs/?group_id=3790">Bug&nbsp;Tracking</a><br>
<a href="http://sourceforge.net/forum/?group_id=3790">Public&nbsp;Forums</a><br>
<a href="http://lists.sourceforge.net/mailman/listinfo/jode-users">Mailing&nbsp;List</a><br>
<a href="http://sourceforge.net/sendmessage.html?touser=18252">Private&nbsp;Mail</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Download</b></font></td></tr>
<tr><td align="right">
<a href="ftp://jode.sourceforge.net/pub/jode/">FTP&nbsp;server</a><br>
<a href="http://sourceforge.net/project/filelist.html?group_id=3790">Source&nbsp;releases</a></td></tr>
<tr bgcolor="ffffff"><td align="center"><br>Powered by <br>
<a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.html?group_id=3790&type=1" border=0 width=88 height=31 alt="SourceForge"></a><br>
<br>Best viewed with <br>
<a href="http://www.anybrowser.org/campaign/"><img src="a-logo.gif" border=0 width=88 height=31 alt="Any Browser"></a><br>
</td></tr></table>
</td>
<td valign="top">
<h2>Download</h2>
The latest source code of <i>JODE</i> is available at the <a href="http://sourceforge.net/project/?group_id=3790">project page</a>.
You need several other packages to build <i>JODE</i>, check the <a href="./links.html">links page</a>. <br><br>
The simplest way to get it, especially for non unix users, is in
precompiled form, though. I have two jar archives at the <a
href="ftp://jode.sourceforge.net/pub/jode">ftp server</a>. You may
need to press shift while clicking on the link, depending on your
browser.
<ul> <li><a href="ftp://jode.sourceforge.net/pub/jode/jode-1.0.93-1.1.jar">jode-1.0.93-1.1.jar</a> is for JDK&nbsp;1.1. It already
contains Getopt and the collection classes from the GNU Classpath
project. If you want to use the swing interface, you have to download
swing separately. </li>
<li> <a href="ftp://jode.sourceforge.net/pub/jode/jode-1.0.93-1.2.jar">jode-1.0.93-1.2.jar</a> is for JDK&nbsp;1.2. It already
contains Getopt, so you don't need any other package.</li> </ul>
<h2>CVS Repository</h2>
You can get the latest sources from the <a href="http://sourceforge.net/cvs/?group_id=3790">CVS repository</a>.
Follow the instruction on that page; use <code>jode</code> as
<i>modulename</i>. Then change to the directory jode and run
<pre>aclocal && automake -a && autoconf</pre>
Afterwards follow the instruction in the INSTALL file.
</td></tr>
</table>
<TABLE width="100%" border="0" cellspacing="0" cellpadding="2" bgcolor="737b9c">
<TR>
<TD align="center"><FONT color="#ffffff"><SPAN class="titlebar">
All trademarks and copyrights on this page are properties of their respective owners. <br>
Last updated on 8-May-2000,
Copyright &copy; 1998-2000 by Jochen Hoenicke.</SPAN></FONT>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>

@ -1,40 +1,40 @@
<?php require("header.inc"); ?>
<h2>Download</h2>
<h1>Download</h1>
The latest source code of <i>JODE</i> is available at the <?php
sflink("project/") ?>project page</a>.
You need several other packages to build <i>JODE</i>, check the <?php
selflink("links") ?>links page</a>. <br><br>
<p>Jode is available in the <?
sflink("project/showfiles.php")?>download area</a> in source or
binary form. For compiling the source code, you need several other
packages, check the <?php selflink("links") ?>links page</a>. You
need a unix like environment for compilation.</p>
The simplest way to get it, especially for non unix users, is in
precompiled form, though. I have two jar archives at the <a
href="ftp://jode.sourceforge.net/pub/jode">ftp server</a>. You may
need to press shift while clicking on the link, depending on your
browser.
<p>The simplest way to get it, especially for non unix users, is in
precompiled form, though. There are two jar archives in the download
area:</P>
<?php
function jarlink($what) {
global $version;
echo "<a href=\"ftp://jode.sourceforge.net/pub/jode/jode-".$version.$what;
echo ".jar\">jode-".$version.$what.".jar</a>";
} ?>
<ul> <li>jode-1.1-JDK1.1.jar is for JDK&nbsp;1.1. If you want to use
the swing interface, you have to download swing separately, all other
packages are already included in the archive. </li>
<ul> <li><?php jarlink("-1.1") ?> is for JDK&nbsp;1.1. It already
contains Getopt and the collection classes from the GNU Classpath
project. If you want to use the swing interface, you have to download
swing separately. </li>
<li>jode-1.1.jar is for JDK&nbsp;1.2 or better. It should run
without any other package.</li> </ul> </p>
<li> <?php jarlink("-1.2") ?> is for JDK&nbsp;1.2. It already
contains Getopt, so you don't need any other package.</li> </ul>
<h1>CVS Repository</h1>
<h2>CVS Repository</h2>
<p>You can get the latest sources from the <?php sflink("cvs/") ?> CVS
repository</a>. Follow the instruction on that page; use
<code>jode</code> as <i>modulename</i>. If you want to checkout a
specific version you can use the <code>-r</code> option:</p>
You can get the latest sources from the <?php sflink("cvs/") ?>
CVS repository</a>.
Follow the instruction on that page; use <code>jode</code> as
<i>modulename</i>. Then change to the directory jode and run
<ul>
<li><code>-r jode_1_0_93</code>: checks out the version 1.0.93</li>
<li><code>-r branch_1_1</code>: checks out the latest version in the
1.1 series.</li> </ul>
<p>To build the sources from CVS change to the main directory where
the <code>configure.in</code> file resides and run
<pre>aclocal && automake -a && autoconf</pre>
Afterwards follow the instruction in the INSTALL file.
Afterwards follow the instruction in the INSTALL file. </p>
<?php require("footer.inc"); ?>

@ -0,0 +1,72 @@
<?php require("header.inc"); ?>
<h1>FAQ - Frequently Asked Questions</h1>
This is a list of some questions that pop up from time to time.
<h2>Decompiler issues</h2>
<h3>The decompiler crashes with a VerifyException, what can I do?</h3>
<p>The class isn't verifiable, probably because there is not enough
information about used classes. See the question about the
classpath.</p>
<p>This could also be caused by malicious bytecode, or because there
is a bug in Jode's verifier.</p>
<h3>What should be included in the classpath?</h3>
<p>Jode needs to know the full class hierarchie to guess the types.
This includes not only the classes in the program, but also the
libraries used by the java program, even the Java runtime library.
You should set the classpath to include all these classes.</p>
<p>If you don't specify the classpath on the command line, Jode uses
the same as your Java Virtual Machine.</p>
<p>As last resort, if Jode can't find a class in the classpath it uses
reflection to ask the Virtual Machine. This works quite well, but
loading classes can have side effects, e.g. when AWT classes are
loaded, an AWT thread is created, even though Jode doesn't need
it.</p>
<h3>Why doesn't Jode decompile my inner class
<code>MyClass$Inner.class</code>?</h3>
<p>You should decompile the outermost class (<code>MyClass</code> in
this case). The produced code contains the inner class. </p>
<h2>Obfuscator issues</h2>
<h3>What should be included in the classpath?</h3>
<p>The program, all libraries, the Java runtime library. Don't omit a
library even when you don't want to obfuscate it.</p>
<h3>What should I preserve</h3>
<p>The most common mistake is to preserve a class. In most cases this
is not what you want. This only makes sure the class won't be
renamed, it doesn't prevent it from being stripped. Instead you
should preserve methods and constructors. The constructor is just a
method with the special name <tt>&lt;init&rt;</tt>. </p>
<p> Another common mistake is to omit the type
signature, e.g. to preserve <tt>Class.main</tt> instead of
<tt>Class.main.([Ljava/lang/String;)V</tt>. That doesn't work. If
you don't want to care about the format of the type signature use a
wildcard as in <tt>Class.main.*</tt>. </p>
<h3>What is a type signature</h3>
<p>The type signature is a machine readable representation of a java
type that is used all over in java bytecode. The JDK ships a command
named <tt>javap</tt>. With <tt>java -s</tt> you can lists the fields
and methods of a class with their type signatures.</p>
<p> If you are interested in the format of type signatures read the
Java Virtual Machine Specification, Chapter 4.3 Descriptors</p>
<?php require("footer.inc"); ?>

@ -0,0 +1,14 @@
<?php require("header.inc"); ?>
<h1>Feedback</h1>
<p>You can report bugs to the <?php sflink("bugs/")?>bug forum</a>. </p>
<p>You can contact me by email via <a
href="http://sourceforge.net/sendmessage.php?touser=18252">hoenicke at
users.sourceforge.net</a>. Please mention <i>jode</i> in the
subject.</p>
<p>There is a mailing list. Check <a href="http://lists.sourceforge.net/mailman/listinfo/jode-users">this page</a> for subscription informations.</p>
<?php require("footer.inc"); ?>

@ -1,11 +1,10 @@
</td></tr>
</table>
<TABLE width="100%" border="0" cellspacing="0" cellpadding="2" bgcolor="737b9c">
<TABLE class=footer width="100%" border="0" cellspacing="0" cellpadding="2">
<TR>
<TD align="center"><FONT color="#ffffff"><SPAN class="titlebar">
<TD align="center"><SPAN class=footer>
All trademarks and copyrights on this page are properties of their respective owners. <br>
Last updated on 30-Jun-2000,
Copyright &copy; 1998-2000 by Jochen Hoenicke.</SPAN></FONT>
Last updated on 29-May-2001,
Copyright &copy; 1998-2001 by Jochen Hoenicke.
Canonic URL is <a class=boldlink href="http://jode.sourceforge.net/">http://jode.sourceforge.net/</a></SPAN>
</TD>
</TR>
</TABLE>

@ -1,13 +1,17 @@
<?php
$version="1.0.93";
if (! $extension) {
$extension = "php";
}
$version="1.1";
function selflink($link) {
global $extension;
echo "<a href=\"./";
if ($link != "jode") {
if ($link != "index") {
if (ereg("#", $link)) {
$link = ereg_replace("#", ".php#", $link);
$link = ereg_replace("#", ".$extension#", $link);
} else {
$link .= ".php";
$link .= ".$extension";
}
echo "$link";
}
@ -21,22 +25,39 @@ function sflink($link) {
<html>
<head>
<title>Java Optimize and Decompile Environment (JODE)</title>
<meta name="date" content="2000-06-30">
<meta name="date" content="2001-05-29">
<meta name="description" content="JODE - Java Optimize and Decompile Environment.">
<meta name="author" content="Jochen Hoenicke">
<meta name="keywords" content="jode, java, decompiler, obfuscator, deobfuscator, reverse engineering, free, GPL">
<style type="text/css">
<!--
body { color:#000000; background-color: #FFFFFF; }
.nav { font-family: Helvetica, Arial, sans-serif; font-weight: bold;
color:#000000; background-color: #EEEEF8; }
.footer { color:#FFFFFF; background-color: #737B9C; }
.boldlink { font-weight:bold; text-decoration: none; color:#FFFFFF; }
//-->
</style>
</head>
<BODY bgcolor=#FFFFFF topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" marginheight="0" marginwidth="0">
<table cellpadding=4 cellspacing=1 width=100%>
<tr><td>
<?php /* <CENTER><img src="constructionint.gif" alt="Under Construction, "><br>
beware broken links</CENTER> */ ?>
</td>
<td> <img src="jode-logo.gif" alt="JODE" width=286 height=110></td>
</tr>
<tr>
<td valign="top">
<body text=#000000 bgcolor=#FFFFFF>
<table cellpadding=4 cellspacing=1 width="100%"
><tr
><td align="left"
><img src="jode-logo.gif" alt="JODE" width=286 height=110
></td
><td align="right"
>Powered by <a href="http://sourceforge.net"><img
src="http://sourceforge.net/sflogo.php?group_id=3790&type=1"
border=0 width=88 height=31 alt="SourceForge"></a><br
>Best viewed with <a
href="http://www.anybrowser.org/campaign/"><img
src="a-logo.gif" border=0 width=88 height=31 alt="Any
Browser"></a><br
></td
></tr
></table>
<?php require("menu.inc"); ?>
</td>
<td valign="top">

@ -1,84 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
<html>
<head>
<title>Java Optimize and Decompile Environment (JODE)</title>
<meta name="date" content="2000-06-30">
<meta name="description" content="JODE - Java Optimize and Decompile Environment.">
<meta name="author" content="Jochen Hoenicke">
<meta name="keywords" content="jode, java, decompiler, obfuscator, deobfuscator, reverse engineering, free, GPL">
</head>
<BODY bgcolor=#FFFFFF topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" marginheight="0" marginwidth="0">
<table cellpadding=4 cellspacing=1 width=100%>
<tr><td>
</td>
<td> <img src="jode-logo.gif" alt="JODE" width=286 height=110></td>
</tr>
<tr>
<td valign="top">
<table cellspacing=0 cellpadding=3 width=100% border=0 bgcolor=eeeef8>
<tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Jode</b></font></td></tr>
<tr><td align="right">
<a href="./"><B>Home</B></a><br>
<a href="http://sourceforge.net/project/?group_id=3790">Project&nbsp;page</a><br>
<br>
<a href="./applet.html">Applet</a><br>
<a href="./download.html">Download</a><br>
<a href="./usage.html">Documentation</a><br>
<a href="./license.html">License</a><br>
<a href="./history.html">History</a><br>
<a href="./links.html">Links</a><br>
<a href="./bluesky.html">Blue&nbsp;Sky</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Feedback</b></font></td></tr>
<tr><td align="right">
<a href="http://sourceforge.net/bugs/?group_id=3790">Bug&nbsp;Tracking</a><br>
<a href="http://sourceforge.net/forum/?group_id=3790">Public&nbsp;Forums</a><br>
<a href="http://lists.sourceforge.net/mailman/listinfo/jode-users">Mailing&nbsp;List</a><br>
<a href="http://sourceforge.net/sendmessage.html?touser=18252">Private&nbsp;Mail</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Download</b></font></td></tr>
<tr><td align="right">
<a href="ftp://jode.sourceforge.net/pub/jode/">FTP&nbsp;server</a><br>
<a href="http://sourceforge.net/project/filelist.html?group_id=3790">Source&nbsp;releases</a></td></tr>
<tr bgcolor="ffffff"><td align="center"><br>Powered by <br>
<a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.html?group_id=3790&type=1" border=0 width=88 height=31 alt="SourceForge"></a><br>
<br>Best viewed with <br>
<a href="http://www.anybrowser.org/campaign/"><img src="a-logo.gif" border=0 width=88 height=31 alt="Any Browser"></a><br>
</td></tr></table>
</td>
<td valign="top">
<h2>History</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. So I wrote a
small <a href="dasm_to_java.perl"><code>perl</code> script</a> that
did this process automatically. At the end of the next day I had my
first working decompiler.</p>
<p>Now while the <code>perl</code> script is working, it is not easy
to use. You have to decompile the code first with a disassembler, cut
out the code of a single method, and run the perl script on it. I
decided to get the bytecode directly out 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>
</td></tr>
</table>
<TABLE width="100%" border="0" cellspacing="0" cellpadding="2" bgcolor="737b9c">
<TR>
<TD align="center"><FONT color="#ffffff"><SPAN class="titlebar">
All trademarks and copyrights on this page are properties of their respective owners. <br>
Last updated on 8-May-2000,
Copyright &copy; 1998-2000 by Jochen Hoenicke.</SPAN></FONT>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>

@ -1,5 +1,5 @@
<?php require("header.inc"); ?>
<h2>History</h2>
<h1>History</h1>
<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

@ -1,131 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
<html>
<head>
<title>Java Optimize and Decompile Environment (JODE)</title>
<meta name="date" content="2000-06-30">
<meta name="description" content="JODE - Java Optimize and Decompile Environment.">
<meta name="author" content="Jochen Hoenicke">
<meta name="keywords" content="jode, java, decompiler, obfuscator, deobfuscator, reverse engineering, free, GPL">
</head>
<BODY bgcolor=#FFFFFF topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" marginheight="0" marginwidth="0">
<table cellpadding=4 cellspacing=1 width=100%>
<tr><td>
</td>
<td> <img src="jode-logo.gif" alt="JODE" width=286 height=110></td>
</tr>
<tr>
<td valign="top">
<table cellspacing=0 cellpadding=3 width=100% border=0 bgcolor=eeeef8>
<tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Jode</b></font></td></tr>
<tr><td align="right">
<a href="./"><B>Home</B></a><br>
<a href="http://sourceforge.net/project/?group_id=3790">Project&nbsp;page</a><br>
<br>
<a href="./applet.html">Applet</a><br>
<a href="./download.html">Download</a><br>
<a href="./usage.html">Documentation</a><br>
<a href="./license.html">License</a><br>
<a href="./history.html">History</a><br>
<a href="./links.html">Links</a><br>
<a href="./bluesky.html">Blue&nbsp;Sky</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Feedback</b></font></td></tr>
<tr><td align="right">
<a href="http://sourceforge.net/bugs/?group_id=3790">Bug&nbsp;Tracking</a><br>
<a href="http://sourceforge.net/forum/?group_id=3790">Public&nbsp;Forums</a><br>
<a href="http://lists.sourceforge.net/mailman/listinfo/jode-users">Mailing&nbsp;List</a><br>
<a href="http://sourceforge.net/sendmessage.html?touser=18252">Private&nbsp;Mail</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Download</b></font></td></tr>
<tr><td align="right">
<a href="ftp://jode.sourceforge.net/pub/jode/">FTP&nbsp;server</a><br>
<a href="http://sourceforge.net/project/filelist.html?group_id=3790">Source&nbsp;releases</a></td></tr>
<tr bgcolor="ffffff"><td align="center"><br>Powered by <br>
<a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.html?group_id=3790&type=1" border=0 width=88 height=31 alt="SourceForge"></a><br>
<br>Best viewed with <br>
<a href="http://www.anybrowser.org/campaign/"><img src="a-logo.gif" border=0 width=88 height=31 alt="Any Browser"></a><br>
</td></tr></table>
</td>
<td valign="top">
<P><i>JODE</i> is a java package containing a decompiler and an
optimizer for java. This package is freely available under the GPL
(see <a href="./license.html">license</a>).<p>
<P>The decompiler takes <tt>class</tt> files as input and produces
something similar to the original <tt>java</tt> 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 debuging) and there are
often more ways to write the same thing. But <i>JODE</i> does its job
quite well, so you should give it a try: <a href="./applet.html">start
the applet</a>.</P>
<P>The optimizer transforms <tt>class</tt> files in various ways with
can be controlled by a script file. It supports the following
operations:</p>
<ul>
<li>Renaming class, method, field and local names to shorter,
obfuscated, or unique names or according to a given translation
table</li>
<li>Removing debugging information</li>
<li>Removing dead code (classes, fields, methods) and constant
fields</li>
<li>Optimizing local variable allocation</li>
</ul>
<h2>News</h2>
<ul>
<li><i>JODE</i> is now hosted by <a href="http://sourceforge.net/">SourceForge</a>.</li>
<li>The latest <a href="http://sourceforge.net/cvs/?group_id=3790">CVS</a> version breaks long lines</li>
<li>I can now decompile <b>inner and anonymous</b> classes.</li>
<li>The optimizer (aka obfuscator) can be customized via a small
config file</li>
<li>Jode is <tt>autoconf</tt>igured.</li>
</ul>
<h2>Limitations</h2>
<p>If not all dependent classes can be found, the verifier (which is
run before decompilation starts) may exit with a type error. You
can decompile it with <tt>--verify=off</tt>, but take the warning
serious, that types may be incorrect. There's sometimes no way to
guess the right type, if you don't have access the full class
hierarchie.<br>
This is not a bug in the verifier: java will complain the same way,
if it is run with bytecode verification turned on. And if you don't
have the dependent classes, you can't compile the code again.</p>
<p>There may be situations, where the code doesn't understand complex
expressions. In this case many ugly temporary variables are used, but
the code should still be compileable. This does especially happen
when you compile with <tt>`-O'</tt> 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 <i>JODE</i> generates some GOTO expression and labels.
This shouldn't happen any more with code produced by javac or jikes.
But some flow obfuscator may provoke this. In that case you can run
the Obfuscator first (to optimize away the flow obfuscation ;-).</p>
</td></tr>
</table>
<TABLE width="100%" border="0" cellspacing="0" cellpadding="2" bgcolor="737b9c">
<TR>
<TD align="center"><FONT color="#ffffff"><SPAN class="titlebar">
All trademarks and copyrights on this page are properties of their respective owners. <br>
Last updated on 8-May-2000,
Copyright &copy; 1998-2000 by Jochen Hoenicke.</SPAN></FONT>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>

@ -1,16 +1,16 @@
<?php require("header.inc"); ?>
<P><i>JODE</i> is a java package containing a decompiler and an
optimizer for java. This package is freely available under the GPL
(see <?php selflink("license") ?>license</a>).<p>
optimizer for java. This package is <?php selflink("license")
?>freely available</a> under the GNU GPL.<p>
<P>The decompiler takes <tt>class</tt> files as input and produces
something similar to the original <tt>java</tt> 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 debuging) and there are
often more ways to write the same thing. But <i>JODE</i> does its job
quite well, so you should give it a try: <? selflink("applet") ?>start
the applet</a>.</P>
<P>The decompiler reads in <tt>class</tt> files and produces something
similar to the original <tt>java</tt> 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 debuging) and there are often
more ways to write the same thing. However, <i>JODE</i> does its job quite
well, so you should give it a try and <? selflink("applet") ?>start the
applet</a>.</P>
<P>The optimizer transforms <tt>class</tt> files in various ways with
can be controlled by a script file. It supports the following
@ -28,14 +28,23 @@ fields</li>
<h2>News</h2>
<ul>
<li><i>JODE</i> 1.1 is out. With support for javac v8 (jdk 1.3). </li>
<li><i>JODE</i> is now hosted by <a href="http://sourceforge.net/">SourceForge</a>.</li>
<li>The latest <?php sflink("cvs/") ?>CVS</a> version breaks long lines</li>
<li>I can now decompile <b>inner and anonymous</b> classes.</li>
<li>Now long lines are automatically broken.</li>
<li><b>Inner and anonymous</b> classes are automatically decompiled.</li>
<li>The optimizer (aka obfuscator) can be customized via a small
config file</li>
<li>Jode is <tt>autoconf</tt>igured.</li>
</ul>
<h2>Known bugs of the decompiler</h2>
<p>Some jdk1.3 synthetic access functions aren't understood. The
produced source contains access$xxx functions, but it still compiles.</p>
<p>There may be other bugs, that cause Exceptions or invalid code.
If you have such a problems don't hesitate to issue a bug report.
Please include the <code>class</code> file if possible.</p>
<h2>Limitations</h2>
<p>If not all dependent classes can be found, the verifier (which is
@ -55,15 +64,4 @@ the code should still be compileable. This does especially happen
when you compile with <tt>`-O'</tt> 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 <i>JODE</i> generates some GOTO expression and labels.
This shouldn't happen any more with code produced by javac or jikes.
But some flow obfuscator may provoke this. In that case you can run
the Obfuscator first (to optimize away the flow obfuscation ;-).</p>
<?php require("footer.inc"); ?>

@ -1,76 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
<html>
<head>
<title>Java Optimize and Decompile Environment (JODE)</title>
<meta name="date" content="2000-06-30">
<meta name="description" content="JODE - Java Optimize and Decompile Environment.">
<meta name="author" content="Jochen Hoenicke">
<meta name="keywords" content="jode, java, decompiler, obfuscator, deobfuscator, reverse engineering, free, GPL">
</head>
<BODY bgcolor=#FFFFFF topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" marginheight="0" marginwidth="0">
<table cellpadding=4 cellspacing=1 width=100%>
<tr><td>
</td>
<td> <img src="jode-logo.gif" alt="JODE" width=286 height=110></td>
</tr>
<tr>
<td valign="top">
<table cellspacing=0 cellpadding=3 width=100% border=0 bgcolor=eeeef8>
<tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Jode</b></font></td></tr>
<tr><td align="right">
<a href="./"><B>Home</B></a><br>
<a href="http://sourceforge.net/project/?group_id=3790">Project&nbsp;page</a><br>
<br>
<a href="./applet.html">Applet</a><br>
<a href="./download.html">Download</a><br>
<a href="./usage.html">Documentation</a><br>
<a href="./license.html">License</a><br>
<a href="./history.html">History</a><br>
<a href="./links.html">Links</a><br>
<a href="./bluesky.html">Blue&nbsp;Sky</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Feedback</b></font></td></tr>
<tr><td align="right">
<a href="http://sourceforge.net/bugs/?group_id=3790">Bug&nbsp;Tracking</a><br>
<a href="http://sourceforge.net/forum/?group_id=3790">Public&nbsp;Forums</a><br>
<a href="http://lists.sourceforge.net/mailman/listinfo/jode-users">Mailing&nbsp;List</a><br>
<a href="http://sourceforge.net/sendmessage.html?touser=18252">Private&nbsp;Mail</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Download</b></font></td></tr>
<tr><td align="right">
<a href="ftp://jode.sourceforge.net/pub/jode/">FTP&nbsp;server</a><br>
<a href="http://sourceforge.net/project/filelist.html?group_id=3790">Source&nbsp;releases</a></td></tr>
<tr bgcolor="ffffff"><td align="center"><br>Powered by <br>
<a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.html?group_id=3790&type=1" border=0 width=88 height=31 alt="SourceForge"></a><br>
<br>Best viewed with <br>
<a href="http://www.anybrowser.org/campaign/"><img src="a-logo.gif" border=0 width=88 height=31 alt="Any Browser"></a><br>
</td></tr></table>
</td>
<td valign="top">
<p><i>JODE</i> is Copyright &copy; 1998-2000 by Jochen Hoenicke. <br><br>
This program is free software; you can redistribute it and/or modify
it under the terms of the <a
href="http://www.gnu.org/copyleft/gpl.html">GNU General Public
License</a> as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.<br><br>
This program is distributed in the hope that it will be useful,
but <b>without any warranty</b>; without even the implied warranty of
<b>merchantability</b> or <b>fitness for a particular purpose</b>. See the
GNU General Public License for more details.
</td></tr>
</table>
<TABLE width="100%" border="0" cellspacing="0" cellpadding="2" bgcolor="737b9c">
<TR>
<TD align="center"><FONT color="#ffffff"><SPAN class="titlebar">
All trademarks and copyrights on this page are properties of their respective owners. <br>
Last updated on 8-May-2000,
Copyright &copy; 1998-2000 by Jochen Hoenicke.</SPAN></FONT>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>

@ -1,15 +1,16 @@
<?php require("header.inc"); ?>
<h1>License</h1>
<p><i>JODE</i> is Copyright &copy; 1998-2000 by Jochen Hoenicke. <br><br>
This program is free software; you can redistribute it and/or modify
<p>This program is free software; you can redistribute it and/or modify
it under the terms of the <a
href="http://www.gnu.org/copyleft/gpl.html">GNU General Public
License</a> as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.<br><br>
version 2 of the License, or (at your option) any later version.</p>
This program is distributed in the hope that it will be useful,
<p>This program is distributed in the hope that it will be useful,
but <b>without any warranty</b>; without even the implied warranty of
<b>merchantability</b> or <b>fitness for a particular purpose</b>. See the
GNU General Public License for more details.
GNU General Public License for more details.</p>
<?php require("footer.inc"); ?>

@ -1,123 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
<html>
<head>
<title>Java Optimize and Decompile Environment (JODE)</title>
<meta name="date" content="2000-06-30">
<meta name="description" content="JODE - Java Optimize and Decompile Environment.">
<meta name="author" content="Jochen Hoenicke">
<meta name="keywords" content="jode, java, decompiler, obfuscator, deobfuscator, reverse engineering, free, GPL">
</head>
<BODY bgcolor=#FFFFFF topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" marginheight="0" marginwidth="0">
<table cellpadding=4 cellspacing=1 width=100%>
<tr><td>
</td>
<td> <img src="jode-logo.gif" alt="JODE" width=286 height=110></td>
</tr>
<tr>
<td valign="top">
<table cellspacing=0 cellpadding=3 width=100% border=0 bgcolor=eeeef8>
<tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Jode</b></font></td></tr>
<tr><td align="right">
<a href="./"><B>Home</B></a><br>
<a href="http://sourceforge.net/project/?group_id=3790">Project&nbsp;page</a><br>
<br>
<a href="./applet.html">Applet</a><br>
<a href="./download.html">Download</a><br>
<a href="./usage.html">Documentation</a><br>
<a href="./license.html">License</a><br>
<a href="./history.html">History</a><br>
<a href="./links.html">Links</a><br>
<a href="./bluesky.html">Blue&nbsp;Sky</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Feedback</b></font></td></tr>
<tr><td align="right">
<a href="http://sourceforge.net/bugs/?group_id=3790">Bug&nbsp;Tracking</a><br>
<a href="http://sourceforge.net/forum/?group_id=3790">Public&nbsp;Forums</a><br>
<a href="http://lists.sourceforge.net/mailman/listinfo/jode-users">Mailing&nbsp;List</a><br>
<a href="http://sourceforge.net/sendmessage.html?touser=18252">Private&nbsp;Mail</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Download</b></font></td></tr>
<tr><td align="right">
<a href="ftp://jode.sourceforge.net/pub/jode/">FTP&nbsp;server</a><br>
<a href="http://sourceforge.net/project/filelist.html?group_id=3790">Source&nbsp;releases</a></td></tr>
<tr bgcolor="ffffff"><td align="center"><br>Powered by <br>
<a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.html?group_id=3790&type=1" border=0 width=88 height=31 alt="SourceForge"></a><br>
<br>Best viewed with <br>
<a href="http://www.anybrowser.org/campaign/"><img src="a-logo.gif" border=0 width=88 height=31 alt="Any Browser"></a><br>
</td></tr></table>
</td>
<td valign="top">
<h1><i>JODE</i> Links</h1>
<h3>Other decompilers</h3>
<ul>
<li><a href="http://dmoz.org/Computers/Programming/Languages/Java/Decompilers_and_Disassemblers/">The Open Directory list</a></li>
<li>A list of decompilers can be found at <a href="http://www.meurrens.org/ip-Links/Java/CodeEngineering/#tocDecompilersToJava">Marc Meurren's list</a>
</li>
<li>A very fast decompiler is <a
href="http://www.geocities.com/SiliconValley/Bridge/8617/jad.html">jad</a>
written in C++. It doesn't come with source code though, and misses
some features <i>JODE</i> has ;-)</li> <li><a
href="http://www.javaworld.com/javaworld/jw-07-1997/jw-07-decompilers.html">A
comparison of three decompilers</a> (but not <i>JODE</i>) was done by Dave
Dyer.
</ul>
<h3>Other obfuscators</h3>
<ul>
<li><a href="http://dmoz.org/Computers/Programming/Languages/Java/Obfuscators/">The Open Directory list</a></li>
<li><a href="http://www.sbktech.org/hashjava_old.html">Hashjava</a> is another free obfuscator. It is no longer maintained, though, since its successor was commercialized.</li>
<li><a href="http://www.zelix.com/klassmaster/index.html">Zelix
Klassmaster</a> does a very good flow optimization and also decrypts
strings. But <i>JODE</i>'s deobfuscator can undo both.</li>
<li><a href="http://www.cs.arizona.edu/~collberg/Research/">Christian S. Collberg</a> has some really interesting papers about non reversible obfuscations.</li>
</ul>
<h3>Graphical User Interface</h3>
<ul>
<li><i>JODE</i> is used by the <a
href="http://jedit.standmed.com/plugins/JavaInsight">JavaInsight plugin</a> for
<a href="http://jedit.sourceforge.net/">jEdit</a>.</li>
</ul>
<h3>Miscellanous packages needed to run JODE</h3>
<dl>
<dt>CYGWIN (unix tools for win95/NT)</dt>
<dd>
<a href="http://sourceware.cygnus.com/cygwin/">http://sourceware.cygnus.com/cygwin/</a>
</dd>
<dt>JDK 1.1:</dt>
<dd>
<a href="http://java.sun.com/products/jdk/1.1/">http://java.sun.com/products/jdk/1.1/</a>
</dd>
<dt><a name="swing">Swing for JDK 1.1:</a><dt>
<dd>
<a href="http://java.sun.com/products/jfc/index.html#download-swing">http://java.sun.com/products/jfc/index.html#download-swing</a>
</dd>
<dt>JDK 1.2:</dt>
<dd>
<a href="http://java.sun.com/products/jdk/1.2/">http://java.sun.com/products/jdk/1.2/</a>
</dd>
<dt><a name="getopt">Getopt</a>:</dt>
<dd>
<a href="http://www.urbanophile.com/arenn/hacking/download.html#getopt">http://www.urbanophile.com/arenn/hacking/download.html#getopt</a>
</dd>
<dt><a name="collections">Collection Classes</a>:</dt>
<dd>I have written a small script that puts the collection classes
from the <a href="http://www.classpath.org">GNU Classpath Project</a> into
its own package (<code>org.gnu.java.util.collections</code>). You can
download the <a href="http://www.informatik.uni-oldenburg.de/~delwi/jode/collections.tar.gz">source code</a> (including
the script), or <a href="collections.jar">a precompiled jar file</a>.
</dd>
</dl>
</td></tr>
</table>
<TABLE width="100%" border="0" cellspacing="0" cellpadding="2" bgcolor="737b9c">
<TR>
<TD align="center"><FONT color="#ffffff"><SPAN class="titlebar">
All trademarks and copyrights on this page are properties of their respective owners. <br>
Last updated on 8-May-2000,
Copyright &copy; 1998-2000 by Jochen Hoenicke.</SPAN></FONT>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>

@ -28,6 +28,19 @@ strings. But <i>JODE</i>'s deobfuscator can undo both.</li>
href="http://jedit.standmed.com/plugins/JavaInsight">JavaInsight plugin</a> for
<a href="http://jedit.sourceforge.net/">jEdit</a>.</li>
</ul>
<h3>Software Directories</h3>
<ul>
<li>Get everything and anything for Linux at the
<a href="http://www.linux-directory.com" target="_top"
><IMG SRC="http://www.linux-directory.com/button_88x31.gif"
WIDTH=88 HEIGHT=31 BORDER=0 ALT="Linux Directory"></a>.
</li>
<li>A great place for developing free software is
<a href="http://sourceforge.net"><img
src="http://sourceforge.net/sflogo.php?group_id=3790&type=1"
border=0 width=88 height=31 alt="SourceForge"></a>
</li>
</ul>
<h3>Miscellanous packages needed to run JODE</h3>
<dl>
<dt>CYGWIN (unix tools for win95/NT)</dt>
@ -52,10 +65,12 @@ href="http://jedit.standmed.com/plugins/JavaInsight">JavaInsight plugin</a> for
</dd>
<dt><a name="collections">Collection Classes</a>:</dt>
<dd>I have written a small script that puts the collection classes
from the <a href="http://www.classpath.org">GNU Classpath Project</a> into
its own package (<code>org.gnu.java.util.collections</code>). You can
download the <a href="http://www.informatik.uni-oldenburg.de/~delwi/jode/collections.tar.gz">source code</a> (including
the script), or <a href="collections.jar">a precompiled jar file</a>.
from the <a href="http://www.classpath.org">GNU Classpath Project</a>
into its own package (<code>gnu.java.util.collections</code>). This
script is now part of GNU classpath. For your convenience I have put a
precompiled <a
href="http://www.informatik.uni-oldenburg.de/~delwi/jode/collections.jar">jar
file</a> on this server.
</dd>
</dl>
<?php require("footer.inc"); ?>

@ -1,115 +1,47 @@
<?php
$menu = array(
"Jode",
array("<B>Home</B>" , "selflink", "jode",
$menu =
array("<B>Home</B>" , "selflink", "index",
"Project page" , "sflink", "project/",
"-", "-", "-",
"Applet" , "selflink", "applet",
"Download" , "selflink", "download",
"FAQ" , "selflink", "faq",
"Feedback" , "selflink", "feedback",
"Documentation", "selflink", "usage",
"License" , "selflink", "license",
"History" , "selflink", "history",
"Links" , "selflink", "links",
"Blue Sky" , "selflink", "bluesky"),
"Feedback",
array("Bug Tracking" , "sflink", "bugs/",
"Public Forums" , "sflink", "forum/",
"Mailing List" , "link",
"http://lists.sourceforge.net/mailman/listinfo/jode-users",
"Private Mail" , "link",
"http://sourceforge.net/sendmessage.php?touser=18252"),
"Download",
array("FTP server", "link", "ftp://jode.sourceforge.net/pub/jode/",
"Source releases", "sflink", "project/filelist.php"));
$images = array(
"Powered by ", "http://sourceforge.net/sflogo.php?group_id=3790&type=1",
"SourceForge", "http://sourceforge.net",
"Best viewed with ", "a-logo.gif",
"Any Browser", "http://www.anybrowser.org/campaign/");
if (eregi("^Lynx", $HTTP_USER_AGENT)) {
reset($menu);
while (list($dummy, $header) = each($menu)) {
list($dummy, $subitems) = each($menu);
echo "<b>$header:</b>\n";
reset($subitems);
while (list($dummy, $name) = each($subitems)) {
list($dummy, $type) = each($subitems);
list($dummy, $link) = each($subitems);
if ($type == "selflink") {
selflink($link);
} else if ($type == "sflink") {
sflink($link);
} else if ($type == "-") {
echo "<br>\n";
continue;
} else if ($type == "link") {
echo "<a href=\"$link\">";
}
$name = ereg_replace(" ", "&nbsp;", $name);
echo "$name</a>";
if (current($subitems)) {
echo " |\n";
}
}
echo "<br>\n\n";
}
echo "<right>\n";
reset($images);
while (list($dummy, $label) = each($images)) {
list($dummy, $src) = each($images);
list($dummy, $alt) = each($images);
list($dummy, $link) = each($images);
echo "$label<a href=\"$link\"><img src=\"$src\" border=0";
echo " width=88 height=31 alt=\"$alt\"></a>\n";
}
echo "</right>\n";
} else {
echo "<table cellspacing=0 cellpadding=3 width=100%";
echo " border=0 bgcolor=eeeef8>\n";
"Blue Sky" , "selflink", "bluesky");
?>
reset($menu);
while (list($dummy, $header) = each($menu)) {
list($dummy, $subitems) = each($menu);
echo "<tr bgcolor=\"7272cc\">\n<td align=\"center\">";
echo "<font color=\"ffffff\"><b>$header</b></font></td></tr>\n";
echo "<tr><td align=\"right\">\n";
reset($subitems);
while (list($dummy, $name) = each($subitems)) {
list($dummy, $type) = each($subitems);
list($dummy, $link) = each($subitems);
if ($type == "selflink") {
selflink($link);
} else if ($type == "sflink") {
sflink($link);
} else if ($type == "-") {
echo "<br>\n";
continue;
} else if ($type == "link") {
echo "<a href=\"$link\">";
}
$name = ereg_replace(" ", "&nbsp;", $name);
<table cellspacing=0 cellpadding=3 border=0 bgcolor=#EEEEF8 class="nav">
<tr><td class="nav">
<?php
reset($menu);
$self = ereg_replace("^.*/", "", $PHP_SELF);
while (list($dummy, $name) = each($menu)) {
list($dummy, $type) = each($menu);
list($dummy, $link) = each($menu);
$name = ereg_replace(" ", "&nbsp;", $name);
if ($type == "selflink") {
if ($self == "$link.$extension") {
echo "$name";
} else {
selflink($link);
echo "$name</a>";
if (current($subitems)) {
echo "<br>\n";
}
}
} else if ($type == "sflink") {
sflink($link);
echo "$name</a>";
} else if ($type == "-") {
echo "<br>\n";
continue;
} else if ($type == "link") {
echo "<a href=\"$link\">$name</a>";
}
echo "</td></tr>\n";
echo "<tr bgcolor=\"ffffff\"><td align=\"center\">";
reset($images);
while (list($dummy, $label) = each($images)) {
list($dummy, $src) = each($images);
list($dummy, $alt) = each($images);
list($dummy, $link) = each($images);
echo "<br>$label<br>\n";
echo "<a href=\"$link\"><img src=\"$src\" border=0";
echo " width=88 height=31 alt=\"$alt\"></a><br>\n";
if (current($menu)) {
echo " |\n";
}
echo "</td></tr></table>\n";
}
?>
</td></tr>
</table><br>

@ -1,281 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
<html>
<head>
<title>Java Optimize and Decompile Environment (JODE)</title>
<meta name="date" content="2000-06-30">
<meta name="description" content="JODE - Java Optimize and Decompile Environment.">
<meta name="author" content="Jochen Hoenicke">
<meta name="keywords" content="jode, java, decompiler, obfuscator, deobfuscator, reverse engineering, free, GPL">
</head>
<BODY bgcolor=#FFFFFF topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" marginheight="0" marginwidth="0">
<table cellpadding=4 cellspacing=1 width=100%>
<tr><td>
</td>
<td> <img src="jode-logo.gif" alt="JODE" width=286 height=110></td>
</tr>
<tr>
<td valign="top">
<table cellspacing=0 cellpadding=3 width=100% border=0 bgcolor=eeeef8>
<tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Jode</b></font></td></tr>
<tr><td align="right">
<a href="./"><B>Home</B></a><br>
<a href="http://sourceforge.net/project/?group_id=3790">Project&nbsp;page</a><br>
<br>
<a href="./applet.html">Applet</a><br>
<a href="./download.html">Download</a><br>
<a href="./usage.html">Documentation</a><br>
<a href="./license.html">License</a><br>
<a href="./history.html">History</a><br>
<a href="./links.html">Links</a><br>
<a href="./bluesky.html">Blue&nbsp;Sky</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Feedback</b></font></td></tr>
<tr><td align="right">
<a href="http://sourceforge.net/bugs/?group_id=3790">Bug&nbsp;Tracking</a><br>
<a href="http://sourceforge.net/forum/?group_id=3790">Public&nbsp;Forums</a><br>
<a href="http://lists.sourceforge.net/mailman/listinfo/jode-users">Mailing&nbsp;List</a><br>
<a href="http://sourceforge.net/sendmessage.html?touser=18252">Private&nbsp;Mail</a><tr bgcolor="7272cc">
<td align="center"><font color="ffffff"><b>Download</b></font></td></tr>
<tr><td align="right">
<a href="ftp://jode.sourceforge.net/pub/jode/">FTP&nbsp;server</a><br>
<a href="http://sourceforge.net/project/filelist.html?group_id=3790">Source&nbsp;releases</a></td></tr>
<tr bgcolor="ffffff"><td align="center"><br>Powered by <br>
<a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.html?group_id=3790&type=1" border=0 width=88 height=31 alt="SourceForge"></a><br>
<br>Best viewed with <br>
<a href="http://www.anybrowser.org/campaign/"><img src="a-logo.gif" border=0 width=88 height=31 alt="Any Browser"></a><br>
</td></tr></table>
</td>
<td valign="top">
<a name="decompiler">
<h1>Using the Decompiler</h1></a>
After you have <a href="./download.html">downloaded</a> the necessary
packages, put them into your <tt>CLASSPATH</tt>:
<ul><li>Under Windows you have to start a MSDOS session and type
something like:
<pre>
set CLASSPATH=C:\download\jode-xxx.jar;C:\swing\swingall.jar
</pre>
</li><li>Under Unix you start a shell and type (for bourne shell):
<pre>export CLASSPATH=/tmp/jode-xxx.jar:/usr/local/swing/swingall.jar</pre>
or for csh:
<pre>setenv CLASSPATH /tmp/jode-xxx.jar:/usr/local/swing/swingall.jar</pre>
</ul>
<br>
There is also a batch file for windows and a script file for unix,
that you can use. Adapt the CLASSPATH in the file and put it to a
convenient location.
<pre>
jar -xvf jode-xxx.jar bin/jode.bat <i>resp.</i> bin/jode
</pre>
<a name="cmdline"><h3>Command Line Interface</h3></a>
The most powerful way to start <I>JODE</I>'s decompiler is the command
line interface. Some people don't like long command lines; they
should go to the next section. <br>
Start the class <tt>jode.decompiler.Main</tt> with the options. The
following command will give a complete list of the available commands:
<pre>java jode.decompiler.Main --help</pre>
<a name="awt"><h3>AWT Interface</h3></a>
The AWT Interface looks exactly like the <a href="./applet.html">applet</a>. In fact the applet uses the AWT Interface. You start it
after setting the <tt>CLASSPATH</tt> (see <a href="./usage.html#decompiler">above</a>), with
<pre>java jode.decompiler.Window</pre>
In the classpath line you can enter a number of jar files, zip files
and directories separated by comma(<tt>,</tt>). Then enter the
dot(<tt>.</tt>) separated name of the class you want to decompile.
Press the <code>start</code> button and the decompiled class should
appear. You can save it via the <code>save</code> button.
<a name="swing"><h3>Swing Interface</h3></a>
For the swing interface you need java version 1.2 or the separately
available swing package (see <a href="./links.html#swing">link
page</a>. You can invoke it like this:
<pre>
java jode.swingui.Main --classpath classes.jar
</pre>
The swing interface will show the package hierarchie of all classes
in the classpath on the left side. You can now select a class and the
decompiled code will appear on the right side. Via the menu, you may
change the classpath or switch between package hierarchie tree and
class inheritence tree.<br>
The swing interface is very useful to browse through class files if
you don't have the source code. You can also use it to trace bugs in
library code. It is not meant to generate <tt>java</tt> files and so
you won't find a save option there.<br>
<a name="java"><h3>Java Interface</h3></a>
If you want to integrate <i>JODE</i> into your own java program, you
can use the <a
href="Decompiler.java"><code>jode.decompiler.Decompiler</code></a>
class. Note that the GPL only allows you to integrate <i>JODE</i>
into GPL programs. Please contact me if you use <i>JODE</i> in this
way.<br>
You may use this <a
href="ftp://jode.sourceforge.net/pub/jode/jode-embedded.jar">stripped
down jar archive</a> containing all necessary classes.
<a name="optimizer"><h1>Using the Obfuscator</h1>
To use the obfuscator you should first create a script file, say <a
href="myproject.jos"><tt>myproject.jos</tt></a>. Then you can invoke the
obfuscator with:
<pre>
java jode.obfuscator.Main myproject.jos
</pre>
<p>The script file should contain the following options: </p>
<p>First select the classpath. You should include everything in the
classpath that you need to run your application. This also includes
the system class files (Sun puts them into <code>classes.zip</code> or
<code>rt.jar</code>))</p>
<pre>
classpath = "c:\\jdk1.2\\jre\\lib\\rt.jar","d:\\project\\java",
"ftp://www.myorg.org/pub/classlib.jar"
</pre>
<p>Specify where you want the obfuscated classes to go. I recommend
to write them directly into a zip file, but you can also give a
directory.</p>
<pre>
dest = "obfuscated.zip"
</pre>
<p>You can make <i>JODE</i> write its translation table. This table
can be used later to undo the name obfuscation, or you can look there
to decrypt exceptions you may get.</p>
<pre>
revtable = "translat.tbl"
</pre>
<p>Select what you want to strip. There are several
possibilities, which can be separated by comma(<tt>,</tt>):</p>
<dl>
<dt>unreach</dt>
<dd>strip unreachable methods and classes.</dd>
<dt>source</dt>
<dd>remove the name of the java file (exceptions will get unreadable).</dd>
<dt>lnt</dt>
<dd>remove the line number table (exceptions will get unreadable).</dd>
<dt>lvt</dt>
<dd>remove the local variable table (debugging doesn't work).</dd>
<dt>inner</dt>
<dd>strip inner class info (reflection doesn't work correctly).</dd>
</dl>
<pre>
strip = "unreach","lvt","inner"
</pre>
<p>Select the packages and classes you want to obfuscate. You should
only include libraries, that you don't ship separately. If you give a
package, all classes and subpackages are loaded. You can also use
<code>*</code> as wild card, that matches everything (including dots).
</p>
<pre>
load = new WildCard { value = "org.myorg.myproject" },
new WildCard { value = "org.myorg.mylib*" },
new WildCard { value = "org.otherorg.shortlib" }
</pre>
<p>Select the methods and classes you want to preserve. This is
the <tt>main</tt> method for applications and the default constructor
<tt>&lt;init&gt;.()V</tt> for applets, resource bundles and other classes
that you load manually at runtime.<br> You have to give the method
name and the type signature to identify your method. <tt>javap
-s</tt> will show you the type signatures for your classes, but you
may also use <tt>*</tt>, to select all methods with that name.</p>
<pre>
preserve = new WildCard { value = "org.myorg.ApplicationClass.main.*" },
new WildCard { value = "org.myorg.AppletClass.&lt;init&gt;.()V" },
new WildCard { value = "org.resources.Bundle*.&lt;init&gt;.()V" },
</pre>
<p>If you want to obfuscate (or just shorten) the identifier you can
specify a renamer. There are currently following renamer
available</p>
<dl><dt>StrongRenamer</dt>
<dd>Renames to the shortest possible name. You can give a charset
that should be used. It uses the same name as much as possible.</dd>
<dt>UniqueRenamer</dt>
<dd>Renames to unique identifier of the form <tt>xxx123</tt>. Useful
to reduce name conflicts, before you decompile an obfuscated package.</dd>
<dt>NameSwapper</dt>
<dd>This renamer just swaps the names. This is a funny obfuscation
option that is not very strong, but very confusing.</dd>
<dt>KeywordRenamer</dt>
<dd>Renames identifiers to keyword. You can give your own list of
keywords as parameters. Resulting code is not decompilable directly,
<b>but it is <i>not</i> legal bytecode either</b>. Some paranoid
web browsers refuse to run applets containing keywords as identifiers
(and they are completely within the Java VM spec).</dd>
</dl>
<pre>
renamer = new StrongRenamer
</pre>
<p>You can also create a renaming table with the same format as the
table written by revtable. The entries in the table get precedence
over renamer. Entries not in the table will get renamed by the
renamer.<p>
<pre>
table = "translat.tbl"
</pre>
<p>Now you can select the analyzer. The purpose of the
analyzer is to mark all reachable methods, find out which methods
needs to get the same name (overloading), and which method names
mustn't change (overload of library methods, e.g. <tt>nextElement</tt>
for <tt>Enumeration</tt>s). There are currently two analyzers.
<dl><dt>SimpleAnalyzer</dt>
<dd>Straight forward analyzer. It is fast and will remove dead code
on method basis.</dd>
<dd><dt>ConstantAnalyzer</dt>
<dd>Strong analyzer that will determine, which fields and instructions
have constant values. It will remove dead code on instruction basis
and replace constant instruction with a load of the constant, or
remove them completely.<br> This analyzer is especially useful to
revert the flow obfuscation of some other obfuscators.</dd>
</dl>
</p>
<pre>
analyzer = new ConstantAnalyzer
</pre>
<p>Pre- and Post transformers transform the bytecode before
resp. after the Analyzer runs. Using this default should be okay.
You may remove the LocalOptimizer, though, if you have problems.</p>
<p>In the future I may add some new post transformers, that do string
encryption, flow obfuscation and similar things. If you want to write
your own Transformers please contact me, since the next version will
change the bytecode interface.</p>
<pre>
post = new LocalOptimizer, new RemovePopAnalyzer
</pre>
</td></tr>
</table>
<TABLE width="100%" border="0" cellspacing="0" cellpadding="2" bgcolor="737b9c">
<TR>
<TD align="center"><FONT color="#ffffff"><SPAN class="titlebar">
All trademarks and copyrights on this page are properties of their respective owners. <br>
Last updated on 8-May-2000,
Copyright &copy; 1998-2000 by Jochen Hoenicke.</SPAN></FONT>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>

@ -9,26 +9,28 @@
*/ ?>
<a name="decompiler">
<h1>Using the Decompiler</h1></a>
After you have <?php selflink("download") ?>downloaded</a> the necessary
packages, put them into your <tt>CLASSPATH</tt>:
<p>After you have <?php selflink("download") ?>downloaded</a> the jar archive
put it into your <tt>CLASSPATH</tt>. The package
<tt>swingall.jar</tt> is also needed if you are using JDK 1.1.</p>
<ul><li>Under Windows you have to start a MSDOS session and type
something like:
<pre>
set CLASSPATH=C:\download\jode-xxx.jar;C:\swing\swingall.jar
set CLASSPATH=C:\download\jode-<?php echo "$version"?>.jar;C:\swing\swingall.jar
</pre>
</li><li>Under Unix you start a shell and type (for bourne shell):
<pre>export CLASSPATH=/tmp/jode-xxx.jar:/usr/local/swing/swingall.jar</pre>
<li>Under Unix you start a shell and type (for bourne shell):
<pre>export CLASSPATH=/tmp/jode-<?php echo "$version"?>.jar:/usr/local/swing/swingall.jar</pre>
or for csh:
<pre>setenv CLASSPATH /tmp/jode-xxx.jar:/usr/local/swing/swingall.jar</pre>
<pre>setenv CLASSPATH /tmp/jode-<?php echo "$version"?>.jar:/usr/local/swing/swingall.jar</pre>
</ul>
<br>
There is also a batch file for windows and a script file for unix,
that you can use. Adapt the CLASSPATH in the file and put it to a
convenient location.
that you can use. You can extract it with the following command:
<pre>
jar -xvf jode-xxx.jar bin/jode.bat <i>resp.</i> bin/jode
jar -xvf jode-<?php echo "$version-jdk1.1"?>.jar bin/jode.bat <i>resp.</i> bin/jode
</pre>
Edit the file to adapt it to your paths and put it to a convenient location.
<a name="cmdline"><h3>Command Line Interface</h3></a>
@ -41,6 +43,13 @@ following command will give a complete list of the available commands:
<pre>java jode.decompiler.Main --help</pre>
If you want to decompile a jar package you can do it this way:
<pre>java jode.decompiler.Main --dest srcdir program.jar</pre>
If you have installed the batch file/script, you can use it like this:
<pre>jode --dest srcdir program.jar</pre>
<a name="awt"><h3>AWT Interface</h3></a>
The AWT Interface looks exactly like the <?php selflink("applet") ?>
@ -60,43 +69,45 @@ appear. You can save it via the <code>save</code> button.
For the swing interface you need java version 1.2 or the separately
available swing package (see <?php selflink("links#swing") ?>link
page</a>. You can invoke it like this:
page</a>. You can invoke it with the following command:
<pre>
java jode.swingui.Main --classpath classes.jar
java jode.swingui.Main classes.jar
<i>resp.</i> jode swi classes.jar
</pre>
The swing interface will show the package hierarchie of all classes
<p>The swing interface will show the package hierarchie of all classes
in the classpath on the left side. You can now select a class and the
decompiled code will appear on the right side. Via the menu, you may
change the classpath or switch between package hierarchie tree and
class inheritence tree.<br>
class inheritence tree.</p>
The swing interface is very useful to browse through class files if
<p>The swing interface is very useful to browse through class files if
you don't have the source code. You can also use it to trace bugs in
library code. It is not meant to generate <tt>java</tt> files and so
you won't find a save option there.<br>
you won't find a save option there.</p>
<a name="java"><h3>Java Interface</h3></a>
If you want to integrate <i>JODE</i> into your own java program, you
can use the <a
href="Decompiler.java"><code>jode.decompiler.Decompiler</code></a>
<p>If you want to integrate <i>JODE</i> into your own java program,
you can use the <a
href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jode/jode/jode/decompiler/Decompiler.java?rev=jode_1_1&content-type=text/vnd.viewcvs-markup"
><code>jode.decompiler.Decompiler</code></a>
class. Note that the GPL only allows you to integrate <i>JODE</i>
into GPL programs. Please contact me if you use <i>JODE</i> in this
way.<br>
into GPL programs. Please tell me if you use <i>JODE</i> in this
way.</p>
You may use this <a
href="ftp://jode.sourceforge.net/pub/jode/jode-embedded.jar">stripped
down jar archive</a> containing all necessary classes.
<p>You should ship <code>jode-1.1-embedded.jar</code> with your program. This jar file is
available in the <? sflink("project/showfiles.php") ?>download area</a>.
It works only under JDK&nbsp;1.2 and above.</p>
<a name="optimizer"><h1>Using the Obfuscator</h1>
To use the obfuscator you should first create a script file, say <a
<p>To use the obfuscator you should first create a script file, say <a
href="myproject.jos"><tt>myproject.jos</tt></a>. Then you can invoke the
obfuscator with:
<pre>
java jode.obfuscator.Main myproject.jos
</pre>
</pre></p>
<p>The script file should contain the following options: </p>

@ -85,8 +85,7 @@ foreach $clazz (@ARGV) {
my ($magic, $minor, $major) = unpack("Nnn", $buff);
die "Wrong magic $magic" if $magic != 0xcafebabe;
die "Wrong minor $minor" if $minor > 3;
die "Wrong minor $major" if $major != 45;
die "Wrong major $major" if $major < 45;
readInBuff 2 or die "Can't read cpool length";

@ -1,7 +1,7 @@
/* AssertError Copyright (C) 1998-1999 Jochen Hoenicke.
/* AssertError Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* GlobalOptions Copyright (C) 1999-2000 Jochen Hoenicke.
/* GlobalOptions Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -25,7 +25,7 @@ public class GlobalOptions {
public final static String version = "@VERSION@";
public final static String email = "jochen@gnu.org";
public final static String copyright =
"Jode (c) 1998-2000 Jochen Hoenicke <"+email+">";
"Jode (c) 1998-2001 Jochen Hoenicke <"+email+">";
public final static String URL = "http://jode.sourceforge.net/";
public static PrintWriter err = new PrintWriter(System.err, true);

@ -1,7 +1,7 @@
/* BinaryInfo Copyright (C) 1998-1999 Jochen Hoenicke.
/* BinaryInfo Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* BytecodeInfo Copyright (C) 1999 Jochen Hoenicke.
/* BytecodeInfo Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -25,6 +25,8 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.EOFException;
import java.io.IOException;
import java.util.BitSet;
import java.util.Stack;
import java.util.Vector;
import java.util.Enumeration;
import java.util.NoSuchElementException;
@ -209,94 +211,98 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes {
protected void readAttribute(String name, int length, ConstantPool cp,
DataInputStream input,
int howMuch) throws IOException {
if ((howMuch & KNOWNATTRIBS) != 0
&& name.equals("LocalVariableTable")) {
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_LVT) != 0)
GlobalOptions.err.println("LocalVariableTable of "+methodInfo);
int count = input.readUnsignedShort();
if (length != 2 + count * 10) {
if (name.equals("LocalVariableTable")) {
if ((howMuch & KNOWNATTRIBS) != 0){
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_LVT) != 0)
GlobalOptions.err.println("Illegal LVT length, ignoring it");
return;
}
lvt = new LocalVariableInfo[count];
for (int i=0; i < count; i++) {
lvt[i] = new LocalVariableInfo();
int start = input.readUnsignedShort();
int end = start + input.readUnsignedShort();
int nameIndex = input.readUnsignedShort();
int typeIndex = input.readUnsignedShort();
int slot = input.readUnsignedShort();
Instruction startInstr =
start >= 0 && start < instrs.length ? instrs[start] : null;
Instruction endInstr;
if (end >=0 && end < instrs.length)
endInstr = instrs[end] == null ? null
: instrs[end].getPrevByAddr();
else {
endInstr = null;
for (int nr = instrs.length - 1; nr >= 0; nr--) {
if (instrs[nr] != null) {
if (instrs[nr].getNextAddr() == end)
endInstr = instrs[nr];
break;
GlobalOptions.err.println("LocalVariableTable of "+methodInfo);
int count = input.readUnsignedShort();
if (length != 2 + count * 10) {
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_LVT) != 0)
GlobalOptions.err.println("Illegal LVT length, ignoring it");
return;
}
lvt = new LocalVariableInfo[count];
for (int i=0; i < count; i++) {
lvt[i] = new LocalVariableInfo();
int start = input.readUnsignedShort();
int end = start + input.readUnsignedShort();
int nameIndex = input.readUnsignedShort();
int typeIndex = input.readUnsignedShort();
int slot = input.readUnsignedShort();
Instruction startInstr =
start >= 0 && start < instrs.length ? instrs[start] : null;
Instruction endInstr;
if (end >=0 && end < instrs.length)
endInstr = instrs[end] == null ? null
: instrs[end].getPrevByAddr();
else {
endInstr = null;
for (int nr = instrs.length - 1; nr >= 0; nr--) {
if (instrs[nr] != null) {
if (instrs[nr].getNextAddr() == end)
endInstr = instrs[nr];
break;
}
}
}
}
if (startInstr == null
|| endInstr == null
|| nameIndex == 0 || typeIndex == 0
|| slot >= maxLocals
|| cp.getTag(nameIndex) != cp.UTF8
|| cp.getTag(typeIndex) != cp.UTF8) {
// This is probably an evil lvt as created by HashJava
// simply ignore it.
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_LVT) != 0)
GlobalOptions.err.println
if (startInstr == null
|| endInstr == null
|| nameIndex == 0 || typeIndex == 0
|| slot >= maxLocals
|| cp.getTag(nameIndex) != cp.UTF8
|| cp.getTag(typeIndex) != cp.UTF8) {
// This is probably an evil lvt as created by HashJava
// simply ignore it.
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_LVT) != 0)
GlobalOptions.err.println
("Illegal entry, ignoring LVT");
lvt = null;
return;
lvt = null;
return;
}
lvt[i].start = startInstr;
lvt[i].end = endInstr;
lvt[i].name = cp.getUTF8(nameIndex);
lvt[i].type = cp.getUTF8(typeIndex);
lvt[i].slot = slot;
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_LVT) != 0)
GlobalOptions.err.println("\t" + lvt[i].name + ": "
+ lvt[i].type
+" range "+start+" - "+end
+" slot "+slot);
}
lvt[i].start = startInstr;
lvt[i].end = endInstr;
lvt[i].name = cp.getUTF8(nameIndex);
lvt[i].type = cp.getUTF8(typeIndex);
lvt[i].slot = slot;
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_LVT) != 0)
GlobalOptions.err.println("\t" + lvt[i].name + ": "
+ lvt[i].type
+" range "+start+" - "+end
+" slot "+slot);
}
} else if ((howMuch & KNOWNATTRIBS) != 0
&& name.equals("LineNumberTable")) {
int count = input.readUnsignedShort();
if (length != 2 + count * 4) {
GlobalOptions.err.println
("Illegal LineNumberTable, ignoring it");
return;
}
lnt = new LineNumber[count];
for (int i = 0; i < count; i++) {
lnt[i] = new LineNumber();
int start = input.readUnsignedShort();
Instruction startInstr = instrs[start];
if (startInstr == null) {
} else
input.readFully(new byte[length]);
} else if (name.equals("LineNumberTable")) {
if ((howMuch & KNOWNATTRIBS) != 0) {
int count = input.readUnsignedShort();
if (length != 2 + count * 4) {
GlobalOptions.err.println
("Illegal entry, ignoring LineNumberTable table");
lnt = null;
("Illegal LineNumberTable, ignoring it");
return;
}
lnt[i].start = startInstr;
lnt[i].linenr = input.readUnsignedShort();
}
lnt = new LineNumber[count];
for (int i = 0; i < count; i++) {
lnt[i] = new LineNumber();
int start = input.readUnsignedShort();
Instruction startInstr = instrs[start];
if (startInstr == null) {
GlobalOptions.err.println
("Illegal entry, ignoring LineNumberTable table");
lnt = null;
return;
}
lnt[i].start = startInstr;
lnt[i].linenr = input.readUnsignedShort();
}
} else
input.readFully(new byte[length]);
} else
super.readAttribute(name, length, cp, input, howMuch);
}
public void read(ConstantPool cp,
DataInputStream input) throws IOException {
maxStack = input.readUnsignedShort();
@ -845,6 +851,42 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes {
int index = input.readUnsignedShort();
exceptionHandlers[i].type = (index == 0) ? null
: cp.getClassName(index);
if (exceptionHandlers[i].catcher.getOpcode() == opc_athrow) {
/* There is an obfuscator, which inserts bogus
* exception entries jumping directly to a throw
* instruction. Remove those handlers.
*/
handlersLength--;
i--;
continue;
}
if (exceptionHandlers[i].start.getAddr()
<= exceptionHandlers[i].catcher.getAddr()
&& exceptionHandlers[i].end.getAddr()
>= exceptionHandlers[i].catcher.getAddr())
{
/* Javac 1.4 is a bit paranoid with finally and
* synchronize blocks and even breaks the JLS.
* We fix it here. Hopefully this won't produce
* any other problems.
*/
if (exceptionHandlers[i].start
== exceptionHandlers[i].catcher) {
handlersLength--;
i--;
} else {
exceptionHandlers[i].end =
exceptionHandlers[i].catcher.getPrevByAddr();
}
}
}
if (handlersLength < exceptionHandlers.length) {
Handler[] newHandlers = new Handler[handlersLength];
System.arraycopy(exceptionHandlers, 0, newHandlers, 0,
handlersLength);
exceptionHandlers = newHandlers;
}
}
readAttributes(cp, input, FULLINFO);
@ -901,9 +943,73 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes {
}
}
private void calculateMaxStack() {
maxStack = 0;
int[] stackHeights = new int[instructions.getCodeLength()];
int[] poppush = new int[2];
Stack todo = new Stack();
for (int i=0; i < stackHeights.length; i++)
stackHeights[i] = -1;
stackHeights[0] = 0;
todo.push(instructions.get(0));
while (!todo.isEmpty()) {
Instruction instr = (Instruction) todo.pop();
Instruction next = instr.getNextByAddr();
Instruction[] succs = instr.getSuccs();
int addr = instr.getAddr();
instr.getStackPopPush(poppush);
int sh = stackHeights[addr] - poppush[0] + poppush[1];
// System.err.println("Instr: "+instr.getDescription()+
// "; before: "+stackHeights[addr]+" after: "+sh);
if (maxStack < sh)
maxStack = sh;
if (instr.getOpcode() == opc_jsr) {
if (stackHeights[next.getAddr()] == -1) {
stackHeights[next.getAddr()] = sh - 1;
todo.push(next);
}
if (stackHeights[succs[0].getAddr()] == -1) {
stackHeights[succs[0].getAddr()] = sh;
todo.push(succs[0]);
}
} else {
if (succs != null) {
for (int i=0; i < succs.length; i++) {
if (stackHeights[succs[i].getAddr()] == -1) {
stackHeights[succs[i].getAddr()] = sh;
todo.push(succs[i]);
}
}
}
if (!instr.doesAlwaysJump()
&& stackHeights[next.getAddr()] == -1) {
stackHeights[next.getAddr()] = sh;
todo.push(next);
}
}
for (int i=0; i< exceptionHandlers.length; i++) {
if (exceptionHandlers[i].start.compareTo(instr) <= 0
&& exceptionHandlers[i].end.compareTo(instr) >= 0) {
int catcher = exceptionHandlers[i].catcher.getAddr();
if (stackHeights[catcher] == -1) {
stackHeights[catcher] = 1;
todo.push(exceptionHandlers[i].catcher);
}
}
}
}
// System.err.println("New maxStack: "+maxStack+" Locals: "+maxLocals);
}
public void prepareWriting(GrowableConstantPool gcp) {
/* Recalculate addr, length and add all constants to gcp */
/* Recalculate addr, length, maxStack, maxLocals and add all
* constants to gcp */
int addr = 0;
maxLocals = (methodInfo.isStatic() ? 0 : 1) +
TypeSignature.getArgumentSize(methodInfo.getType());
for (Iterator iter = instructions.iterator(); iter.hasNext(); ) {
Instruction instr = (Instruction) iter.next();
int opcode = instr.getOpcode();
@ -957,22 +1063,44 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes {
length = 3;
else
length = 6;
if (slot >= maxLocals)
maxLocals = slot + 1;
break;
}
case opc_iload: case opc_lload:
case opc_fload: case opc_dload: case opc_aload:
case opc_istore: case opc_lstore:
case opc_fstore: case opc_dstore: case opc_astore:
if (instr.getLocalSlot() < 4) {
case opc_iload: case opc_fload: case opc_aload:
case opc_istore: case opc_fstore: case opc_astore: {
int slot = instr.getLocalSlot();
if (slot < 4)
length = 1;
break;
}
/* fall through */
else if (slot < 256)
length = 2;
else
length = 4;
if (slot >= maxLocals)
maxLocals = slot + 1;
break;
}
case opc_lload: case opc_dload:
case opc_lstore: case opc_dstore: {
int slot = instr.getLocalSlot();
if (slot < 4)
length = 1;
else if (slot < 256)
length = 2;
else
length = 4;
if (slot+1 >= maxLocals)
maxLocals = slot + 2;
break;
}
case opc_ret: {
if (instr.getLocalSlot() < 256)
int slot = instr.getLocalSlot();
if (slot < 256)
length = 2;
else
length = 4;
if (slot >= maxLocals)
maxLocals = slot + 1;
break;
}
case opc_lookupswitch: {
@ -1092,6 +1220,12 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes {
addr += length;
}
instructions.setLastAddr(addr);
try {
calculateMaxStack();
} catch (RuntimeException ex) {
ex.printStackTrace();
dumpCode(GlobalOptions.err);
}
for (int i=0; i< exceptionHandlers.length; i++)
if (exceptionHandlers[i].type != null)
gcp.putClassName(exceptionHandlers[i].type);
@ -1483,14 +1617,6 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes {
return lnt;
}
public void setMaxStack(int ms) {
maxStack = ms;
}
public void setMaxLocals(int ml) {
maxLocals = ml;
}
public void setExceptionHandlers(Handler[] handlers) {
exceptionHandlers = handlers;
}

@ -1,7 +1,7 @@
/* ClassFormatException Copyright (C) 1998-1999 Jochen Hoenicke.
/* ClassFormatException Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* ClassInfo Copyright (C) 1998-1999 Jochen Hoenicke.
/* ClassInfo Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -82,6 +82,7 @@ public class ClassInfo extends BinaryInfo {
private boolean modified = false;
private int modifiers = -1;
private boolean deprecatedFlag;
private String name;
private ClassInfo superclass;
private ClassInfo[] interfaces;
@ -123,14 +124,14 @@ public class ClassInfo extends BinaryInfo {
}
public static Enumeration getClassesAndPackages(final String packageName) {
final Enumeration enum =
final Enumeration enumeration =
classpath.listFiles(packageName.replace('.','/'));
return new Enumeration() {
public boolean hasMoreElements() {
return enum.hasMoreElements();
return enumeration.hasMoreElements();
}
public Object nextElement() {
String name = (String) enum.nextElement();
String name = (String) enumeration.nextElement();
if (!name.endsWith(".class"))
// This is a package
return name;
@ -167,98 +168,121 @@ public class ClassInfo extends BinaryInfo {
ConstantPool cp,
DataInputStream input,
int howMuch) throws IOException {
if ((howMuch & KNOWNATTRIBS) != 0 && name.equals("SourceFile")) {
if (length != 2)
throw new ClassFormatException("SourceFile attribute"
+ " has wrong length");
sourceFile = cp.getUTF8(input.readUnsignedShort());
} else if ((howMuch & (OUTERCLASSES | INNERCLASSES)) != 0
&& name.equals("InnerClasses")) {
int count = input.readUnsignedShort();
if (length != 2 + 8 * count)
if (name.equals("SourceFile")) {
if ((howMuch & KNOWNATTRIBS) != 0) {
if (length != 2)
throw new ClassFormatException("SourceFile attribute"
+ " has wrong length");
sourceFile = cp.getUTF8(input.readUnsignedShort());
} else
input.readFully(new byte[length]);
} else if (name.equals("InnerClasses")) {
if ((howMuch & (OUTERCLASSES | INNERCLASSES)) != 0) {
int count = input.readUnsignedShort();
if (length != 2 + 8 * count)
throw new ClassFormatException
("InnerClasses attribute has wrong length");
int innerCount = 0, outerCount = 0, extraCount = 0;
InnerClassInfo[] innerClassInfo = new InnerClassInfo[count];
for (int i=0; i< count; i++) {
int innerIndex = input.readUnsignedShort();
int outerIndex = input.readUnsignedShort();
int nameIndex = input.readUnsignedShort();
String inner = cp.getClassName(innerIndex);
String outer =
outerIndex != 0 ? cp.getClassName(outerIndex) : null;
String innername =
nameIndex != 0 ? cp.getUTF8(nameIndex) : null;
int access = input.readUnsignedShort();
if (innername != null && innername.length() == 0)
innername = null;
InnerClassInfo ici = new InnerClassInfo
(inner, outer, innername, access);
if (outer != null && outer.equals(getName())
&& innername != null)
innerClassInfo[innerCount++] = ici;
else
innerClassInfo[count - (++extraCount)] = ici;
}
/* Now innerClasses are at the front of innerClassInfo array
* in correct order. The other InnerClassInfos are in reverse
* order in the rest of the innerClassInfo array.
*/
/* We now count the outerClasses. The reverse order is the
* right thing for us.
*/
{
String lastOuterName = getName();
for (int i = count - extraCount;
i < count && lastOuterName != null; i++) {
InnerClassInfo ici = innerClassInfo[i];
if (ici.inner.equals(lastOuterName)) {
outerCount++;
extraCount--;
lastOuterName = ici.outer;
int innerCount = 0, outerCount = 0, extraCount = 0;
InnerClassInfo[] innerClassInfo = new InnerClassInfo[count];
for (int i=0; i< count; i++) {
int innerIndex = input.readUnsignedShort();
int outerIndex = input.readUnsignedShort();
int nameIndex = input.readUnsignedShort();
String inner = cp.getClassName(innerIndex);
String outer =
outerIndex != 0 ? cp.getClassName(outerIndex) : null;
String innername =
nameIndex != 0 ? cp.getUTF8(nameIndex) : null;
int access = input.readUnsignedShort();
if (innername != null && innername.length() == 0)
innername = null;
/* Some compilers give method scope classes a valid
* outer field, but we mustn't handle them as inner
* classes. The best way to distinguish this case
* is by the class name.
*/
if (outer != null && innername != null
&& inner.length() > outer.length() + 2 + innername.length()
&& inner.startsWith(outer+"$")
&& inner.endsWith("$"+innername)
&& Character.isDigit(inner.charAt(outer.length() + 1)))
outer = null;
InnerClassInfo ici = new InnerClassInfo
(inner, outer, innername, access);
if (outer != null && outer.equals(getName())
&& innername != null)
innerClassInfo[innerCount++] = ici;
else
innerClassInfo[count - (++extraCount)] = ici;
}
/* Now innerClasses are at the front of innerClassInfo array
* in correct order. The other InnerClassInfos are in reverse
* order in the rest of the innerClassInfo array.
*/
/* We now count the outerClasses. The reverse order is the
* right thing for us.
*/
{
String lastOuterName = getName();
for (int i = count - extraCount;
i < count && lastOuterName != null; i++) {
InnerClassInfo ici = innerClassInfo[i];
if (ici.inner.equals(lastOuterName)) {
outerCount++;
extraCount--;
lastOuterName = ici.outer;
}
}
}
}
if (innerCount > 0) {
innerClasses = new InnerClassInfo[innerCount];
System.arraycopy(innerClassInfo, 0,
innerClasses, 0, innerCount);
} else
innerClasses = null;
if (outerCount > 0) {
outerClasses = new InnerClassInfo[outerCount];
} else
outerClasses = null;
if (extraCount > 0) {
extraClasses = new InnerClassInfo[extraCount];
} else
extraClasses = null;
/* The last part: We split between outer and extra classes.
* In this step we will also revert the order of the extra
* classes.
*/
{
int outerPtr = 0;
String lastOuterName = getName();
for (int i = count - extraCount - outerCount;
i < count; i++) {
InnerClassInfo ici = innerClassInfo[i];
/* If we counted correctly there is no NullPointer
* or ArrayIndexOutOfBoundsException here
*/
if (ici.inner.equals(lastOuterName)) {
outerClasses[outerPtr++] = ici;
lastOuterName = ici.outer;
} else
extraClasses[--extraCount] = ici;
if (innerCount > 0) {
innerClasses = new InnerClassInfo[innerCount];
System.arraycopy(innerClassInfo, 0,
innerClasses, 0, innerCount);
} else
innerClasses = null;
if (outerCount > 0) {
outerClasses = new InnerClassInfo[outerCount];
} else
outerClasses = null;
if (extraCount > 0) {
extraClasses = new InnerClassInfo[extraCount];
} else
extraClasses = null;
/* The last part: We split between outer and extra classes.
* In this step we will also revert the order of the extra
* classes.
*/
{
int outerPtr = 0;
String lastOuterName = getName();
for (int i = count - extraCount - outerCount;
i < count; i++) {
InnerClassInfo ici = innerClassInfo[i];
/* If we counted correctly there is no NullPointer
* or ArrayIndexOutOfBoundsException here
*/
if (ici.inner.equals(lastOuterName)) {
outerClasses[outerPtr++] = ici;
lastOuterName = ici.outer;
} else
extraClasses[--extraCount] = ici;
}
}
}
} else
input.readFully(new byte[length]);
} else if (name.equals("Deprecated")) {
deprecatedFlag = true;
if (length != 0)
throw new ClassFormatException
("Deprecated attribute has wrong length");
} else
super.readAttribute(name, length, cp, input, howMuch);
}
@ -272,10 +296,10 @@ public class ClassInfo extends BinaryInfo {
/* header */
if (input.readInt() != 0xcafebabe)
throw new ClassFormatException("Wrong magic");
if (input.readUnsignedShort() > 3)
throw new ClassFormatException("Wrong minor");
if (input.readUnsignedShort() != 45)
throw new ClassFormatException("Wrong major");
int version = input.readUnsignedShort();
version |= input.readUnsignedShort() << 16;
if (version < (45 << 16 | 0))
throw new ClassFormatException("Wrong class version");
/* constant pool */
ConstantPool cpool = new ConstantPool();
@ -393,6 +417,8 @@ public class ClassInfo extends BinaryInfo {
gcp.putUTF8(extraClasses[i].name);
}
}
if (deprecatedFlag)
gcp.putUTF8("Deprecated");
prepareAttributes(gcp);
}
@ -448,6 +474,10 @@ public class ClassInfo extends BinaryInfo {
output.writeShort(extraClasses[i].modifiers);
}
}
if (deprecatedFlag) {
output.writeShort(gcp.putUTF8("Deprecated"));
output.writeInt(0);
}
}
public void write(DataOutputStream out) throws IOException {
@ -603,9 +633,6 @@ public class ClassInfo extends BinaryInfo {
String message = ex.getMessage();
if ((howMuch & ~(FIELDS|METHODS|HIERARCHY
|INNERCLASSES|OUTERCLASSES)) != 0) {
GlobalOptions.err.println
("Can't read class " + name + ".");
ex.printStackTrace(GlobalOptions.err);
throw new NoClassDefFoundError(name);
}
// Try getting the info through the reflection interface
@ -739,6 +766,10 @@ public class ClassInfo extends BinaryInfo {
return Modifier.isInterface(getModifiers());
}
public boolean isDeprecated() {
return deprecatedFlag;
}
public FieldInfo findField(String name, String typeSig) {
if ((status & FIELDS) == 0)
loadInfo(FIELDS);
@ -813,6 +844,10 @@ public class ClassInfo extends BinaryInfo {
modified = true;
}
public void setDeprecated(boolean flag) {
deprecatedFlag = flag;
}
public void setMethods(MethodInfo[] mi) {
methods = mi;
modified = true;

@ -1,7 +1,7 @@
/* ConstantPool Copyright (C) 1998-1999 Jochen Hoenicke.
/* ConstantPool Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* FieldInfo Copyright (C) 1998-1999 Jochen Hoenicke.
/* FieldInfo Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -49,12 +49,15 @@ public class FieldInfo extends BinaryInfo {
ConstantPool cp,
DataInputStream input,
int howMuch) throws IOException {
if ((howMuch & KNOWNATTRIBS) != 0 && name.equals("ConstantValue")) {
if (length != 2)
throw new ClassFormatException("ConstantValue attribute"
+ " has wrong length");
int index = input.readUnsignedShort();
constant = cp.getConstant(index);
if (name.equals("ConstantValue")) {
if ((howMuch & KNOWNATTRIBS) != 0) {
if (length != 2)
throw new ClassFormatException("ConstantValue attribute"
+ " has wrong length");
int index = input.readUnsignedShort();
constant = cp.getConstant(index);
} else
input.readFully(new byte[length]);
} else if (name.equals("Synthetic")) {
syntheticFlag = true;
if (length != 0)

@ -1,7 +1,7 @@
/* GrowableConstantPool Copyright (C) 1999 Jochen Hoenicke.
/* GrowableConstantPool Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* Handler Copyright (C) 1999 Jochen Hoenicke.
/* Handler Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* InnerClassInfo Copyright (C) 1999 Jochen Hoenicke.
/* InnerClassInfo Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* Instruction Copyright (C) 1999 Jochen Hoenicke.
/* Instruction Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* LineNumber Copyright (C) 1999 Jochen Hoenicke.
/* LineNumber Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* LocalVariableInfo Copyright (C) 1999 Jochen Hoenicke.
/* LocalVariableInfo Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* MethodInfo Copyright (C) 1998-1999 Jochen Hoenicke.
/* MethodInfo Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -51,11 +51,13 @@ public class MethodInfo extends BinaryInfo {
protected void readAttribute(String name, int length, ConstantPool cp,
DataInputStream input,
int howMuch) throws IOException {
if ((howMuch & KNOWNATTRIBS) != 0 && name.equals("Code")) {
bytecode = new BytecodeInfo(this);
bytecode.read(cp, input);
} else if ((howMuch & KNOWNATTRIBS) != 0
&& name.equals("Exceptions")) {
if (name.equals("Code")) {
if ((howMuch & KNOWNATTRIBS) != 0) {
bytecode = new BytecodeInfo(this);
bytecode.read(cp, input);
} else
input.readFully(new byte[length]);
} else if (name.equals("Exceptions")) {
int count = input.readUnsignedShort();
exceptions = new String[count];
for (int i=0; i< count; i++)

@ -1,7 +1,7 @@
/* Opcodes Copyright (C) 1998-1999 Jochen Hoenicke.
/* Opcodes Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* Reference Copyright (C) 1999 Jochen Hoenicke.
/* Reference Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* SearchPath Copyright (C) 1998-1999 Jochen Hoenicke.
/* SearchPath Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -279,7 +279,7 @@ public class SearchPath {
} catch (SecurityException ex) {
GlobalOptions.err.println
("Warning: Security exception while accessing "
+bases[i]+".");
+ bases[i] + ".");
}
} catch (MalformedURLException ex) {
/* disable entry */
@ -309,6 +309,10 @@ public class SearchPath {
}
public boolean exists(String filename) {
String localFileName =
(java.io.File.separatorChar != '/')
? filename.replace('/', java.io.File.separatorChar)
: filename;
for (int i=0; i<dirs.length; i++) {
if (zipEntries[i] != null) {
if (zipEntries[i].get(filename) != null)
@ -347,11 +351,8 @@ public class SearchPath {
if (ze != null)
return true;
} else {
if (java.io.File.separatorChar != '/')
filename = filename
.replace('/', java.io.File.separatorChar);
try {
File f = new File(dirs[i], filename);
File f = new File(dirs[i], localFileName);
if (f.exists())
return true;
} catch (SecurityException ex) {
@ -369,6 +370,10 @@ public class SearchPath {
* @return An InputStream for the file.
*/
public InputStream getFile(String filename) throws IOException {
String localFileName =
(java.io.File.separatorChar != '/')
? filename.replace('/', java.io.File.separatorChar)
: filename;
for (int i=0; i<dirs.length; i++) {
if (urlzips[i] != null) {
ZipInputStream zis = new ZipInputStream
@ -379,26 +384,26 @@ public class SearchPath {
while ((ze = zis.getNextEntry()) != null) {
if (ze.getName().equals(fullname)) {
///#ifdef JDK11
// The skip method in jdk1.1.7 ZipInputStream
// is buggy. We return a wrapper that fixes
// this.
return new FilterInputStream(zis) {
private byte[] tmpbuf = new byte[512];
public long skip(long n) throws IOException {
long skipped = 0;
while (n > 0) {
int count = read(tmpbuf, 0,
(int)Math.min(n, 512L));
if (count == -1)
return skipped;
skipped += count;
n -= count;
}
return skipped;
}
};
/// // The skip method in jdk1.1.7 ZipInputStream
/// // is buggy. We return a wrapper that fixes
/// // this.
/// return new FilterInputStream(zis) {
/// private byte[] tmpbuf = new byte[512];
/// public long skip(long n) throws IOException {
/// long skipped = 0;
/// while (n > 0) {
/// int count = read(tmpbuf, 0,
/// (int)Math.min(n, 512L));
/// if (count == -1)
/// return skipped;
/// skipped += count;
/// n -= count;
/// }
/// return skipped;
/// }
/// };
///#else
/// return zis;
return zis;
///#endif
}
zis.closeEntry();
@ -413,8 +418,8 @@ public class SearchPath {
return conn.getInputStream();
} catch (SecurityException ex) {
GlobalOptions.err.println("Warning: SecurityException"
+" while accessing "
+bases[i]+filename);
+ " while accessing "
+ bases[i] + filename);
ex.printStackTrace(GlobalOptions.err);
/* ignore and take next element */
} catch (FileNotFoundException ex) {
@ -431,17 +436,14 @@ public class SearchPath {
if (ze != null)
return zips[i].getInputStream(ze);
} else {
if (java.io.File.separatorChar != '/')
filename = filename
.replace('/', java.io.File.separatorChar);
try {
File f = new File(dirs[i], filename);
File f = new File(dirs[i], localFileName);
if (f.exists())
return new FileInputStream(f);
} catch (SecurityException ex) {
GlobalOptions.err.println("Warning: SecurityException"
+" while accessing "
+dirs[i]+filename);
+ " while accessing "
+ dirs[i] + localFileName);
/* ignore and take next element */
}
}
@ -457,6 +459,10 @@ public class SearchPath {
* @return true, if filename exists and is a directory, false otherwise.
*/
public boolean isDirectory(String filename) {
String localFileName =
(java.io.File.separatorChar != '/')
? filename.replace('/', java.io.File.separatorChar)
: filename;
for (int i=0; i<dirs.length; i++) {
if (dirs[i] == null)
continue;
@ -467,17 +473,14 @@ public class SearchPath {
if (zipEntries[i].containsKey(filename))
return true;
} else {
if (java.io.File.separatorChar != '/')
filename = filename
.replace('/', java.io.File.separatorChar);
try {
File f = new File(dirs[i], filename);
File f = new File(dirs[i], localFileName);
if (f.exists())
return f.isDirectory();
} catch (SecurityException ex) {
GlobalOptions.err.println("Warning: SecurityException"
+" while accessing "
+dirs[i]+filename);
+ " while accessing "
+ dirs[i] + localFileName);
}
}
}
@ -543,11 +546,13 @@ public class SearchPath {
if (f.exists() && f.isDirectory()) {
currentDir = f;
files = f.list();
fileNr = 0;
}
} catch (SecurityException ex) {
GlobalOptions.err.println("Warning: SecurityException"
+" while accessing "
+dirs[pathNr]+localDirName);
GlobalOptions.err.println
("Warning: SecurityException"
+ " while accessing "
+ dirs[pathNr] + localDirName);
/* ignore and take next element */
}
}

@ -1,7 +1,7 @@
/* TypeSignature Copyright (C) 1999 Jochen Hoenicke.
/* TypeSignature Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* Analyzer Copyright (C) 1998-1999 Jochen Hoenicke.
/* Analyzer Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* Applet Copyright (C) 1999 Jochen Hoenicke.
/* Applet Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* ClassAnalyzer Copyright (C) 1998-1999 Jochen Hoenicke.
/* ClassAnalyzer Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -57,6 +57,12 @@ public class ClassAnalyzer
* The minimal visible complexity.
*/
private static double STEP_COMPLEXITY = 0.03;
/**
* The value of the strictfp modifier.
* JDK1.1 doesn't define it.
*/
private static int STRICTFP = 0x800;
double methodComplexity = 0.0;
double innerComplexity = 0.0;
@ -126,6 +132,10 @@ public class ClassAnalyzer
return Modifier.isStatic(modifiers);
}
public final boolean isStrictFP() {
return (modifiers & STRICTFP) != 0;
}
public FieldAnalyzer getField(int index) {
return fields[index];
}
@ -231,6 +241,17 @@ public class ClassAnalyzer
staticConstructor = methods[j];
else
constrVector.addElement(methods[j]);
/* Java bytecode can't have strictfp modifier for
* classes, while java can't have strictfp modifier
* for constructors. We handle the difference here.
*
* If only a few constructors are strictfp and the
* methods aren't this would add too much strictfp,
* but that isn't really dangerous.
*/
if (methods[j].isStrictFP())
modifiers |= STRICTFP;
}
methodComplexity += methods[j].getComplexity();
}
@ -400,9 +421,78 @@ public class ClassAnalyzer
public void dumpDeclaration(TabbedPrintWriter writer) throws IOException
{
dumpSource(writer);
dumpDeclaration(writer, null, 0.0, 0.0);
}
public void dumpDeclaration(TabbedPrintWriter writer,
ProgressListener pl, double done, double scale)
throws IOException
{
if (fields == null) {
/* This means that the class could not be loaded.
* give up.
*/
return;
}
writer.startOp(writer.NO_PAREN, 0);
/* Clear the SUPER bit, which is also used as SYNCHRONIZED bit. */
int modifiedModifiers = modifiers & ~(Modifier.SYNCHRONIZED
| STRICTFP);
if (clazz.isInterface())
/* interfaces are implicitily abstract */
modifiedModifiers &= ~Modifier.ABSTRACT;
if (parent instanceof MethodAnalyzer) {
/* method scope classes are implicitly private */
modifiedModifiers &= ~Modifier.PRIVATE;
/* anonymous classes are implicitly final */
if (name == null)
modifiedModifiers &= ~Modifier.FINAL;
}
String modif = Modifier.toString(modifiedModifiers);
if (modif.length() > 0)
writer.print(modif + " ");
if (isStrictFP()) {
/* The STRICTFP modifier is set.
* We handle it, since java.lang.reflect.Modifier is too dumb.
*/
writer.print("strictfp ");
}
/* interface is in modif */
if (!clazz.isInterface())
writer.print("class ");
writer.print(name);
ClassInfo superClazz = clazz.getSuperclass();
if (superClazz != null &&
superClazz != ClassInfo.javaLangObject) {
writer.breakOp();
writer.print(" extends " + (writer.getClassString
(superClazz, Scope.CLASSNAME)));
}
ClassInfo[] interfaces = clazz.getInterfaces();
if (interfaces.length > 0) {
writer.breakOp();
writer.print(clazz.isInterface() ? " extends " : " implements ");
writer.startOp(writer.EXPL_PAREN, 1);
for (int i=0; i < interfaces.length; i++) {
if (i > 0) {
writer.print(", ");
writer.breakOp();
}
writer.print(writer.getClassString
(interfaces[i], Scope.CLASSNAME));
}
writer.endOp();
}
writer.println();
writer.openBraceClass();
writer.tab();
dumpBlock(writer, pl, done, scale);
writer.untab();
writer.closeBraceClass();
}
public void dumpBlock(TabbedPrintWriter writer)
throws IOException
{
@ -501,6 +591,7 @@ public class ClassAnalyzer
needNewLine = true;
}
writer.popScope();
clazz.dropInfo(clazz.KNOWNATTRIBS | clazz.UNKNOWNATTRIBS);
}
public void dumpSource(TabbedPrintWriter writer)
@ -513,67 +604,8 @@ public class ClassAnalyzer
ProgressListener pl, double done, double scale)
throws IOException
{
if (fields == null) {
/* This means that the class could not be loaded.
* give up.
*/
return;
}
writer.startOp(writer.NO_PAREN, 0);
/* Clear the SUPER bit, which is also used as SYNCHRONIZED bit. */
int modifiedModifiers = modifiers & ~Modifier.SYNCHRONIZED;
if (clazz.isInterface())
/* interfaces are implicitily abstract */
modifiedModifiers &= ~Modifier.ABSTRACT;
if (parent instanceof MethodAnalyzer) {
/* method scope classes are implicitly private */
modifiedModifiers &= ~Modifier.PRIVATE;
/* anonymous classes are implicitly final */
if (name == null)
modifiedModifiers &= ~Modifier.FINAL;
}
String modif = Modifier.toString(modifiedModifiers);
if (modif.length() > 0)
writer.print(modif + " ");
/* interface is in modif */
if (!clazz.isInterface())
writer.print("class ");
writer.print(name);
ClassInfo superClazz = clazz.getSuperclass();
if (superClazz != null &&
superClazz != ClassInfo.javaLangObject) {
writer.breakOp();
writer.print(" extends " + (writer.getClassString
(superClazz, Scope.CLASSNAME)));
}
ClassInfo[] interfaces = clazz.getInterfaces();
if (interfaces.length > 0) {
writer.breakOp();
writer.print(clazz.isInterface() ? " extends " : " implements ");
writer.startOp(writer.EXPL_PAREN, 1);
for (int i=0; i < interfaces.length; i++) {
if (i > 0) {
writer.print(", ");
writer.breakOp();
}
writer.print(writer.getClassString
(interfaces[i], Scope.CLASSNAME));
}
writer.endOp();
}
dumpDeclaration(writer, pl, done, scale);
writer.println();
writer.openBrace();
writer.tab();
dumpBlock(writer, pl, done, scale);
writer.untab();
if (parent instanceof MethodAnalyzer) {
/* This is a method scope class */
writer.closeBraceNoSpace();
} else
writer.closeBrace();
clazz.dropInfo(clazz.KNOWNATTRIBS | clazz.UNKNOWNATTRIBS);
}
public void dumpJavaFile(TabbedPrintWriter writer)
@ -611,7 +643,11 @@ public class ClassAnalyzer
}
public boolean conflicts(String name, int usageType) {
ClassInfo info = clazz;
return conflicts(clazz, name, usageType);
}
private static boolean conflicts(ClassInfo info,
String name, int usageType) {
while (info != null) {
if (usageType == NOSUPERMETHODNAME || usageType == METHODNAME) {
MethodInfo[] minfos = info.getMethods();
@ -639,6 +675,11 @@ public class ClassAnalyzer
if (usageType == NOSUPERFIELDNAME
|| usageType == NOSUPERMETHODNAME)
return false;
ClassInfo[] ifaces = info.getInterfaces();
for (int i = 0; i < ifaces.length; i++)
if (conflicts(ifaces[i], name, usageType))
return true;
info = info.getSuperclass();
}
return false;

@ -1,7 +1,7 @@
/* ClassDeclarer Copyright (C) 1999 Jochen Hoenicke.
/* ClassDeclarer Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* DeadCodeAnalysis Copyright (C) 1999 Jochen Hoenicke.
/* DeadCodeAnalysis Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* Declarable Copyright (C) 1999 Jochen Hoenicke.
/* Declarable Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* Decompiler Copyright (C) 2000 Jochen Hoenicke.
/* Decompiler Copyright (C) 2000-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -103,6 +103,8 @@ public class Decompiler {
Options.outputStyle = Options.GNU_STYLE;
else if (value.equals("sun"))
Options.outputStyle = Options.SUN_STYLE;
else if (value.equals("pascal"))
Options.outputStyle = Options.PASCAL_STYLE;
else
throw new IllegalArgumentException("Invalid style "+value);
return;

@ -1,7 +1,7 @@
/* FieldAnalyzer Copyright (C) 1998-1999 Jochen Hoenicke.
/* FieldAnalyzer Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -57,7 +57,7 @@ public class FieldAnalyzer implements Analyzer {
if (fd.getConstant() != null) {
constant = new ConstOperator(fd.getConstant());
constant.setType(type);
constant.makeInitializer();
constant.makeInitializer(type);
}
}
@ -107,7 +107,7 @@ public class FieldAnalyzer implements Analyzer {
}
analyzedSynthetic();
} else
expr.makeInitializer();
expr.makeInitializer(type);
constant = expr;
return true;
@ -187,11 +187,6 @@ public class FieldAnalyzer implements Analyzer {
writer.breakOp();
writer.print(" = ");
constant.dumpExpression(writer.IMPL_PAREN, writer);
} else if ((modifiers & (Modifier.STATIC | Modifier.FINAL))
== (Modifier.STATIC | Modifier.FINAL)) {
/* Static final fields must always be initialized */
writer.breakOp();
writer.print(" = null");
}
writer.endOp();
writer.println(";");

@ -1,7 +1,7 @@
/* ImportHandler Copyright (C) 1998-1999 Jochen Hoenicke.
/* ImportHandler Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* LocalInfo Copyright (C) 1998-1999 Jochen Hoenicke.
/* LocalInfo Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -126,56 +126,58 @@ public class LocalInfo implements Declarable {
* If this is called with ourself nothing will happen.
* @param li the local info that we want to shadow.
*/
public void combineWith(LocalInfo li) {
li = li.getLocalInfo();
if (shadow != null) {
getLocalInfo().combineWith(li);
} else {
if (this != li) {
shadow = li;
if (!nameIsGenerated)
shadow.name = name;
if (constExpr != null) {
if (shadow.constExpr != null)
throw new jode.AssertError
("local has multiple constExpr");
shadow.constExpr = constExpr;
}
// GlobalOptions.err.println("combining "+name+"("+type+") and "
// +shadow.name+"("+shadow.type+")");
shadow.setType(type);
boolean needTypeUpdate = !li.type.equals(type);
java.util.Enumeration enum = operators.elements();
while (enum.hasMoreElements()) {
LocalVarOperator lvo =
(LocalVarOperator) enum.nextElement();
if (needTypeUpdate) {
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_TYPES) != 0)
GlobalOptions.err.println("updating " + lvo);
lvo.updateType();
}
shadow.operators.addElement(lvo);
}
enum = hints.elements();
while (enum.hasMoreElements()) {
Object hint = enum.nextElement();
if (!shadow.hints.contains(hint))
shadow.hints.addElement(hint);
}
public void combineWith(LocalInfo shadow) {
if (this.shadow != null) {
getLocalInfo().combineWith(shadow);
return;
}
/* Clear unused fields, to allow garbage collection.
*/
type = null;
name = null;
operators = null;
}
}
shadow = shadow.getLocalInfo();
if (this == shadow)
return;
this.shadow = shadow;
if (!nameIsGenerated)
shadow.name = name;
if (constExpr != null) {
if (shadow.constExpr != null)
throw new jode.AssertError
("local has multiple constExpr");
shadow.constExpr = constExpr;
}
// GlobalOptions.err.println("combining "+name+"("+type+") and "
// +shadow.name+"("+shadow.type+")");
shadow.setType(type);
boolean needTypeUpdate = !shadow.type.equals(type);
java.util.Enumeration enumeration = operators.elements();
while (enumeration.hasMoreElements()) {
LocalVarOperator lvo =
(LocalVarOperator) enumeration.nextElement();
if (needTypeUpdate) {
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_TYPES) != 0)
GlobalOptions.err.println("updating " + lvo);
lvo.updateType();
}
shadow.operators.addElement(lvo);
}
enumeration = hints.elements();
while (enumeration.hasMoreElements()) {
Object hint = enumeration.nextElement();
if (!shadow.hints.contains(hint))
shadow.hints.addElement(hint);
}
/* Clear unused fields, to allow garbage collection.
*/
type = null;
name = null;
operators = null;
}
/**
@ -207,9 +209,9 @@ public class LocalInfo implements Declarable {
return shadow.guessName();
}
if (name == null) {
Enumeration enum = hints.elements();
while (enum.hasMoreElements()) {
Hint hint = (Hint) enum.nextElement();
Enumeration enumeration = hints.elements();
while (enumeration.hasMoreElements()) {
Hint hint = (Hint) enumeration.nextElement();
if (type.isOfType(hint.getType())) {
name = hint.getName();
setType(hint.getType());
@ -320,9 +322,9 @@ public class LocalInfo implements Declarable {
if (!li.type.equals(newType)) {
li.type = newType;
java.util.Enumeration enum = li.operators.elements();
while (enum.hasMoreElements()) {
LocalVarOperator lvo = (LocalVarOperator) enum.nextElement();
java.util.Enumeration enumeration = li.operators.elements();
while (enumeration.hasMoreElements()) {
LocalVarOperator lvo = (LocalVarOperator) enumeration.nextElement();
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_TYPES) != 0)
GlobalOptions.err.println("updating "+lvo);
lvo.updateType();
@ -359,15 +361,13 @@ public class LocalInfo implements Declarable {
}
public boolean isConstant() {
LocalInfo li = getLocalInfo();
Enumeration enum = li.operators.elements();
int writes = 0;
while (enum.hasMoreElements()) {
if (((LocalVarOperator) enum.nextElement()).isWrite())
writes++;
}
if (writes > 1)
return false;
/* Checking if a local can be declared final is tricky,
* since it can also be the case if it is written in
* the "then" and "else" part of an if statement.
*
* We return true now, otherwise some code would not be
* decompilable.
*/
return true;
}
@ -377,14 +377,13 @@ public class LocalInfo implements Declarable {
public boolean markFinal() {
LocalInfo li = getLocalInfo();
Enumeration enum = li.operators.elements();
Enumeration enumeration = li.operators.elements();
int writes = 0;
while (enum.hasMoreElements()) {
if (((LocalVarOperator) enum.nextElement()).isWrite())
while (enumeration.hasMoreElements()) {
if (((LocalVarOperator) enumeration.nextElement()).isWrite())
writes++;
}
if (writes > 1)
return false;
/* FIXME: Check if declaring final is okay */
li.isFinal = true;
return true;
}

@ -1,7 +1,7 @@
/* LocalVarEntry Copyright (C) 1999 Jochen Hoenicke.
/* LocalVarEntry Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* LocalVariableRangeList Copyright (C) 1998-1999 Jochen Hoenicke.
/* LocalVariableRangeList Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* LocalVariableTable Copyright (C) 1998-1999 Jochen Hoenicke.
/* LocalVariableTable Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* Main Copyright (C) 1998-1999 Jochen Hoenicke.
/* Main Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -19,7 +19,6 @@
package jode.decompiler;
import jode.bytecode.ClassInfo;
import jode.bytecode.SearchPath;
import jode.GlobalOptions;
import java.io.BufferedOutputStream;
@ -28,13 +27,19 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.zip.ZipOutputStream;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.Enumeration;
import java.util.Vector;
import gnu.getopt.LongOpt;
import gnu.getopt.Getopt;
public class Main extends Options {
private static int successCount = 0;
private static Vector failedClasses;
private static final int OPTION_START=0x10000;
private static final int OPTION_END =0x20000;
@ -73,7 +78,10 @@ public class Main extends Options {
public static void usage() {
PrintWriter err = GlobalOptions.err;
err.println("Version: " + GlobalOptions.version);
err.println("Usage: java jode.decompiler.Main [OPTIONS]... [CLASSES]...");
err.println("Usage: java jode.decompiler.Main [OPTION]* {CLASS|JAR}*");
err.println("Give a fully qualified CLASS name, e.g. jode.decompiler.Main, if you want to");
err.println("decompile a single class, or a JAR file containing many classes.");
err.println("OPTION is any of these:");
err.println(" -h, --help "+
"show this information.");
err.println(" -V, --version "+
@ -94,9 +102,13 @@ public class Main extends Options {
err.println(" "+
"and packages with more then pkglimit used classes.");
err.println(" "+
"Limit 0 means, never import, default is 0,1.");
"Limit 0 means never import. Default is 0,1.");
err.println(" -D, --debug=... "+
"use --debug=help for more information.");
err.println("The following options can be turned on or off with `yes' or `no' argument.");
err.println("NOTE: The following options can be turned on or off with `yes' or `no'.");
err.println("The options tagged with (default) are normally on. Omitting the yes/no");
err.println("argument will toggle the option, e.g. --verify is equivalent to --verify=no.");
err.println(" --inner "+
"decompile inner classes (default).");
err.println(" --anonymous "+
@ -106,7 +118,7 @@ public class Main extends Options {
err.println(" --lvt "+
"use the local variable table (default).");
err.println(" --pretty "+
"use `pretty' names for local variables.");
"use `pretty' names for local variables (default).");
err.println(" --push "+
"allow PUSH instructions in output.");
err.println(" --decrypt "+
@ -116,10 +128,7 @@ public class Main extends Options {
err.println(" --immediate "+
"output source immediately (may produce buggy code).");
err.println(" --verify "+
"verify code before decompiling it.");
err.println("Debugging options, mainly used to debug this decompiler:");
err.println(" -D, --debug=... "+
"use --debug=help for more information.");
"verify code before decompiling it (default).");
}
public static boolean handleOption(int option, int longind, String arg) {
@ -131,21 +140,121 @@ public class Main extends Options {
options &= ~(1 << option);
else {
GlobalOptions.err.println
("jode.decompiler.Main: option --"+longOptions[longind].getName()
+" takes one of `yes', `no', `on', `off' as parameter");
("jode.decompiler.Main: option --"
+ longOptions[longind].getName()
+ " takes one of `yes', `no', `on', `off' as parameter");
return false;
}
return true;
}
public static void decompileClass(String className,
ZipOutputStream destZip, String destDir,
TabbedPrintWriter writer,
ImportHandler imports) {
try {
ClassInfo clazz;
try {
clazz = ClassInfo.forName(className);
} catch (IllegalArgumentException ex) {
GlobalOptions.err.println
("`"+className+"' is not a class name");
return;
}
if (skipClass(clazz))
return;
String filename =
className.replace('.', File.separatorChar)+".java";
if (destZip != null) {
writer.flush();
destZip.putNextEntry(new ZipEntry(filename));
} else if (destDir != null) {
File file = new File (destDir, filename);
File directory = new File(file.getParent());
if (!directory.exists() && !directory.mkdirs()) {
GlobalOptions.err.println
("Could not create directory "
+ directory.getPath() + ", check permissions.");
}
writer = new TabbedPrintWriter
(new BufferedOutputStream(new FileOutputStream(file)),
imports, false);
}
GlobalOptions.err.println(className);
ClassAnalyzer clazzAna = new ClassAnalyzer(clazz, imports);
clazzAna.dumpJavaFile(writer);
if (destZip != null) {
writer.flush();
destZip.closeEntry();
} else if (destDir != null)
writer.close();
/* Now is a good time to clean up */
System.gc();
successCount++;
} catch (IOException ex) {
failedClasses.addElement(className);
GlobalOptions.err.println
("Can't write source of "+className+".");
GlobalOptions.err.println("Check the permissions.");
ex.printStackTrace(GlobalOptions.err);
} catch (Throwable t) {
failedClasses.addElement(className);
GlobalOptions.err.println
("Failed to decompile "+className+".");
t.printStackTrace(GlobalOptions.err);
}
}
public static void main(String[] params) {
try {
decompile(params);
} catch (ExceptionInInitializerError ex) {
ex.getException().printStackTrace();
} catch (Throwable ex) {
ex.printStackTrace();
}
printSummary();
/* When AWT applications are compiled with insufficient
* classpath the type guessing by reflection code can
* generate an awt thread that will prevent normal
* exiting.
*/
System.exit(0);
}
private static void printSummary() {
GlobalOptions.err.println();
if (failedClasses.size() > 0) {
GlobalOptions.err.println("Failed to decompile these classes:");
Enumeration enumeration = failedClasses.elements();
while (enumeration.hasMoreElements()) {
GlobalOptions.err.println("\t" + enumeration.nextElement());
}
GlobalOptions.err.println("Failed to decompile " + failedClasses.size() + " classes.");
}
GlobalOptions.err.println("Decompiled " + successCount + " classes.");
}
public static void decompile(String[] params) {
if (params.length == 0) {
usage();
return;
}
failedClasses = new Vector();
String classPath = System.getProperty("java.class.path")
.replace(File.pathSeparatorChar, SearchPath.altPathSeparatorChar);
.replace(File.pathSeparatorChar, Decompiler.altPathSeparatorChar);
String bootClassPath = System.getProperty("sun.boot.class.path");
if (bootClassPath != null)
classPath += Decompiler.altPathSeparatorChar
+ bootClassPath.replace(File.pathSeparatorChar,
Decompiler.altPathSeparatorChar);
String destDir = null;
int importPackageLimit = ImportHandler.DEFAULT_PACKAGE_LIMIT;
@ -202,6 +311,8 @@ public class Main extends Options {
outputStyle = SUN_STYLE;
else if ("gnu".startsWith(arg))
outputStyle = GNU_STYLE;
else if ("pascal".startsWith(arg))
outputStyle = Options.PASCAL_STYLE;
else {
GlobalOptions.err.println
("jode.decompiler.Main: Unknown style `"+arg+"'.");
@ -246,7 +357,7 @@ public class Main extends Options {
}
if (errorInParams)
return;
ClassInfo.setClassPath(classPath.toString());
ClassInfo.setClassPath(classPath);
ImportHandler imports = new ImportHandler(importPackageLimit,
importClassLimit);
@ -268,51 +379,32 @@ public class Main extends Options {
}
for (int i= g.getOptind(); i< params.length; i++) {
try {
ClassInfo clazz;
try {
clazz = ClassInfo.forName(params[i]);
} catch (IllegalArgumentException ex) {
GlobalOptions.err.println
("`"+params[i]+"' is not a class name");
continue;
}
if (skipClass(clazz))
continue;
String filename =
params[i].replace('.', File.separatorChar)+".java";
if (destZip != null) {
writer.flush();
destZip.putNextEntry(new ZipEntry(filename));
} else if (destDir != null) {
File file = new File (destDir, filename);
File directory = new File(file.getParent());
if (!directory.exists() && !directory.mkdirs()) {
GlobalOptions.err.println
("Could not create directory "
+ directory.getPath() + ", check permissions.");
if ((params[i].endsWith(".jar") || params[i].endsWith(".zip"))
&& new File(params[i]).isFile()) {
/* The user obviously wants to decompile a jar/zip file.
* Lets do him a pleasure and allow this.
*/
ClassInfo.setClassPath(params[i]
+ Decompiler.altPathSeparatorChar
+ classPath);
Enumeration enumeration = new ZipFile(params[i]).entries();
while (enumeration.hasMoreElements()) {
String entry
= ((ZipEntry) enumeration.nextElement()).getName();
if (entry.endsWith(".class")) {
entry = entry.substring(0, entry.length() - 6)
.replace('/', '.');
decompileClass(entry, destZip, destDir,
writer, imports);
}
}
writer = new TabbedPrintWriter
(new BufferedOutputStream(new FileOutputStream(file)),
imports, false);
}
GlobalOptions.err.println(params[i]);
ClassAnalyzer clazzAna = new ClassAnalyzer(clazz, imports);
clazzAna.dumpJavaFile(writer);
if (destZip != null) {
writer.flush();
destZip.closeEntry();
} else if (destDir != null)
writer.close();
/* Now is a good time to clean up */
System.gc();
ClassInfo.setClassPath(classPath);
} else
decompileClass(params[i], destZip, destDir,
writer, imports);
} catch (IOException ex) {
GlobalOptions.err.println
("Can't write source of "+params[i]+".");
GlobalOptions.err.println("Check the permissions.");
("Can't read zip file " + params[i] + ".");
ex.printStackTrace(GlobalOptions.err);
}
}

@ -1,7 +1,7 @@
/* MethodAnalyzer Copyright (C) 1998-1999 Jochen Hoenicke.
/* MethodAnalyzer Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -27,6 +27,7 @@ import jode.bytecode.Handler;
import jode.bytecode.Instruction;
import jode.bytecode.LocalVariableInfo;
import jode.jvm.SyntheticAnalyzer;
import jode.decompiler.Options;
import jode.type.*;
import jode.expr.Expression;
import jode.expr.ConstOperator;
@ -80,6 +81,11 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
* The minimal visible complexity.
*/
private static double STEP_COMPLEXITY = 0.01;
/**
* The value of the strictfp modifier.
* JDK1.1 doesn't define it.
*/
private static int STRICTFP = 0x800;
/**
* The import handler where we should register our types.
*/
@ -316,6 +322,14 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
return minfo.isSynthetic();
}
/**
* Checks if this method is strictfp
* @return true, iff this method is synthetic.
*/
public final boolean isStrictFP() {
return (minfo.getModifiers() & STRICTFP) != 0;
}
/**
* Tells if this method is the constructor$xx method generated by jikes.
* @param value true, iff this method is the jikes constructor.
@ -593,7 +607,7 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
CodeVerifier verifier
= new CodeVerifier(getClazz(), minfo, code);
try {
verifier.verify();
verifier.verify();
} catch (VerifyException ex) {
ex.printStackTrace(GlobalOptions.err);
throw new jode.AssertError("Verification error");
@ -660,9 +674,9 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
*/
public void makeDeclaration(Set done) {
if (innerAnalyzers != null) {
for (Enumeration enum = innerAnalyzers.elements();
enum.hasMoreElements(); ) {
ClassAnalyzer classAna = (ClassAnalyzer) enum.nextElement();
for (Enumeration enumeration = innerAnalyzers.elements();
enumeration.hasMoreElements(); ) {
ClassAnalyzer classAna = (ClassAnalyzer) enumeration.nextElement();
if (classAna.getParent() == this) {
OuterValues innerOV = classAna.getOuterValues();
for (int i=0; i < innerOV.getCount(); i++) {
@ -678,9 +692,9 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
}
}
for (Enumeration enum = allLocals.elements();
enum.hasMoreElements(); ) {
LocalInfo li = (LocalInfo)enum.nextElement();
for (Enumeration enumeration = allLocals.elements();
enumeration.hasMoreElements(); ) {
LocalInfo li = (LocalInfo)enumeration.nextElement();
if (!li.isShadow())
imports.useType(li.getType());
}
@ -719,7 +733,7 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
if (synth.getKind() == synth.GETCLASS)
return true;
if (synth.getKind() >= synth.ACCESSGETFIELD
&& synth.getKind() <= synth.ACCESSCONSTRUCTOR
&& synth.getKind() <= synth.ACCESSDUPPUTSTATIC
&& (Options.options & Options.OPTION_INNER) != 0
&& (Options.options & Options.OPTION_ANON) != 0)
return true;
@ -746,10 +760,12 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
if (isJikesBlockInitializer)
return true;
/* The default constructor must be empty of course */
/* The default constructor must be empty
* and mustn't throw exceptions */
if (getMethodHeader() == null
|| !(getMethodHeader().getBlock() instanceof jode.flow.EmptyBlock)
|| !getMethodHeader().hasNoJumps())
|| !getMethodHeader().hasNoJumps()
|| exceptions.length > 0)
return false;
if (declareAsConstructor
@ -839,6 +855,7 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
if (isConstructor() && isStatic())
modifiedModifiers &= ~(Modifier.FINAL | Modifier.PUBLIC
| Modifier.PROTECTED | Modifier.PRIVATE);
modifiedModifiers &= ~STRICTFP;
writer.startOp(writer.NO_PAREN, 1);
String delim = "";
@ -847,11 +864,28 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
delim = " ";
}
String modif = Modifier.toString(modifiedModifiers);
if (modif.length() > 0) {
writer.print(delim + modif);
delim = " ";
}
if (isStrictFP()) {
/* The STRICTFP modifier is set.
* We handle it, since java.lang.reflect.Modifier is too dumb.
*/
/* If STRICTFP is already set for class don't set it for method.
* And don't set STRICTFP for native methods or constructors.
*/
if (!classAnalyzer.isStrictFP()
&& !isConstructor()
&& (modifiedModifiers & Modifier.NATIVE) == 0) {
writer.print(delim + "strictfp");
delim = " ";
}
}
if (isConstructor
&& (isStatic()
|| (classAnalyzer.getName() == null
@ -866,6 +900,8 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
writer.print(" " + methodName);
}
writer.breakOp();
if ((Options.outputStyle & Options.GNU_SPACING) != 0)
writer.print(" ");
writer.print("(");
writer.startOp(writer.EXPL_PAREN, 0);
int offset = skipParams + (isStatic() ? 0 : 1);
@ -895,11 +931,11 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
}
writer.endOp();
if (code != null) {
writer.openBrace();
writer.openBraceNoIndent();
writer.tab();
methodHeader.dumpSource(writer);
writer.untab();
writer.closeBrace();
writer.closeBraceNoIndent();
} else
writer.println(";");
writer.popScope();
@ -911,9 +947,9 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
* exists.
*/
public LocalInfo findLocal(String name) {
Enumeration enum = allLocals.elements();
while (enum.hasMoreElements()) {
LocalInfo li = (LocalInfo) enum.nextElement();
Enumeration enumeration = allLocals.elements();
while (enumeration.hasMoreElements()) {
LocalInfo li = (LocalInfo) enumeration.nextElement();
if (li.getName().equals(name))
return li;
}
@ -928,9 +964,9 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
*/
public ClassAnalyzer findAnonClass(String name) {
if (innerAnalyzers != null) {
Enumeration enum = innerAnalyzers.elements();
while (enum.hasMoreElements()) {
ClassAnalyzer classAna = (ClassAnalyzer) enum.nextElement();
Enumeration enumeration = innerAnalyzers.elements();
while (enumeration.hasMoreElements()) {
ClassAnalyzer classAna = (ClassAnalyzer) enumeration.nextElement();
if (classAna.getParent() == this
&& classAna.getName() != null
&& classAna.getName().equals(name)) {
@ -1008,8 +1044,7 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
expr).getSubExpressions()[0];
if (expr instanceof ThisOperator) {
outerValueArray[j] =
new ThisOperator(((ThisOperator)
expr).getClassInfo());
new ThisOperator(((ThisOperator) expr).getClassInfo());
continue;
}
LocalInfo li = null;
@ -1080,9 +1115,9 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
*/
public ClassAnalyzer getClassAnalyzer(ClassInfo cinfo) {
if (innerAnalyzers != null) {
Enumeration enum = innerAnalyzers.elements();
while (enum.hasMoreElements()) {
ClassAnalyzer classAna = (ClassAnalyzer) enum.nextElement();
Enumeration enumeration = innerAnalyzers.elements();
while (enumeration.hasMoreElements()) {
ClassAnalyzer classAna = (ClassAnalyzer) enumeration.nextElement();
if (classAna.getClazz().equals(cinfo)) {
if (classAna.getParent() != this) {
ClassDeclarer declarer = classAna.getParent();
@ -1115,9 +1150,9 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
if (usedAnalyzers != null)
used.addAll(usedAnalyzers);
if (innerAnalyzers != null) {
Enumeration enum = innerAnalyzers.elements();
while (enum.hasMoreElements()) {
ClassAnalyzer classAna = (ClassAnalyzer) enum.nextElement();
Enumeration enumeration = innerAnalyzers.elements();
while (enumeration.hasMoreElements()) {
ClassAnalyzer classAna = (ClassAnalyzer) enumeration.nextElement();
if (classAna.getParent() == this)
classAna.fillDeclarables(used);
}

@ -1,7 +1,7 @@
/* Opcodes Copyright (C) 1999 Jochen Hoenicke.
/* Opcodes Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* Options Copyright (C) 1998-1999 Jochen Hoenicke.
/* Options Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -22,10 +22,13 @@ import jode.bytecode.ClassInfo;
import jode.bytecode.InnerClassInfo;
public class Options {
public static final int TAB_SIZE_MASK = 0x0f;
public static final int BRACE_AT_EOL = 0x10;
public static final int SUN_STYLE = 0x14;
public static final int GNU_STYLE = 0x02;
public static final int TAB_SIZE_MASK = 0x0f;
public static final int BRACE_AT_EOL = 0x10;
public static final int BRACE_FLUSH_LEFT = 0x20;
public static final int GNU_SPACING = 0x40;
public static final int SUN_STYLE = 0x14;
public static final int GNU_STYLE = 0x42;
public static final int PASCAL_STYLE = 0x24;
public static final int OPTION_LVT = 0x0001;
public static final int OPTION_INNER = 0x0002;

@ -1,7 +1,7 @@
/* OuterValueListener Copyright (C) 1999 Jochen Hoenicke.
/* OuterValueListener Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,12 +10,13 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
*/
package jode.decompiler;
/**

@ -1,7 +1,7 @@
/* OuterValues Copyright (C) 1998-1999 Jochen Hoenicke.
/* OuterValues Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -71,6 +71,7 @@ public class OuterValues
private Expression[] head;
private Vector ovListeners;
private boolean jikesAnonymousInner;
private boolean implicitOuterClass;
/**
* The maximal number of parameters used for outer values.
@ -270,6 +271,17 @@ public class OuterValues
return jikesAnonymousInner;
}
/**
* Javac 1.3 doesn't give an outer class reference for anonymous
* classes that extend inner classes, provided the outer class is
* the normal this parameter. Instead it takes a normal outer
* value parameter for this. This method tells if this is such a
* class.
*/
public boolean isImplicitOuterClass() {
return implicitOuterClass;
}
public void addOuterValueListener(OuterValueListener l) {
if (ovListeners == null)
ovListeners = new Vector();
@ -285,6 +297,10 @@ public class OuterValues
jikesAnonymousInner = value;
}
public void setImplicitOuterClass(boolean value) {
implicitOuterClass = value;
}
private static int countSlots(Expression[] exprs, int length) {
int slots = 0;
for (int i=0; i < length; i++)
@ -324,9 +340,9 @@ public class OuterValues
}
if (ovListeners != null) {
for (Enumeration enum = ovListeners.elements();
enum.hasMoreElements();)
((OuterValueListener) enum.nextElement()
for (Enumeration enumeration = ovListeners.elements();
enumeration.hasMoreElements();)
((OuterValueListener) enumeration.nextElement()
).shrinkingOuterValues(this, newHeadCount);
}
}
@ -346,8 +362,8 @@ public class OuterValues
}
if (jikesAnonymousInner)
sb.append("!jikesAnonymousInner");
if (implicitOuterClass)
sb.append("!implicitOuterClass");
return sb.append("]").toString();
}
}

@ -1,7 +1,7 @@
/* ProgressListener Copyright (C) 2000 Jochen Hoenicke.
/* ProgressListener Copyright (C) 2000-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* Scope Copyright (C) 1998-1999 Jochen Hoenicke.
/* Scope Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* TabbedPrintWriter Copyright (C) 1998-1999 Jochen Hoenicke.
/* TabbedPrintWriter Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -101,11 +101,8 @@ public class TabbedPrintWriter {
}
public void startOp(int opts, int penalty, int pos) {
if (startPos != -1) {
System.err.println("WARNING: missing breakOp");
Thread.dumpStack();
return;
}
if (startPos != -1)
throw new InternalError("missing breakOp");
startPos = pos;
options = opts;
breakPenalty = penalty;
@ -120,17 +117,15 @@ public class TabbedPrintWriter {
public void endOp(int pos) {
endPos = pos;
if (childBPs.size() == 1) {
BreakPoint child =
(BreakPoint) currentBP.childBPs.elementAt(0);
if (child.startPos == -1) {
startPos = endPos = -1;
childBPs = null;
} else if (child.startPos == currentBP.startPos
&& child.endPos == currentBP.endPos) {
if (options == DONT_BREAK)
options = child.options;
childBPs = child.childBPs;
}
/* There is no breakpoint in this op, replace this with
* our child, if possible.
*/
BreakPoint child = (BreakPoint) childBPs.elementAt(0);
options = Math.min(options, child.options);
startPos = child.startPos;
endPos = child.endPos;
breakPenalty = child.breakPenalty;
childBPs = child.childBPs;
}
}
@ -148,16 +143,16 @@ public class TabbedPrintWriter {
String parens = "{\010{}\010}<\010<>\010>[\010[]\010]`\010`'\010'"
.substring(options*6, options*6+6);
pw.print(parens.substring(0,3));
Enumeration enum = childBPs.elements();
Enumeration enumeration = childBPs.elements();
int cur = startPos;
BreakPoint child = (BreakPoint) enum.nextElement();
BreakPoint child = (BreakPoint) enumeration.nextElement();
if (child.startPos >= 0) {
pw.print(line.substring(cur, child.startPos));
child.dumpRegion(line);
cur = child.endPos;
}
while (enum.hasMoreElements()) {
child = (BreakPoint) enum.nextElement();
while (enumeration.hasMoreElements()) {
child = (BreakPoint) enumeration.nextElement();
pw.print(line.substring(cur, child.breakPos));
pw.print("!\010!"+breakPenalty);
cur = child.breakPos;
@ -187,9 +182,9 @@ public class TabbedPrintWriter {
indent++;
}
Enumeration enum = childBPs.elements();
Enumeration enumeration = childBPs.elements();
int cur = startPos;
BreakPoint child = (BreakPoint) enum.nextElement();
BreakPoint child = (BreakPoint) enumeration.nextElement();
if (child.startPos >= 0) {
pw.print(line.substring(cur, child.startPos));
child.printRegion(indent + child.startPos - cur, line);
@ -198,8 +193,8 @@ public class TabbedPrintWriter {
if (options == NO_PAREN)
indent += indentsize;
String indentStr = makeIndentStr(indent);
while (enum.hasMoreElements()) {
child = (BreakPoint) enum.nextElement();
while (enumeration.hasMoreElements()) {
child = (BreakPoint) enumeration.nextElement();
pw.print(line.substring(cur, child.breakPos));
pw.println();
pw.print(indentStr);
@ -323,14 +318,14 @@ public class TabbedPrintWriter {
lastSpace -= 2;
}
Enumeration enum = childBPs.elements();
Enumeration enumeration = childBPs.elements();
childBPs = new Vector();
int currInd = 0;
BreakPoint lastChild, nextChild;
boolean indentNext = options == NO_PAREN;
for (lastChild = (BreakPoint) enum.nextElement();
enum.hasMoreElements(); lastChild = nextChild) {
nextChild = (BreakPoint) enum.nextElement();
for (lastChild = (BreakPoint) enumeration.nextElement();
enumeration.hasMoreElements(); lastChild = nextChild) {
nextChild = (BreakPoint) enumeration.nextElement();
int childStart = lastChild.breakPos;
int childEnd = nextChild.breakPos;
@ -396,12 +391,12 @@ public class TabbedPrintWriter {
}
if (space < 0)
return minPenalty;
Enumeration enum = childBPs.elements();
Enumeration enumeration = childBPs.elements();
BreakPoint lastChild, nextChild;
boolean indentNext = options == NO_PAREN;
for (lastChild = (BreakPoint) enum.nextElement();
enum.hasMoreElements(); lastChild = nextChild) {
nextChild = (BreakPoint) enum.nextElement();
for (lastChild = (BreakPoint) enumeration.nextElement();
enumeration.hasMoreElements(); lastChild = nextChild) {
nextChild = (BreakPoint) enumeration.nextElement();
int childStart = lastChild.breakPos;
int childEnd = nextChild.breakPos;
@ -541,8 +536,9 @@ public class TabbedPrintWriter {
Stack state = new Stack();
int pos = currentLine.length();
while (currentBP.parentBP != null) {
state.push(new Integer(currentBP.options));
state.push(new Integer(currentBP.breakPenalty));
/* We don't want parentheses or unconventional line breaking */
currentBP.options = DONT_BREAK;
currentBP.endPos = pos;
currentBP = currentBP.parentBP;
}
@ -553,8 +549,7 @@ public class TabbedPrintWriter {
Stack state = (Stack) s;
while (!state.isEmpty()) {
int penalty = ((Integer) state.pop()).intValue();
int options = ((Integer) state.pop()).intValue();
startOp(options, penalty);
startOp(DONT_BREAK, penalty);
}
}
@ -746,12 +741,38 @@ public class TabbedPrintWriter {
} else {
if (currentLine.length() > 0)
println();
if (currentIndent > 0)
if ((Options.outputStyle & Options.BRACE_FLUSH_LEFT) == 0
&& currentIndent > 0)
tab();
println("{");
}
}
public void openBraceClass() {
if (currentLine.length() > 0) {
if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0)
print(" ");
else
println();
}
println("{");
}
/**
* Print a opening brace with the current indentation style.
* Called at the end the line of a method declaration.
*/
public void openBraceNoIndent() {
if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0) {
print(currentLine.length() > 0 ? " {" : "{");
println();
} else {
if (currentLine.length() > 0)
println();
println("{");
}
}
/**
* Print a opening brace with the current indentation style.
* Called at the end of the line of the instance that opens the
@ -763,7 +784,8 @@ public class TabbedPrintWriter {
else {
if (currentLine.length() > 0)
println();
if (currentIndent > 0)
if ((Options.outputStyle & Options.BRACE_FLUSH_LEFT) == 0
&& currentIndent > 0)
tab();
println("{");
}
@ -774,19 +796,14 @@ public class TabbedPrintWriter {
print("} ");
else {
println("}");
if (currentIndent > 0)
if ((Options.outputStyle & Options.BRACE_FLUSH_LEFT) == 0
&& currentIndent > 0)
untab();
}
}
public void closeBraceNoSpace() {
if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0)
print("}");
else {
println("}");
if (currentIndent > 0)
untab();
}
public void closeBraceClass() {
print("}");
}
public void closeBrace() {
@ -794,11 +811,16 @@ public class TabbedPrintWriter {
println("}");
else {
println("}");
if (currentIndent > 0)
if ((Options.outputStyle & Options.BRACE_FLUSH_LEFT) == 0
&& currentIndent > 0)
untab();
}
}
public void closeBraceNoIndent() {
println("}");
}
public void flush() {
pw.flush();
}

@ -1,7 +1,7 @@
/* Window Copyright (C) 1999 Jochen Hoenicke.
/* Window Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* ArrayLengthOperator Copyright (C) 1998-1999 Jochen Hoenicke.
/* ArrayLengthOperator Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* ArrayLoadOperator Copyright (C) 1998-1999 Jochen Hoenicke.
/* ArrayLoadOperator Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* ArrayStoreOperator Copyright (C) 1998-1999 Jochen Hoenicke.
/* ArrayStoreOperator Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -32,4 +32,29 @@ public class ArrayStoreOperator extends ArrayLoadOperator
public boolean matches(Operator loadop) {
return loadop instanceof ArrayLoadOperator;
}
public void dumpExpression(TabbedPrintWriter writer)
throws java.io.IOException {
Type arrType = subExpressions[0].getType().getHint();
if (arrType instanceof ArrayType) {
Type elemType = ((ArrayType) arrType).getElementType();
if (!elemType.isOfType(getType())) {
/* We need an explicit widening cast */
writer.print("(");
writer.startOp(writer.EXPL_PAREN, 1);
writer.print("(");
writer.printType(Type.tArray(getType().getHint()));
writer.print(") ");
writer.breakOp();
subExpressions[0].dumpExpression(writer, 700);
writer.print(")");
writer.breakOp();
writer.print("[");
subExpressions[1].dumpExpression(writer, 0);
writer.print("]");
return;
}
}
super.dumpExpression(writer);
}
}

@ -1,7 +1,7 @@
/* BinaryOperator Copyright (C) 1998-1999 Jochen Hoenicke.
/* BinaryOperator Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* CheckCastOperator Copyright (C) 1998-1999 Jochen Hoenicke.
/* CheckCastOperator Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* CheckNullOperator Copyright (C) 1999 Jochen Hoenicke.
/* CheckNullOperator Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* ClassFieldOperator Copyright (C) 1999 Jochen Hoenicke.
/* ClassFieldOperator Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* CombineableOperator Copyright (C) 1999 Jochen Hoenicke.
/* CombineableOperator Copyright (C) 1999-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* CompareBinaryOperator Copyright (C) 1998-1999 Jochen Hoenicke.
/* CompareBinaryOperator Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$

@ -1,7 +1,7 @@
/* CompareToIntOperator Copyright (C) 1998-1999 Jochen Hoenicke.
/* CompareToIntOperator Copyright (C) 1998-2002 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
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
@ -10,8 +10,8 @@
* 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
* You should have received a copy of the GNU Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
@ -54,6 +54,7 @@ public class CompareToIntOperator extends Operator {
throws java.io.IOException
{
subExpressions[0].dumpExpression(writer, 550);
writer.breakOp();
writer.print(" <=>");
if (allowsNaN)
writer.print(greaterOnNaN ? "g" : "l");

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save