From a4ff579f1dfdfddfb07e3d611925bfb2b0d467d8 Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 15 Jan 1999 11:00:17 +0000 Subject: [PATCH] Initial revision git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@156 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/JodeApplet.java | 67 ++++++++++ jode/jode/obfuscator/MethodReachability.java | 132 +++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 jode/jode/JodeApplet.java create mode 100644 jode/jode/obfuscator/MethodReachability.java diff --git a/jode/jode/JodeApplet.java b/jode/jode/JodeApplet.java new file mode 100644 index 0000000..df42488 --- /dev/null +++ b/jode/jode/JodeApplet.java @@ -0,0 +1,67 @@ +package jode; +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.io.*; + +public class JodeApplet extends Applet implements ActionListener, Runnable { + TextField classpathField; + TextField classField; + TextArea sourcecodeField; + + Thread decompileThread; + + public JodeApplet() { + setLayout(new BorderLayout()); + Panel optionPanel = new Panel(); + optionPanel.setLayout(new GridLayout(2,2)); + optionPanel.add(new Label("class path: ")); + classpathField = new TextField(); + optionPanel.add(classpathField); + optionPanel.add(new Label("class name: ")); + classField = new TextField(); + optionPanel.add(classField); + add(optionPanel, BorderLayout.NORTH); + + sourcecodeField = new TextArea(); + add(sourcecodeField, BorderLayout.CENTER); + + classField.addActionListener(this); + } + + public synchronized void actionPerformed(ActionEvent e) { + if (decompileThread == null) { + decompileThread = new Thread(this); + sourcecodeField.setText("Please wait, while decompiling...\n"); + decompileThread.start(); + } else + sourcecodeField.append("Be a little bit more patient, please.\n"); + } + + public void init() { + String cp = getParameter("classpath"); + if (cp != null) + classpathField.setText(cp); + String cls = getParameter("class"); + if (cls != null) + classField.setText(cls); + } + + public void run() { + JodeEnvironment env = new JodeEnvironment(classpathField.getText()); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + TabbedPrintWriter writer = new TabbedPrintWriter(out, " "); + env.doClass(classField.getText(), writer); + sourcecodeField.setText(out.toString()); + } catch (Throwable t) { + sourcecodeField.setText("Didn't succeed.\n" + +"Check the java console for more info."); + t.printStackTrace(); + } finally { + synchronized(this) { + decompileThread = null; + } + } + } +} diff --git a/jode/jode/obfuscator/MethodReachability.java b/jode/jode/obfuscator/MethodReachability.java new file mode 100644 index 0000000..a068051 --- /dev/null +++ b/jode/jode/obfuscator/MethodReachability.java @@ -0,0 +1,132 @@ +/* + * MethodReachability (c) 1998 Jochen Hoenicke + * + * You may distribute under the terms of the GNU General Public License. + * + * IN NO EVENT SHALL JOCHEN HOENICKE BE LIABLE TO ANY PARTY FOR DIRECT, + * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF + * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOCHEN HOENICKE + * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * JOCHEN HOENICKE SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" + * BASIS, AND JOCHEN HOENICKE HAS NO OBLIGATION TO PROVIDE MAINTENANCE, + * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * $Id$ + */ + +package jode.obfuscator; +import jode.bytecode.ConstantPool; +import jode.bytecode.MethodInfo; +import jode.MethodType; +import jode.Type; +import java.lang.reflect.Modifier; +import java.util.*; + +public class MethodReachability { + ClassReachability clazz; + MethodInfo info; + public ClassReachability inheritedFromClass; + + public boolean reachable = false; + public boolean preserve = false; + + public Vector references; + + public MethodReachability(ClassReachability clazz, MethodInfo info) { + this.clazz = clazz; + this.info = info; + + AttributeInfo codeattr = minfo.findAttribute("Code"); + if (codeattr != null) { + DataInputStream stream = new DataInputStream + (new ByteArrayInputStream(codeattr.getContents())); + CodeInfo codeinfo = new CodeInfo(); + try { + codeinfo.read(classAnalyzer.getConstantPool(), stream); + analyzeCode(codeinfo); + } catch (IOException ex) { + ex.printStackTrace(); + code = null; + } + } + + } + + public void analyzeCode(CodeInfo codeinfo) { + references = new Vector(); + byte[] code = codeinfo.getCode(); + try { + DataInputStream stream = + new DataInputStream(new ByteArrayInputStream(code)); + Opcodes.getReferences(stream, references); + } catch (IOException ex) { + ex.printStackTrace(); + throw new ClassFormatError(ex.getMessage()); + } + } + + public void markReachable() { + ConstantPool cp = clazz.getClassInfo().getConstantPool(); + if (!reachable) { + reachable = true; + Enumeration enum = references.elements(); + while (enum.hasMoreElements()) { + int ref = ((Integer) enum.nextElement()).intValue(); + int tag = cp.getTag(ref); + switch (tag) { + case ConstantPool.FIELDREF: + case ConstantPool.METHODREF: + case ConstantPool.INTERFACEMETHODREF: + String[] refs = cp.getRef(ref); + if (tag == ConstantPool.FIELDREF) + clazz.getBundle() + .markReachableField(refs[0], refs[1], + new MethodType(refs[2])); + else + clazz.getBundle() + .markReachableMethod(refs[0], refs[1], + new MethodTyp(refs[2])); + break; + case ConstantPool.CLASS: + String clName = cp.getClassName(ref); + clazz.getBundle().markReachable(clName); + break; + } + } + } + } + + public void markPreserved() { + ConstantPool cp = clazz.getClassInfo().getConstantPool(); + if (!preserved) { + preserved = true; + Enumeration enum = references.elements(); + while (enum.hasMoreElements()) { + int ref = ((Integer) enum.nextElement()).intValue(); + int tag = cp.getTag(ref); + switch (tag) { + case ConstantPool.FIELDREF: + case ConstantPool.METHODREF: + case ConstantPool.INTERFACEMETHODREF: + String[] refs = cp.getRef(ref); + if (tag == ConstantPool.FIELDREF) + clazz.getBundle() + .markPreservedField(refs[0], refs[1], + new MethodType(refs[2])); + else + clazz.getBundle() + .markPreservedMethod(refs[0], refs[1], + new MethodTyp(refs[2])); + break; + case ConstantPool.CLASS: + String clName = cp.getClassName(ref); + clazz.getBundle().markPreserved(clName); + break; + } + } + } + } +}