Allow pool to be dynamically rebuilt

This commit is contained in:
Adam
2015-05-09 17:00:30 -04:00
parent 0d21d49d2d
commit 4af719032d
45 changed files with 597 additions and 333 deletions

View File

@@ -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;
}
}