From 4af719032deece4fabc3a5a287eb001845268087 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 9 May 2015 17:00:30 -0400 Subject: [PATCH] Allow pool to be dynamically rebuilt --- .../java/info/sigterm/deob/ClassFile.java | 58 ++++--- .../java/info/sigterm/deob/ConstantPool.java | 153 ++++++++++++++---- src/main/java/info/sigterm/deob/Deob.java | 2 +- src/main/java/info/sigterm/deob/Field.java | 21 ++- src/main/java/info/sigterm/deob/Fields.java | 14 +- .../java/info/sigterm/deob/Interfaces.java | 20 +-- src/main/java/info/sigterm/deob/Method.java | 25 ++- .../sigterm/deob/attributes/Attribute.java | 3 +- .../deob/attributes/AttributeType.java | 1 - .../sigterm/deob/attributes/Attributes.java | 21 ++- .../info/sigterm/deob/attributes/Code.java | 22 +-- .../deob/attributes/ConstantValue.java | 8 +- .../deob/attributes/code/Exception.java | 10 +- .../deob/attributes/code/Exceptions.java | 9 +- .../deob/attributes/code/Instruction.java | 6 + .../attributes/code/instructions/AAStore.java | 1 - .../attributes/code/instructions/ALoad.java | 1 - .../code/instructions/ANewArray.java | 8 +- .../code/instructions/CheckCast.java | 7 +- .../code/instructions/GetField.java | 9 +- .../code/instructions/GetStatic.java | 20 +-- .../code/instructions/InstanceOf.java | 9 +- .../code/instructions/InvokeInterface.java | 20 +-- .../code/instructions/InvokeSpecial.java | 21 +-- .../code/instructions/InvokeStatic.java | 15 +- .../code/instructions/InvokeVirtual.java | 17 +- .../attributes/code/instructions/LDC.java | 10 +- .../attributes/code/instructions/LDC2_W.java | 10 +- .../attributes/code/instructions/LDC_W.java | 15 +- .../code/instructions/MultiANewArray.java | 7 +- .../attributes/code/instructions/New.java | 7 +- .../code/instructions/PutField.java | 12 +- .../code/instructions/PutStatic.java | 12 +- .../java/info/sigterm/deob/pool/Class.java | 32 +++- .../java/info/sigterm/deob/pool/Double.java | 17 ++ .../java/info/sigterm/deob/pool/Field.java | 37 ++++- .../java/info/sigterm/deob/pool/Float.java | 17 ++ .../java/info/sigterm/deob/pool/Integer.java | 17 ++ .../sigterm/deob/pool/InterfaceMethod.java | 37 ++++- .../java/info/sigterm/deob/pool/Long.java | 17 ++ .../java/info/sigterm/deob/pool/Method.java | 37 ++++- .../info/sigterm/deob/pool/NameAndType.java | 42 +++-- .../info/sigterm/deob/pool/PoolEntry.java | 17 +- .../java/info/sigterm/deob/pool/String.java | 32 +++- .../java/info/sigterm/deob/pool/UTF8.java | 54 +++---- 45 files changed, 597 insertions(+), 333 deletions(-) diff --git a/src/main/java/info/sigterm/deob/ClassFile.java b/src/main/java/info/sigterm/deob/ClassFile.java index 395b00f659..8c1ed6d51d 100644 --- a/src/main/java/info/sigterm/deob/ClassFile.java +++ b/src/main/java/info/sigterm/deob/ClassFile.java @@ -4,6 +4,7 @@ import info.sigterm.deob.attributes.Attributes; import info.sigterm.deob.pool.Class; import info.sigterm.deob.pool.NameAndType; +import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -11,19 +12,20 @@ import java.util.ArrayList; public class ClassFile { + private static final int MAGIC = 0xcafebabe; + private ClassGroup group; private DataInputStream is; private ClassFile parent; // super class private ArrayList children = new ArrayList(); // classes which inherit from this - private int magic; private short minor_version; private short major_version; private ConstantPool pool; private short access_flags; - private int this_class; - private int super_class; + private Class name; + private Class super_class; private Interfaces interfaces; private Fields fields; private Methods methods; @@ -34,18 +36,18 @@ public class ClassFile this.group = group; this.is = is; - magic = is.readInt(); - if (magic != 0xcafebabe) + int magic = is.readInt(); + if (magic != MAGIC) throw new IOException("File is not a java class file."); minor_version = is.readShort(); major_version = is.readShort(); - pool = new ConstantPool(this); + pool = new ConstantPool(this, is); access_flags = is.readShort(); - this_class = is.readUnsignedShort(); - super_class = is.readUnsignedShort(); + name = pool.getClass(is.readUnsignedShort()); + super_class = pool.getClass(is.readUnsignedShort()); interfaces = new Interfaces(this); @@ -58,24 +60,32 @@ public class ClassFile public void write(DataOutputStream out) throws IOException { - out.writeInt(0xcafebabe); + out.writeInt(MAGIC); out.writeShort(minor_version); out.writeShort(major_version); + /* constant pool will be rebuilt now */ + pool.reset(); + + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + DataOutputStream rest = new DataOutputStream(bout); + rest.writeShort(access_flags); + rest.writeShort(pool.make(name)); + rest.writeShort(pool.make(super_class)); + + interfaces.write(rest); + + fields.write(rest); + + methods.write(rest); + + attributes.write(rest); + + // Now the pool is created + pool.write(out); - - out.writeShort(access_flags); - out.writeShort(this_class); - out.writeShort(super_class); - - interfaces.write(out); - - fields.write(out); - - methods.write(out); - - attributes.write(out); + out.write(bout.toByteArray()); } public ClassGroup getGroup() @@ -110,14 +120,12 @@ public class ClassFile public String getName() { - Class entry = (Class) pool.getEntry(this_class); - return entry.getName(); + return name.getName(); } public ClassFile getParent() { - Class entry = (Class) pool.getEntry(super_class); - String superName = entry.getName(); + String superName = super_class.getName(); ClassFile other = group.findClass(superName); assert other != this; return other; diff --git a/src/main/java/info/sigterm/deob/ConstantPool.java b/src/main/java/info/sigterm/deob/ConstantPool.java index 304601964f..0131a635a8 100644 --- a/src/main/java/info/sigterm/deob/ConstantPool.java +++ b/src/main/java/info/sigterm/deob/ConstantPool.java @@ -1,7 +1,8 @@ package info.sigterm.deob; -import info.sigterm.deob.attributes.code.instructions.Return; import info.sigterm.deob.pool.ConstantType; +import info.sigterm.deob.pool.InterfaceMethod; +import info.sigterm.deob.pool.NameAndType; import info.sigterm.deob.pool.PoolEntry; import info.sigterm.deob.pool.UTF8; @@ -9,22 +10,26 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.lang.reflect.Constructor; +import java.security.KeyStore.Entry; +import java.util.ArrayList; +import java.util.List; public class ConstantPool { private ClassFile classFile; - private int count; - private PoolEntry pool[]; - - ConstantPool(ClassFile c) throws IOException + private List entries = new ArrayList(); + + ConstantPool(ClassFile c) { classFile = c; + } - DataInputStream is = c.getStream(); + ConstantPool(ClassFile c, DataInputStream is) throws IOException + { + this(c); - count = is.readUnsignedShort(); - pool = new PoolEntry[count]; + int count = is.readUnsignedShort(); for (int i = 1; i < count; ++i) { @@ -36,8 +41,9 @@ public class ConstantPool { Constructor con = type.getPoolClass().getConstructor(new Class[] { ConstantPool.class }); PoolEntry entry = con.newInstance(this); + entry.id = i; - pool[i] = entry; + entries.add(entry); i += entry.getSlots() - 1; } catch (Exception e) @@ -45,16 +51,41 @@ public class ConstantPool throw new IOException(e); } } + + for (PoolEntry entry : entries) + entry.resolve(); + } + + public void reset() + { + for (PoolEntry entry : entries) + { + entry.id = 0; + } + + entries.clear(); } public void write(DataOutputStream out) throws IOException { - out.writeShort(count); - for (int i = 1; i < count; ++i) + /* this grows as it is iterated */ + for (int i = 0; i < entries.size(); ++i) { - PoolEntry entry = pool[i]; - if (entry == null) - continue; + PoolEntry entry = entries.get(i); + entry.prime(); + } + + int size = 0; + for (PoolEntry entry : entries) + size += entry.getSlots(); + + out.writeShort(size + 1); + int i = 1; + for (PoolEntry entry : entries) + { + assert i == entry.id; + i += entry.getSlots(); + out.writeByte(entry.getType().getType()); entry.write(out); } @@ -67,24 +98,92 @@ public class ConstantPool public PoolEntry getEntry(int index) { - return pool[index]; + for (PoolEntry entry : entries) + if (entry.id == index) + return entry; + return null; } - public int findUTF8Index(String s) + public String getUTF8(int index) { - for (int i = 1; i < count; ++i) + PoolEntry entry = getEntry(index); + UTF8 u = (UTF8) entry; + return u.getValue(); + } + + public info.sigterm.deob.pool.Class getClass(int index) + { + return (info.sigterm.deob.pool.Class) getEntry(index); + } + + public info.sigterm.deob.pool.Field getField(int index) + { + return (info.sigterm.deob.pool.Field) getEntry(index); + } + + public InterfaceMethod getInterfaceMethod(int index) + { + return (InterfaceMethod) getEntry(index); + } + + public info.sigterm.deob.pool.Method getMethod(int index) + { + return (info.sigterm.deob.pool.Method) getEntry(index); + } + + public NameAndType getNameAndType(int index) + { + return (NameAndType) getEntry(index); + } + + public Object get(int index) + { + PoolEntry entry = getEntry(index); + return entry.getObject(); + } + + public int make(PoolEntry entry) + { + int i = 1; + + for (PoolEntry e : entries) { - PoolEntry entry = pool[i]; - if (entry instanceof UTF8) - { - UTF8 u = (UTF8) entry; - if (s.equals(u.getValue())) - { - return i; - } - } + if (e.equals(entry)) + return i; + + i += e.getSlots(); } - return -1; + entries.add(entry); + entry.id = i; + entry.pool = this; + return i; + } + + public int makeUTF8(String str) + { + return make(new UTF8(str)); + } + + public int make(Object object) + { + if (object instanceof String) + return make(new info.sigterm.deob.pool.String(this, (String) object)); + + if (object instanceof Integer) + return make(new info.sigterm.deob.pool.Integer(this, (int) object)); + + if (object instanceof Float) + return make(new info.sigterm.deob.pool.Float(this, (float) object)); + + if (object instanceof Long) + return make(new info.sigterm.deob.pool.Long(this, (long) object)); + + if (object instanceof Double) + return make(new info.sigterm.deob.pool.Double(this, (double) object)); + + System.err.println("Constant pool make with unknown object " + object + " type " + object.getClass()); + + return 0; } } diff --git a/src/main/java/info/sigterm/deob/Deob.java b/src/main/java/info/sigterm/deob/Deob.java index 440a8be1d9..60748290c7 100644 --- a/src/main/java/info/sigterm/deob/Deob.java +++ b/src/main/java/info/sigterm/deob/Deob.java @@ -43,7 +43,7 @@ public class Deob group.buildCallGraph(); checkCallGraph(group); - checkParameters(group); + //checkParameters(group); //execute(group); diff --git a/src/main/java/info/sigterm/deob/Field.java b/src/main/java/info/sigterm/deob/Field.java index cac2817514..0931b0824a 100644 --- a/src/main/java/info/sigterm/deob/Field.java +++ b/src/main/java/info/sigterm/deob/Field.java @@ -2,7 +2,6 @@ package info.sigterm.deob; import info.sigterm.deob.attributes.Attributes; import info.sigterm.deob.attributes.code.Instruction; -import info.sigterm.deob.pool.UTF8; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -24,8 +23,7 @@ public class Field private Fields fields; private short accessFlags; - private int nameIndex; - private int descriptorIndex; + private String name, descriptor; private Attributes attributes; private ArrayList instructions = new ArrayList(); // instructions which reference this field @@ -35,18 +33,21 @@ public class Field this.fields = fields; DataInputStream is = fields.getClassFile().getStream(); + ConstantPool pool = fields.getClassFile().getPool(); accessFlags = is.readShort(); - nameIndex = is.readUnsignedShort(); - descriptorIndex = is.readUnsignedShort(); + name = pool.getUTF8(is.readUnsignedShort()); + descriptor = pool.getUTF8(is.readUnsignedShort()); attributes = new Attributes(this); } public void write(DataOutputStream out) throws IOException { + ConstantPool pool = fields.getClassFile().getPool(); + out.writeShort(accessFlags); - out.writeShort(nameIndex); - out.writeShort(descriptorIndex); + out.writeShort(pool.makeUTF8(name)); + out.writeShort(pool.makeUTF8(descriptor)); attributes.write(out); } @@ -62,14 +63,12 @@ public class Field public String getName() { - UTF8 u = (UTF8) fields.getClassFile().getPool().getEntry(nameIndex); - return u.getValue(); + return name; } public String getDescriptor() { - UTF8 u = (UTF8) fields.getClassFile().getPool().getEntry(descriptorIndex); - return u.getValue(); + return descriptor; } public Attributes getAttributes() diff --git a/src/main/java/info/sigterm/deob/Fields.java b/src/main/java/info/sigterm/deob/Fields.java index 76e1b54900..360bae0602 100644 --- a/src/main/java/info/sigterm/deob/Fields.java +++ b/src/main/java/info/sigterm/deob/Fields.java @@ -5,13 +5,14 @@ import info.sigterm.deob.pool.NameAndType; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; public class Fields { private ClassFile classFile; - private int count; - private Field[] fields; + private List fields = new ArrayList<>(); Fields(ClassFile c) throws IOException { @@ -19,16 +20,15 @@ public class Fields DataInputStream is = c.getStream(); - count = is.readUnsignedShort(); - fields = new Field[count]; + int count = is.readUnsignedShort(); for (int i = 0; i < count; ++i) - fields[i] = new Field(this); + fields.add(new Field(this)); } public void write(DataOutputStream out) throws IOException { - out.writeShort(count); + out.writeShort(fields.size()); for (Field f : fields) f.write(out); } @@ -38,7 +38,7 @@ public class Fields return classFile; } - public Field[] getFields() + public List getFields() { return fields; } diff --git a/src/main/java/info/sigterm/deob/Interfaces.java b/src/main/java/info/sigterm/deob/Interfaces.java index e464beffa4..dd2bd69bf1 100644 --- a/src/main/java/info/sigterm/deob/Interfaces.java +++ b/src/main/java/info/sigterm/deob/Interfaces.java @@ -12,8 +12,7 @@ public class Interfaces { private ClassFile classFile; - private int count; - private int interfaces[]; + private List interfaces = new ArrayList(); Interfaces(ClassFile c) throws IOException { @@ -21,19 +20,17 @@ public class Interfaces DataInputStream is = c.getStream(); - count = is.readUnsignedShort(); - interfaces = new int[count]; + int count = is.readUnsignedShort(); for (int i = 0; i < count; ++i) - interfaces[i] = is.readUnsignedShort(); + interfaces.add(c.getPool().getClass(is.readUnsignedShort())); } public List getInterfaces() { List l = new ArrayList<>(); - for (int i : interfaces) + for (Class clazz : interfaces) { - Class clazz = (Class) classFile.getPool().getEntry(i); ClassFile iface = classFile.getGroup().findClass(clazz.getName()); if (iface != null) l.add(iface); @@ -43,16 +40,15 @@ public class Interfaces public void write(DataOutputStream out) throws IOException { - out.writeShort(count); - for (int i : interfaces) - out.writeShort(i); + out.writeShort(interfaces.size()); + for (Class clazz : interfaces) + out.writeShort(classFile.getPool().make(clazz)); } public boolean instanceOf(ClassFile cf) { - for (int i : interfaces) + for (Class clazz : interfaces) { - Class clazz = (Class) classFile.getPool().getEntry(i); ClassFile iface = classFile.getGroup().findClass(clazz.getName()); if (iface.instanceOf(cf)) return true; diff --git a/src/main/java/info/sigterm/deob/Method.java b/src/main/java/info/sigterm/deob/Method.java index b4180b4a44..7676aeaac7 100644 --- a/src/main/java/info/sigterm/deob/Method.java +++ b/src/main/java/info/sigterm/deob/Method.java @@ -7,7 +7,6 @@ import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.instruction.types.LVTInstruction; import info.sigterm.deob.callgraph.Node; import info.sigterm.deob.pool.NameAndType; -import info.sigterm.deob.pool.UTF8; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -22,8 +21,8 @@ public class Method private Methods methods; private short accessFlags; - private int nameIndex; - private int descriptorIndex; + private String name; + private String descriptor; private Attributes attributes; private List callsTo = new ArrayList<>(), callsFrom = new ArrayList<>(); @@ -33,18 +32,21 @@ public class Method this.methods = methods; DataInputStream is = methods.getClassFile().getStream(); + ConstantPool pool = methods.getClassFile().getPool(); accessFlags = is.readShort(); - nameIndex = is.readUnsignedShort(); - descriptorIndex = is.readUnsignedShort(); + name = pool.getUTF8(is.readUnsignedShort()); + descriptor = pool.getUTF8(is.readUnsignedShort()); attributes = new Attributes(this); } public void write(DataOutputStream out) throws IOException { + ConstantPool pool = methods.getClassFile().getPool(); + out.writeShort(accessFlags); - out.writeShort(nameIndex); - out.writeShort(descriptorIndex); + out.writeShort(pool.makeUTF8(name)); + out.writeShort(pool.makeUTF8(descriptor)); attributes.write(out); } @@ -60,20 +62,17 @@ public class Method public String getName() { - UTF8 u = (UTF8) methods.getClassFile().getPool().getEntry(nameIndex); - return u.getValue(); + return name; } public String getDescriptor() { - UTF8 u = (UTF8) methods.getClassFile().getPool().getEntry(descriptorIndex); - return u.getValue(); + return descriptor; } public NameAndType getNameAndType() { - // this isn't really from the pool .. - return new NameAndType(methods.getClassFile().getPool(), nameIndex, descriptorIndex); + return new NameAndType(name, descriptor); } public boolean isStatic() diff --git a/src/main/java/info/sigterm/deob/attributes/Attribute.java b/src/main/java/info/sigterm/deob/attributes/Attribute.java index 12303c4bbc..34f80d29c1 100644 --- a/src/main/java/info/sigterm/deob/attributes/Attribute.java +++ b/src/main/java/info/sigterm/deob/attributes/Attribute.java @@ -10,7 +10,6 @@ public abstract class Attribute private Attributes attributes; private AttributeType type; private int length; - public int nameIndex; Attribute(Attributes attr, AttributeType type) throws IOException { @@ -21,7 +20,7 @@ public abstract class Attribute this.length = is.readInt(); } - public void write(DataOutputStream out) throws IOException + public final void write(DataOutputStream out) throws IOException { ByteArrayOutputStream bout = new ByteArrayOutputStream(); writeAttr(new DataOutputStream(bout)); diff --git a/src/main/java/info/sigterm/deob/attributes/AttributeType.java b/src/main/java/info/sigterm/deob/attributes/AttributeType.java index 38db535d50..bbbe0c7414 100644 --- a/src/main/java/info/sigterm/deob/attributes/AttributeType.java +++ b/src/main/java/info/sigterm/deob/attributes/AttributeType.java @@ -8,7 +8,6 @@ public enum AttributeType private String name; private Class clazz; - public int nameIndex; AttributeType(String name, Class clazz) { diff --git a/src/main/java/info/sigterm/deob/attributes/Attributes.java b/src/main/java/info/sigterm/deob/attributes/Attributes.java index 580d3ccdce..d0ea8b72b2 100644 --- a/src/main/java/info/sigterm/deob/attributes/Attributes.java +++ b/src/main/java/info/sigterm/deob/attributes/Attributes.java @@ -9,6 +9,8 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; public class Attributes { @@ -17,8 +19,7 @@ public class Attributes private Method method; private Code code; - private int count; - private Attribute[] attributes; + private List attributes = new ArrayList<>(); public Attributes(ClassFile cf) throws IOException { @@ -87,22 +88,20 @@ public class Attributes { DataInputStream is = getStream(); - count = is.readUnsignedShort(); - attributes = new Attribute[count]; + int count = is.readUnsignedShort(); for (int i = 0; i < count; ++i) { - int nameIndex = is.readUnsignedShort(); - UTF8 name = (UTF8) getClassFile().getPool().getEntry(nameIndex); + String name = this.getClassFile().getPool().getUTF8(is.readUnsignedShort()); - AttributeType type = AttributeType.findType(name.getValue()); + AttributeType type = AttributeType.findType(name); try { Constructor con = type.getAttributeClass().getConstructor(new Class[] { Attributes.class }); Attribute attr = con.newInstance(this); - attr.nameIndex = nameIndex; - attributes[i] = attr; + if (type != AttributeType.UNKNOWN) + attributes.add(attr); } catch (Exception ex) { @@ -113,10 +112,10 @@ public class Attributes public void write(DataOutputStream out) throws IOException { - out.writeShort(count); + out.writeShort(attributes.size()); for (Attribute a : attributes) { - out.writeShort(a.nameIndex); + out.writeShort(this.getClassFile().getPool().makeUTF8(a.getType().getName())); a.write(out); } } diff --git a/src/main/java/info/sigterm/deob/attributes/Code.java b/src/main/java/info/sigterm/deob/attributes/Code.java index c1b4114348..988b199297 100644 --- a/src/main/java/info/sigterm/deob/attributes/Code.java +++ b/src/main/java/info/sigterm/deob/attributes/Code.java @@ -29,6 +29,17 @@ public class Code extends Attribute exceptions = new Exceptions(this); this.attributes = new Attributes(this); } + + @Override + public void writeAttr(DataOutputStream out) throws IOException + { + out.writeShort(maxStack); + out.writeShort(maxLocals); + + instructions.write(out); + exceptions.write(out); + attributes.write(out); + } public int getMaxStack() { @@ -59,15 +70,4 @@ public class Code extends Attribute { instructions.buildCallGraph(); } - - @Override - public void writeAttr(DataOutputStream out) throws IOException - { - out.writeShort(maxStack); - out.writeShort(maxLocals); - - instructions.write(out); - exceptions.write(out); - attributes.write(out); - } } diff --git a/src/main/java/info/sigterm/deob/attributes/ConstantValue.java b/src/main/java/info/sigterm/deob/attributes/ConstantValue.java index 7590903f45..99f023cc08 100644 --- a/src/main/java/info/sigterm/deob/attributes/ConstantValue.java +++ b/src/main/java/info/sigterm/deob/attributes/ConstantValue.java @@ -8,24 +8,24 @@ import java.io.IOException; public class ConstantValue extends Attribute { - private int constantValueIndex; + private PoolEntry value; public ConstantValue(Attributes attributes) throws IOException { super(attributes, AttributeType.CONSTANT_VALUE); DataInputStream is = attributes.getStream(); - constantValueIndex = is.readUnsignedShort(); + value = this.getAttributes().getClassFile().getPool().getEntry(is.readUnsignedShort()); } public PoolEntry getValue() { - return this.getAttributes().getClassFile().getPool().getEntry(constantValueIndex); + return value; } @Override public void writeAttr(DataOutputStream out) throws IOException { - out.writeShort(constantValueIndex); + out.writeShort(this.getAttributes().getClassFile().getPool().make(value)); } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/Exception.java b/src/main/java/info/sigterm/deob/attributes/code/Exception.java index 9f1c4c5e41..70ad0644e7 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Exception.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Exception.java @@ -1,6 +1,7 @@ package info.sigterm.deob.attributes.code; import info.sigterm.deob.ConstantPool; +import info.sigterm.deob.pool.Class; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -13,26 +14,29 @@ public class Exception private int startPc; private int endPc; private int handlerPc; - private int catchType; + private Class cacheType; public Exception(Exceptions exceptions) throws IOException { this.exceptions = exceptions; DataInputStream is = exceptions.getCode().getAttributes().getStream(); + ConstantPool pool = exceptions.getCode().getAttributes().getClassFile().getPool(); startPc = is.readUnsignedShort(); endPc = is.readUnsignedShort(); handlerPc = is.readUnsignedShort(); - catchType = is.readUnsignedShort(); + cacheType = pool.getClass(is.readUnsignedShort()); } public void write(DataOutputStream out) throws IOException { + ConstantPool pool = exceptions.getCode().getAttributes().getClassFile().getPool(); + out.writeShort(startPc); out.writeShort(endPc); out.writeShort(handlerPc); - out.writeShort(catchType); + out.writeShort(cacheType == null ? 0 : pool.make(cacheType)); } public Exceptions getExceptions() diff --git a/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java b/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java index 92aba3dbf3..412de3d30b 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java @@ -1,18 +1,18 @@ package info.sigterm.deob.attributes.code; import info.sigterm.deob.attributes.Code; -import info.sigterm.deob.execution.ObjectInstance; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.List; public class Exceptions { private Code code; - private Exception[] exceptions; + private List exceptions = new ArrayList(); public Exceptions(Code code) throws IOException { @@ -21,15 +21,14 @@ public class Exceptions DataInputStream is = code.getAttributes().getStream(); int count = is.readUnsignedShort(); - exceptions = new Exception[count]; for (int i = 0; i < count; ++i) - exceptions[i] = new Exception(this); + exceptions.add(new Exception(this)); } public void write(DataOutputStream out) throws IOException { - out.writeShort(exceptions.length); + out.writeShort(exceptions.size()); for (Exception e : exceptions) e.write(out); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/Instruction.java b/src/main/java/info/sigterm/deob/attributes/code/Instruction.java index cd92755bbc..019482fbbd 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instruction.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instruction.java @@ -1,5 +1,6 @@ package info.sigterm.deob.attributes.code; +import info.sigterm.deob.ConstantPool; import info.sigterm.deob.execution.Frame; import java.io.DataOutputStream; @@ -33,6 +34,11 @@ public abstract class Instruction { return instructions; } + + public ConstantPool getPool() + { + return instructions.getCode().getAttributes().getClassFile().getPool(); + } public int getPc() { diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/AAStore.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/AAStore.java index 0c294cff2f..93848db640 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/AAStore.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/AAStore.java @@ -5,7 +5,6 @@ import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.execution.ArrayInstance; import info.sigterm.deob.execution.Frame; -import info.sigterm.deob.execution.ObjectInstance; import info.sigterm.deob.execution.Stack; public class AAStore extends Instruction diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad.java index eac85a4ebf..33eda525f6 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad.java @@ -1,6 +1,5 @@ package info.sigterm.deob.attributes.code.instructions; -import info.sigterm.deob.Method; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/ANewArray.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/ANewArray.java index 226352c38f..1139e5e7ac 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/ANewArray.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/ANewArray.java @@ -15,14 +15,14 @@ import java.io.IOException; public class ANewArray extends Instruction { - private int index; + private Class clazz; public ANewArray(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + clazz = this.getPool().getClass(is.readUnsignedShort()); length += 2; } @@ -30,14 +30,14 @@ public class ANewArray extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + + out.writeShort(this.getPool().make(clazz)); } @Override public void execute(Frame frame) { ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - Class clazz = (Class) thisClass.getPool().getEntry(index); int count = (int) frame.getStack().pop(); diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/CheckCast.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/CheckCast.java index 813c5951c4..7326f178e0 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/CheckCast.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/CheckCast.java @@ -15,14 +15,14 @@ import java.io.IOException; public class CheckCast extends Instruction { - private int index; + private Class clazz; public CheckCast(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + clazz = this.getPool().getClass(is.readUnsignedShort()); length += 2; } @@ -30,7 +30,7 @@ public class CheckCast extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(clazz)); } @Override @@ -39,7 +39,6 @@ public class CheckCast extends Instruction ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); ConstantPool pool = thisClass.getPool(); - Class clazz = (Class) pool.getEntry(index); ObjectInstance obj = (ObjectInstance) e.getStack().pop(); if (obj == null) diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetField.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetField.java index dca6b9e00e..ec0447db80 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetField.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetField.java @@ -17,14 +17,14 @@ import java.io.IOException; public class GetField extends Instruction { - private int index; + private Field field; public GetField(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + field = this.getPool().getField(is.readUnsignedShort()); length += 2; } @@ -32,7 +32,7 @@ public class GetField extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(field)); } @Override @@ -43,9 +43,8 @@ public class GetField extends Instruction ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); ConstantPool pool = thisClass.getPool(); - Field entry = (Field) pool.getEntry(index); - NameAndType nat = entry.getNameAndType(); + NameAndType nat = field.getNameAndType(); if (object == null) { diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java index 26d0103010..6a4b32b3ba 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java @@ -18,14 +18,14 @@ import java.io.IOException; public class GetStatic extends Instruction { - private int index; + private Field field; public GetStatic(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + field = this.getPool().getField(is.readUnsignedShort()); length += 2; } @@ -33,7 +33,7 @@ public class GetStatic extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(field)); } @Override @@ -41,11 +41,8 @@ public class GetStatic extends Instruction { ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - ConstantPool pool = thisClass.getPool(); - Field entry = (Field) pool.getEntry(index); - - Class clazz = entry.getClassEntry(); - NameAndType nat = entry.getNameAndType(); + Class clazz = field.getClassEntry(); + NameAndType nat = field.getNameAndType(); ClassFile cf = thisClass.getGroup().findClass(clazz.getName()); if (cf == null) @@ -65,11 +62,8 @@ public class GetStatic extends Instruction @Override public void buildInstructionGraph() { - ConstantPool pool = this.getInstructions().getCode().getAttributes().getClassFile().getPool(); - Field entry = (Field) pool.getEntry(index); - - Class clazz = entry.getClassEntry(); - NameAndType nat = entry.getNameAndType(); + Class clazz = field.getClassEntry(); + NameAndType nat = field.getNameAndType(); ClassFile cf = this.getInstructions().getCode().getAttributes().getClassFile().getGroup().findClass(clazz.getName()); if (cf == null) diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InstanceOf.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InstanceOf.java index 0fff49ace9..758065547b 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InstanceOf.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InstanceOf.java @@ -15,14 +15,14 @@ import java.io.IOException; public class InstanceOf extends Instruction { - private int index; + private Class clazz; public InstanceOf(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + clazz = this.getPool().getClass(is.readUnsignedShort()); length += 2; } @@ -30,16 +30,13 @@ public class InstanceOf extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(clazz)); } @Override public void execute(Frame e) { ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - - ConstantPool pool = thisClass.getPool(); - Class clazz = (Class) pool.getEntry(index); ObjectInstanceBase obj = (ObjectInstanceBase) e.getStack().pop(); if (obj == null) diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java index d6a205fc86..9c2d6242eb 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java @@ -18,7 +18,7 @@ import java.io.IOException; public class InvokeInterface extends Instruction { - private int index; + private InterfaceMethod method; private int count; public InvokeInterface(Instructions instructions, InstructionType type, int pc) throws IOException @@ -26,7 +26,7 @@ public class InvokeInterface extends Instruction super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + method = this.getPool().getInterfaceMethod(is.readUnsignedShort()); count = is.readUnsignedByte(); is.skip(1); length += 4; @@ -36,19 +36,14 @@ public class InvokeInterface extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(method)); out.writeByte(count); out.writeByte(0); } @Override public void buildCallGraph() - { - ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - - ConstantPool pool = thisClass.getPool(); - InterfaceMethod method = (InterfaceMethod) pool.getEntry(index); - + { info.sigterm.deob.pool.Class clazz = method.getClassEntry(); NameAndType nat = method.getNameAndType(); @@ -64,12 +59,7 @@ public class InvokeInterface extends Instruction @Override public void execute(Frame e) - { - ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - - ConstantPool pool = thisClass.getPool(); - InterfaceMethod method = (InterfaceMethod) pool.getEntry(index); - + { ObjectInstance object = (ObjectInstance) e.getStack().pop(); ClassInstance objectType = object.getType(); diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java index 2ddceae8d5..fc780527b5 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java @@ -10,7 +10,6 @@ import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.ObjectInstance; import info.sigterm.deob.pool.Method; import info.sigterm.deob.pool.NameAndType; -import info.sigterm.deob.pool.PoolEntry; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -18,14 +17,14 @@ import java.io.IOException; public class InvokeSpecial extends Instruction { - private int index; + private Method method; public InvokeSpecial(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + method = this.getPool().getMethod(is.readUnsignedShort()); length += 2; } @@ -33,17 +32,12 @@ public class InvokeSpecial extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(method)); } @Override public void buildCallGraph() { - ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - - ConstantPool pool = thisClass.getPool(); - Method method = (Method) pool.getEntry(index); - info.sigterm.deob.pool.Class clazz = method.getClassEntry(); NameAndType nat = method.getNameAndType(); @@ -61,10 +55,6 @@ public class InvokeSpecial extends Instruction @Override public void execute(Frame e) { - ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - - ConstantPool pool = thisClass.getPool(); - Method method = (Method) pool.getEntry(index); int count = method.getNameAndType().getNumberOfArgs(); ObjectInstance object = (ObjectInstance) e.getStack().pop(); @@ -89,10 +79,7 @@ public class InvokeSpecial extends Instruction @Override public String getDesc(Frame frame) - { - ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - Method method = (Method) thisClass.getPool().getEntry(index); - + { return "invokespecial " + method.getNameAndType().getDescriptor() + " on " + method.getClassEntry().getName(); } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java index 0487f9728d..729cf410d4 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java @@ -15,14 +15,14 @@ import java.io.IOException; public class InvokeStatic extends Instruction { - private int index; + private Method method; public InvokeStatic(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + method = this.getPool().getMethod(is.readUnsignedShort()); length += 2; } @@ -30,17 +30,12 @@ public class InvokeStatic extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(method)); } @Override public void buildCallGraph() - { - ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - - ConstantPool pool = thisClass.getPool(); - Method method = (Method) pool.getEntry(index); - + { info.sigterm.deob.pool.Class clazz = method.getClassEntry(); NameAndType nat = method.getNameAndType(); @@ -60,8 +55,6 @@ public class InvokeStatic extends Instruction { ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - ConstantPool pool = thisClass.getPool(); - Method method = (Method) pool.getEntry(index); info.sigterm.deob.pool.Class clazz = method.getClassEntry(); ClassFile otherClass = thisClass.getGroup().findClass(clazz.getName()); diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java index 2c17af404f..114d9e0e1a 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java @@ -17,14 +17,14 @@ import java.io.IOException; public class InvokeVirtual extends Instruction { - private int index; + private Method method; public InvokeVirtual(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + method = this.getPool().getMethod(is.readUnsignedShort()); length += 2; } @@ -32,17 +32,12 @@ public class InvokeVirtual extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(method)); } @Override public void buildCallGraph() - { - ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - - ConstantPool pool = thisClass.getPool(); - Method method = (Method) pool.getEntry(index); - + { info.sigterm.deob.pool.Class clazz = method.getClassEntry(); NameAndType nat = method.getNameAndType(); @@ -61,10 +56,6 @@ public class InvokeVirtual extends Instruction @Override public void execute(Frame e) { - ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - - ConstantPool pool = thisClass.getPool(); - Method method = (Method) pool.getEntry(index); int count = method.getNameAndType().getNumberOfArgs(); Object[] args = new Object[count + 1]; diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC.java index ed75a5a8b1..4068e3f843 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC.java @@ -13,14 +13,14 @@ import java.io.IOException; public class LDC extends Instruction { - private int index; + private Object value; public LDC(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readByte(); + value = this.getPool().get(is.readUnsignedByte()); length += 1; } @@ -28,14 +28,12 @@ public class LDC extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeByte(index); + out.writeByte(this.getPool().make(value)); } @Override public void execute(Frame frame) { - ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - PoolEntry entry = thisClass.getPool().getEntry(index); - frame.getStack().push(this, entry.getObject()); + frame.getStack().push(this, value); } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC2_W.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC2_W.java index 6b0a9e124b..0a8334622c 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC2_W.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC2_W.java @@ -13,14 +13,14 @@ import java.io.IOException; public class LDC2_W extends Instruction { - private int index; + private Object value; public LDC2_W(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + value = this.getPool().get(is.readUnsignedShort()); length += 2; } @@ -28,14 +28,12 @@ public class LDC2_W extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(value)); } @Override public void execute(Frame frame) { - ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - PoolEntry entry = thisClass.getPool().getEntry(index); - frame.getStack().push(this, entry.getObject()); + frame.getStack().push(this, value); } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC_W.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC_W.java index b56123f9da..574a9d75ba 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC_W.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC_W.java @@ -13,14 +13,14 @@ import java.io.IOException; public class LDC_W extends Instruction { - private int index; + private Object value; public LDC_W(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + value = this.getPool().get(is.readUnsignedShort()); length += 2; } @@ -28,24 +28,19 @@ public class LDC_W extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(value)); } @Override public void execute(Frame frame) { - ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - PoolEntry entry = thisClass.getPool().getEntry(index); - frame.getStack().push(this, entry.getObject()); + frame.getStack().push(this, value); } @Override public String getDesc(Frame frame) { - ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - PoolEntry entry = thisClass.getPool().getEntry(index); - - return "ldc_w " + entry.getObject(); + return "ldc_w " + value; } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/MultiANewArray.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/MultiANewArray.java index 2cc764b35f..5409fe0139 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/MultiANewArray.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/MultiANewArray.java @@ -14,7 +14,7 @@ import java.io.IOException; public class MultiANewArray extends Instruction { - private int index; + private Class clazz; private int dimensions; public MultiANewArray(Instructions instructions, InstructionType type, int pc) throws IOException @@ -22,7 +22,7 @@ public class MultiANewArray extends Instruction super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + clazz = this.getPool().getClass(is.readUnsignedShort()); dimensions = is.readUnsignedByte(); length += 3; } @@ -31,7 +31,7 @@ public class MultiANewArray extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(clazz)); out.writeByte(dimensions); } @@ -41,7 +41,6 @@ public class MultiANewArray extends Instruction Stack stack = e.getStack(); ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - Class clazz = (Class) thisClass.getPool().getEntry(index); // XXX primive type/array type ? [[I [[Lmyclass; etc ClassFile cf = thisClass.getGroup().findClass(clazz.getName()); diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/New.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/New.java index 8a8ce5f5a7..b011d6d703 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/New.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/New.java @@ -15,14 +15,14 @@ import java.io.IOException; public class New extends Instruction { - private int index; + private Class clazz; public New(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + clazz = this.getPool().getClass(is.readUnsignedShort()); length += 2; } @@ -30,14 +30,13 @@ public class New extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(clazz)); } @Override public void execute(Frame e) { ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - Class clazz = (Class) thisClass.getPool().getEntry(index); ClassFile cf = thisClass.getGroup().findClass(clazz.getName()); if (cf == null) { diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/PutField.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/PutField.java index b2cd35926c..1b09417cf3 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/PutField.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/PutField.java @@ -17,14 +17,14 @@ import java.io.IOException; public class PutField extends Instruction { - private int index; + private Field field; public PutField(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + field = this.getPool().getField(is.readUnsignedShort()); length += 2; } @@ -32,17 +32,13 @@ public class PutField extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(field)); } @Override public void execute(Frame e) { - ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - - ConstantPool pool = thisClass.getPool(); - Field entry = (Field) pool.getEntry(index); - NameAndType nat = entry.getNameAndType(); + NameAndType nat = field.getNameAndType(); ObjectInstance object = (ObjectInstance) e.getStack().pop(); Object value = e.getStack().pop(); diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/PutStatic.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/PutStatic.java index b4792d47f2..00bded78ee 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/PutStatic.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/PutStatic.java @@ -18,14 +18,14 @@ import java.io.IOException; public class PutStatic extends Instruction { - private int index; + private Field field; public PutStatic(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); + field = this.getPool().getField(is.readUnsignedShort()); length += 2; } @@ -33,7 +33,7 @@ public class PutStatic extends Instruction public void write(DataOutputStream out, int pc) throws IOException { super.write(out, pc); - out.writeShort(index); + out.writeShort(this.getPool().make(field)); } @Override @@ -41,10 +41,8 @@ public class PutStatic extends Instruction { ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); - ConstantPool pool = thisClass.getPool(); - Field entry = (Field) pool.getEntry(index); - Class clazz = entry.getClassEntry(); - NameAndType nat = entry.getNameAndType(); + Class clazz = field.getClassEntry(); + NameAndType nat = field.getNameAndType(); Object value = e.getStack().pop(); diff --git a/src/main/java/info/sigterm/deob/pool/Class.java b/src/main/java/info/sigterm/deob/pool/Class.java index 1f10a76cf3..1c2cf1cf08 100644 --- a/src/main/java/info/sigterm/deob/pool/Class.java +++ b/src/main/java/info/sigterm/deob/pool/Class.java @@ -9,6 +9,7 @@ import java.io.IOException; public class Class extends PoolEntry { private int index; + private java.lang.String name; public Class(ConstantPool pool) throws IOException { @@ -17,11 +18,32 @@ public class Class extends PoolEntry DataInputStream is = pool.getClassFile().getStream(); index = is.readUnsignedShort(); } + + @Override + public void resolve() + { + name = this.getPool().getUTF8(index); + } + + @Override + public void prime() + { + index = this.getPool().makeUTF8(name); + } + + @Override + public boolean equals(Object other) + { + if (!(other instanceof Class)) + return false; + + Class c = (Class) other; + return name.equals(c.name); + } public java.lang.String getName() { - UTF8 u = (UTF8) this.getPool().getEntry(index); - return u.getValue(); + return name; } @Override @@ -29,4 +51,10 @@ public class Class extends PoolEntry { out.writeShort(index); } + + @Override + public Object getObject() + { + return name; + } } diff --git a/src/main/java/info/sigterm/deob/pool/Double.java b/src/main/java/info/sigterm/deob/pool/Double.java index 3d99bb5540..4a6054fc12 100644 --- a/src/main/java/info/sigterm/deob/pool/Double.java +++ b/src/main/java/info/sigterm/deob/pool/Double.java @@ -18,6 +18,23 @@ public class Double extends PoolEntry value = is.readDouble(); } + + public Double(ConstantPool pool, double d) + { + super(pool, ConstantType.DOUBLE); + + value = d; + } + + @Override + public boolean equals(Object other) + { + if (!(other instanceof Double)) + return false; + + Double d = (Double) other; + return value == d.value; + } @Override public int getSlots() diff --git a/src/main/java/info/sigterm/deob/pool/Field.java b/src/main/java/info/sigterm/deob/pool/Field.java index 96a6a55606..0ce9e560f3 100644 --- a/src/main/java/info/sigterm/deob/pool/Field.java +++ b/src/main/java/info/sigterm/deob/pool/Field.java @@ -8,8 +8,9 @@ import java.io.IOException; public class Field extends PoolEntry { - private int classIndex; - private int nameAndTypeIndex; + private int classIndex, natIndex; + private Class clazz; + private NameAndType nat; public Field(ConstantPool pool) throws IOException { @@ -18,23 +19,47 @@ public class Field extends PoolEntry DataInputStream is = pool.getClassFile().getStream(); classIndex = is.readUnsignedShort(); - nameAndTypeIndex = is.readUnsignedShort(); + natIndex = is.readUnsignedShort(); + } + + @Override + public void resolve() + { + clazz = this.getPool().getClass(classIndex); + nat = this.getPool().getNameAndType(natIndex); + } + + @Override + public void prime() + { + classIndex = this.getPool().make(clazz); + natIndex = this.getPool().make(nat); + } + + @Override + public boolean equals(Object other) + { + if (!(other instanceof Field)) + return false; + + Field f = (Field) other; + return clazz.equals(f.clazz) && nat.equals(f.nat); } public Class getClassEntry() { - return (Class) this.getPool().getEntry(classIndex); + return clazz; } public NameAndType getNameAndType() { - return (NameAndType) this.getPool().getEntry(nameAndTypeIndex); + return nat; } @Override public void write(DataOutputStream out) throws IOException { out.writeShort(classIndex); - out.writeShort(nameAndTypeIndex); + out.writeShort(natIndex); } } diff --git a/src/main/java/info/sigterm/deob/pool/Float.java b/src/main/java/info/sigterm/deob/pool/Float.java index 96d1d3dba6..dc83084385 100644 --- a/src/main/java/info/sigterm/deob/pool/Float.java +++ b/src/main/java/info/sigterm/deob/pool/Float.java @@ -18,6 +18,23 @@ public class Float extends PoolEntry value = is.readFloat(); } + + public Float(ConstantPool pool, float f) + { + super(pool, ConstantType.FLOAT); + + value = f; + } + + @Override + public boolean equals(Object other) + { + if (!(other instanceof Float)) + return false; + + Float f = (Float) other; + return value == f.value; + } @Override public Object getObject() diff --git a/src/main/java/info/sigterm/deob/pool/Integer.java b/src/main/java/info/sigterm/deob/pool/Integer.java index ca779f7aaf..5b76fd7925 100644 --- a/src/main/java/info/sigterm/deob/pool/Integer.java +++ b/src/main/java/info/sigterm/deob/pool/Integer.java @@ -18,6 +18,23 @@ public class Integer extends PoolEntry value = is.readInt(); } + + public Integer(ConstantPool pool, int i) + { + super(pool, ConstantType.INTEGER); + + value = i; + } + + @Override + public boolean equals(Object other) + { + if (!(other instanceof Integer)) + return false; + + Integer i = (Integer) other; + return value == i.value; + } @Override public Object getObject() diff --git a/src/main/java/info/sigterm/deob/pool/InterfaceMethod.java b/src/main/java/info/sigterm/deob/pool/InterfaceMethod.java index 25e28e9d1c..56f9097422 100644 --- a/src/main/java/info/sigterm/deob/pool/InterfaceMethod.java +++ b/src/main/java/info/sigterm/deob/pool/InterfaceMethod.java @@ -8,8 +8,9 @@ import java.io.IOException; public class InterfaceMethod extends PoolEntry { - private int classIndex; - private int nameAndTypeIndex; + private int classIndex, natIndex; + private Class clazz; + private NameAndType nat; public InterfaceMethod(ConstantPool pool) throws IOException { @@ -18,23 +19,47 @@ public class InterfaceMethod extends PoolEntry DataInputStream is = pool.getClassFile().getStream(); classIndex = is.readUnsignedShort(); - nameAndTypeIndex = is.readUnsignedShort(); + natIndex = is.readUnsignedShort(); + } + + @Override + public void resolve() + { + clazz = this.getPool().getClass(classIndex); + nat = this.getPool().getNameAndType(natIndex); + } + + @Override + public void prime() + { + classIndex = this.getPool().make(clazz); + natIndex = this.getPool().make(nat); + } + + @Override + public boolean equals(Object other) + { + if (!(other instanceof InterfaceMethod)) + return false; + + InterfaceMethod i = (InterfaceMethod) other; + return clazz.equals(i.clazz) && nat.equals(i.nat); } public Class getClassEntry() { - return (Class) this.getPool().getEntry(classIndex); + return clazz; } public NameAndType getNameAndType() { - return (NameAndType) this.getPool().getEntry(nameAndTypeIndex); + return nat; } @Override public void write(DataOutputStream out) throws IOException { out.writeShort(classIndex); - out.writeShort(nameAndTypeIndex); + out.writeShort(natIndex); } } diff --git a/src/main/java/info/sigterm/deob/pool/Long.java b/src/main/java/info/sigterm/deob/pool/Long.java index 05e0da925e..01514bbf91 100644 --- a/src/main/java/info/sigterm/deob/pool/Long.java +++ b/src/main/java/info/sigterm/deob/pool/Long.java @@ -18,6 +18,23 @@ public class Long extends PoolEntry value = is.readLong(); } + + public Long(ConstantPool pool, long l) + { + super(pool, ConstantType.LONG); + + value = l; + } + + @Override + public boolean equals(Object other) + { + if (!(other instanceof Long)) + return false; + + Long l = (Long) other; + return value == l.value; + } @Override public int getSlots() diff --git a/src/main/java/info/sigterm/deob/pool/Method.java b/src/main/java/info/sigterm/deob/pool/Method.java index fa0df0bfc9..85dc65b5a4 100644 --- a/src/main/java/info/sigterm/deob/pool/Method.java +++ b/src/main/java/info/sigterm/deob/pool/Method.java @@ -8,8 +8,9 @@ import java.io.IOException; public class Method extends PoolEntry { - private int classIndex; - private int nameAndTypeIndex; + private int classIndex, natIndex; + private Class clazz; + private NameAndType nat; public Method(ConstantPool pool) throws IOException { @@ -18,23 +19,47 @@ public class Method extends PoolEntry DataInputStream is = pool.getClassFile().getStream(); classIndex = is.readUnsignedShort(); - nameAndTypeIndex = is.readUnsignedShort(); + natIndex = is.readUnsignedShort(); + } + + @Override + public void resolve() + { + clazz = this.getPool().getClass(classIndex); + nat = this.getPool().getNameAndType(natIndex); + } + + @Override + public void prime() + { + classIndex = this.getPool().make(clazz); + natIndex = this.getPool().make(nat); + } + + @Override + public boolean equals(Object other) + { + if (!(other instanceof Method)) + return false; + + Method m = (Method) other; + return clazz.equals(m.clazz) && nat.equals(m.nat); } public Class getClassEntry() { - return (Class) this.getPool().getEntry(classIndex); + return clazz; } public NameAndType getNameAndType() { - return (NameAndType) this.getPool().getEntry(nameAndTypeIndex); + return nat; } @Override public void write(DataOutputStream out) throws IOException { out.writeShort(classIndex); - out.writeShort(nameAndTypeIndex); + out.writeShort(natIndex); } } diff --git a/src/main/java/info/sigterm/deob/pool/NameAndType.java b/src/main/java/info/sigterm/deob/pool/NameAndType.java index 2f69d4b116..5a5122071d 100644 --- a/src/main/java/info/sigterm/deob/pool/NameAndType.java +++ b/src/main/java/info/sigterm/deob/pool/NameAndType.java @@ -10,8 +10,8 @@ import java.util.regex.Pattern; public class NameAndType extends PoolEntry { - private int nameIndex; - private int descriptorIndex; + private int nameIndex, descriptorIndex; + private java.lang.String name, descriptor; public NameAndType(ConstantPool pool) throws IOException { @@ -23,24 +23,46 @@ public class NameAndType extends PoolEntry descriptorIndex = is.readUnsignedShort(); } - public NameAndType(ConstantPool pool, int name, int type) + public NameAndType(java.lang.String name, java.lang.String type) { - super(pool, ConstantType.NAME_AND_TYPE); + super(null, ConstantType.NAME_AND_TYPE); - this.nameIndex = name; - this.descriptorIndex = type; + this.name = name; + descriptor = type; + } + + @Override + public void resolve() + { + name = this.getPool().getUTF8(nameIndex); + descriptor = this.getPool().getUTF8(descriptorIndex); + } + + @Override + public void prime() + { + nameIndex = this.getPool().makeUTF8(name); + descriptorIndex = this.getPool().makeUTF8(descriptor); + } + + @Override + public boolean equals(Object other) + { + if (!(other instanceof NameAndType)) + return false; + + NameAndType nat = (NameAndType) other; + return name.equals(nat.name) && descriptor.equals(nat.descriptor); } public java.lang.String getName() { - UTF8 u = (UTF8) this.getPool().getEntry(nameIndex); - return u.getValue(); + return name; } public java.lang.String getDescriptor() { - UTF8 u = (UTF8) this.getPool().getEntry(descriptorIndex); - return u.getValue(); + return descriptor; } public Object getStackObject() diff --git a/src/main/java/info/sigterm/deob/pool/PoolEntry.java b/src/main/java/info/sigterm/deob/pool/PoolEntry.java index 48169d61f2..85fb4d0644 100644 --- a/src/main/java/info/sigterm/deob/pool/PoolEntry.java +++ b/src/main/java/info/sigterm/deob/pool/PoolEntry.java @@ -7,8 +7,9 @@ import info.sigterm.deob.ConstantPool; public abstract class PoolEntry { - private ConstantPool pool; + public ConstantPool pool; private ConstantType type; + public int id; protected PoolEntry(ConstantPool pool, ConstantType type) { @@ -16,6 +17,18 @@ public abstract class PoolEntry this.type = type; } + // read objects from indexes + public void resolve() + { + } + + // make objects and prime indexes + public void prime() + { + } + + public abstract boolean equals(Object other); + public abstract void write(DataOutputStream out) throws IOException; public ConstantPool getPool() @@ -35,6 +48,6 @@ public abstract class PoolEntry public Object getObject() { - throw new RuntimeException("No getObject implemented for " + this); + return this; } } diff --git a/src/main/java/info/sigterm/deob/pool/String.java b/src/main/java/info/sigterm/deob/pool/String.java index aae5c1ac8c..3fbc02eda6 100644 --- a/src/main/java/info/sigterm/deob/pool/String.java +++ b/src/main/java/info/sigterm/deob/pool/String.java @@ -9,6 +9,7 @@ import java.io.IOException; public class String extends PoolEntry { private int stringIndex; + private java.lang.String string; public String(ConstantPool pool) throws IOException { @@ -18,11 +19,40 @@ public class String extends PoolEntry stringIndex = is.readUnsignedShort(); } + + public String(ConstantPool pool, java.lang.String str) + { + super(pool, ConstantType.STRING); + + string = str; + } + + @Override + public void resolve() + { + string = this.getPool().getUTF8(stringIndex); + } + + @Override + public void prime() + { + stringIndex = this.getPool().makeUTF8(string); + } + + @Override + public boolean equals(Object other) + { + if (!(other instanceof String)) + return false; + + String s = (String) other; + return string.equals(s.string); + } @Override public Object getObject() { - return this.getPool().getEntry(stringIndex).getObject(); + return string; } @Override diff --git a/src/main/java/info/sigterm/deob/pool/UTF8.java b/src/main/java/info/sigterm/deob/pool/UTF8.java index f2944fb420..94c629a5cb 100644 --- a/src/main/java/info/sigterm/deob/pool/UTF8.java +++ b/src/main/java/info/sigterm/deob/pool/UTF8.java @@ -8,58 +8,48 @@ import java.io.IOException; public class UTF8 extends PoolEntry { - private StringBuilder sb = new StringBuilder(); + private java.lang.String string; public UTF8(ConstantPool pool) throws IOException { super(pool, ConstantType.UTF8); DataInputStream ios = pool.getClassFile().getStream(); - - short length = ios.readShort(); - for (int i = 0; i < length; i++) - { - int a = ios.read(); - if ((a & 0x80) == 0) - { - sb.append((char)a); - } - else if ((a & 0x20) == 0) - { - int b = ios.read(); - char c = (char)(((a & 0x1f) << 6) + (b & 0x3f)); - sb.append(c); - i++; - } - else - { - int b = ios.read(); - int c = ios.read(); - char ch = (char)(((a & 0xf) << 12) + ((b & 0x3f) << 6) + (c & 0x3f)); - sb.append(ch); - i += 2; - } - } + string = ios.readUTF(); + } + + public UTF8(java.lang.String value) + { + super(null, ConstantType.UTF8); + + string = value; + } + + @Override + public boolean equals(Object other) + { + if (!(other instanceof UTF8)) + return false; + + UTF8 u = (UTF8) other; + return string.equals(u.string); } public java.lang.String getValue() { - return (java.lang.String) getObject(); + return string; } @Override public Object getObject() { - return sb.toString(); + return getValue(); } @Override public void write(DataOutputStream out) throws IOException { java.lang.String s = getValue(); - byte[] bytes = s.getBytes("UTF-8"); - - out.writeShort(bytes.length); - out.write(bytes); + out.writeUTF(s); } }