Allow pool to be dynamically rebuilt
This commit is contained in:
@@ -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<ClassFile> children = new ArrayList<ClassFile>(); // 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;
|
||||
|
||||
@@ -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<PoolEntry> entries = new ArrayList<PoolEntry>();
|
||||
|
||||
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<? extends PoolEntry> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class Deob
|
||||
group.buildCallGraph();
|
||||
|
||||
checkCallGraph(group);
|
||||
checkParameters(group);
|
||||
//checkParameters(group);
|
||||
|
||||
//execute(group);
|
||||
|
||||
|
||||
@@ -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<Instruction> instructions = new ArrayList<Instruction>(); // 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()
|
||||
|
||||
@@ -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<Field> 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<Field> getFields()
|
||||
{
|
||||
return fields;
|
||||
}
|
||||
|
||||
@@ -12,8 +12,7 @@ public class Interfaces
|
||||
{
|
||||
private ClassFile classFile;
|
||||
|
||||
private int count;
|
||||
private int interfaces[];
|
||||
private List<Class> interfaces = new ArrayList<Class>();
|
||||
|
||||
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<ClassFile> getInterfaces()
|
||||
{
|
||||
List<ClassFile> 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;
|
||||
|
||||
@@ -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<Node> 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()
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -8,7 +8,6 @@ public enum AttributeType
|
||||
|
||||
private String name;
|
||||
private Class<? extends Attribute> clazz;
|
||||
public int nameIndex;
|
||||
|
||||
AttributeType(String name, Class<? extends Attribute> clazz)
|
||||
{
|
||||
|
||||
@@ -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<Attribute> 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<? extends Attribute> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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<Exception> exceptions = new ArrayList<Exception>();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user