init of deob

This commit is contained in:
Adam
2014-11-30 20:35:37 -05:00
commit 41681f94a5
30 changed files with 933 additions and 0 deletions

6
pom.xml Normal file
View File

@@ -0,0 +1,6 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>info.sigterm</groupId>
<artifactId>deob</artifactId>
<version>0.0.1-SNAPSHOT</version>
</project>

View File

@@ -0,0 +1,98 @@
package info.sigterm.deob;
import info.sigterm.deob.attributes.Attribute;
import info.sigterm.deob.attributes.AttributeType;
import info.sigterm.deob.attributes.Code;
import info.sigterm.deob.pool.UTF8;
import java.io.DataInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
public class Attributes
{
private ClassFile classFile;
private Field field;
private Method method;
private Code code;
private int count;
private Attribute[] attributes;
Attributes(ClassFile cf) throws IOException
{
classFile = cf;
load();
}
Attributes(Field f) throws IOException
{
field = f;
load();
}
Attributes(Method m) throws IOException
{
method = m;
load();
}
public Attributes(Code c) throws IOException
{
code = c;
load();
}
public ClassFile getClassFile()
{
if (classFile != null)
return classFile;
if (field != null)
return field.getFields().getClassFile();
if (method != null)
return method.getMethods().getClassFile();
if (code != null)
return code.getAttributes().getClassFile();
return null;
}
public DataInputStream getStream()
{
return getClassFile().getStream();
}
private void load() throws IOException
{
DataInputStream is = getStream();
count = is.readUnsignedShort();
attributes = new Attribute[count];
for (int i = 0; i < count; ++i)
{
int nameIndex = is.readUnsignedShort();
UTF8 name = (UTF8) getClassFile().getPool().getEntry(nameIndex);
AttributeType type = AttributeType.findType(name.getValue());
try
{
Constructor<? extends Attribute> con = type.getAttributeClass().getConstructor(new Class[] { Attributes.class });
Attribute attr = con.newInstance(this);
attributes[i] = attr;
}
catch (Exception ex)
{
throw new IOException(ex);
}
}
}
}

View File

@@ -0,0 +1,57 @@
package info.sigterm.deob;
import java.io.DataInputStream;
import java.io.IOException;
public class ClassFile
{
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 Interfaces interfaces;
private Fields fields;
private Methods methods;
private Attributes attributes;
private DataInputStream is;
public ClassFile(DataInputStream is) throws IOException
{
this.is = is;
magic = is.readInt();
if (magic != 0xcafebabe)
throw new IOException("File is not a java class file.");
minor_version = is.readShort();
major_version = is.readShort();
pool = new ConstantPool(this);
access_flags = is.readShort();
this_class = is.readUnsignedShort();
super_class = is.readUnsignedShort();
interfaces = new Interfaces(this);
fields = new Fields(this);
methods = new Methods(this);
attributes = new Attributes(this);
}
public DataInputStream getStream()
{
return is;
}
public ConstantPool getPool()
{
return pool;
}
}

View File

@@ -0,0 +1,61 @@
package info.sigterm.deob;
import info.sigterm.deob.pool.ConstantType;
import info.sigterm.deob.pool.PoolEntry;
import java.io.DataInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
public class ConstantPool
{
private ClassFile classFile;
private int count;
private PoolEntry pool[];
ConstantPool(ClassFile c) throws IOException
{
classFile = c;
DataInputStream is = c.getStream();
count = is.readUnsignedShort();
pool = new PoolEntry[count];
for (int i = 1; i < count; ++i)
{
byte typeCode = is.readByte();
ConstantType type = ConstantType.findFromType(typeCode);
try
{
Constructor<? extends PoolEntry> con = type.getPoolClass().getConstructor(new Class[] { ConstantPool.class });
PoolEntry entry = con.newInstance(this);
pool[i] = entry;
for (int j = 1; j < entry.getSlots(); ++j)
{
pool[i + 1] = entry;
++i;
}
}
catch (Exception e)
{
throw new IOException(e);
}
}
}
public ClassFile getClassFile()
{
return classFile;
}
public PoolEntry getEntry(int index)
{
return pool[index];
}
}

View File

@@ -0,0 +1,26 @@
package info.sigterm.deob;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class Deob
{
public static void main(String[] args) throws IOException
{
JarFile jar = new JarFile(args[0]);
for (Enumeration<JarEntry> it = jar.entries(); it.hasMoreElements();)
{
JarEntry entry = it.nextElement();
if (!entry.getName().endsWith(".class"))
continue;
InputStream is = jar.getInputStream(entry);
ClassFile c = new ClassFile(new DataInputStream(is));
}
}
}

View File

@@ -0,0 +1,31 @@
package info.sigterm.deob;
import java.io.DataInputStream;
import java.io.IOException;
class Field
{
private Fields fields;
private short accessFlags;
private int nameIndex;
private int descriptorIndex;
private Attributes attributes;
Field(Fields fields) throws IOException
{
this.fields = fields;
DataInputStream is = fields.getClassFile().getStream();
accessFlags = is.readShort();
nameIndex = is.readUnsignedShort();
descriptorIndex = is.readUnsignedShort();
attributes = new Attributes(this);
}
public Fields getFields()
{
return fields;
}
}

View File

@@ -0,0 +1,30 @@
package info.sigterm.deob;
import java.io.DataInputStream;
import java.io.IOException;
public class Fields
{
private ClassFile classFile;
private int count;
private Field[] fields;
Fields(ClassFile c) throws IOException
{
classFile = c;
DataInputStream is = c.getStream();
count = is.readUnsignedShort();
fields = new Field[count];
for (int i = 0; i < count; ++i)
fields[i] = new Field(this);
}
public ClassFile getClassFile()
{
return classFile;
}
}

View File

@@ -0,0 +1,25 @@
package info.sigterm.deob;
import java.io.DataInputStream;
import java.io.IOException;
public class Interfaces
{
private ClassFile classFile;
private int count;
private int interfaces[];
Interfaces(ClassFile c) throws IOException
{
classFile = c;
DataInputStream is = c.getStream();
count = is.readUnsignedShort();
interfaces = new int[count];
for (int i = 0; i < count; ++i)
interfaces[i] = is.readUnsignedShort();
}
}

View File

@@ -0,0 +1,31 @@
package info.sigterm.deob;
import java.io.DataInputStream;
import java.io.IOException;
class Method
{
private Methods methods;
private short accessFlags;
private int nameIndex;
private int descriptorIndex;
private Attributes attributes;
Method(Methods methods) throws IOException
{
this.methods = methods;
DataInputStream is = methods.getClassFile().getStream();
accessFlags = is.readShort();
nameIndex = is.readUnsignedShort();
descriptorIndex = is.readUnsignedShort();
attributes = new Attributes(this);
}
public Methods getMethods()
{
return methods;
}
}

View File

@@ -0,0 +1,30 @@
package info.sigterm.deob;
import java.io.DataInputStream;
import java.io.IOException;
public class Methods
{
ClassFile classFile;
private int count;
private Method[] methods;
Methods(ClassFile cf) throws IOException
{
classFile = cf;
DataInputStream is = cf.getStream();
count = is.readUnsignedShort();
methods = new Method[count];
for (int i = 0; i < count; ++i)
methods[i] = new Method(this);
}
public ClassFile getClassFile()
{
return classFile;
}
}

View File

@@ -0,0 +1,32 @@
package info.sigterm.deob.attributes;
import info.sigterm.deob.Attributes;
import java.io.DataInputStream;
import java.io.IOException;
public class Attribute
{
private Attributes attributes;
private AttributeType type;
private int length;
Attribute(Attributes attr, AttributeType type) throws IOException
{
this.attributes = attr;
this.type = type;
DataInputStream is = attr.getStream();
this.length = is.readInt();
}
public Attributes getAttributes()
{
return attributes;
}
public int getLength()
{
return length;
}
}

View File

@@ -0,0 +1,36 @@
package info.sigterm.deob.attributes;
public enum AttributeType
{
CONSTANT_VALUE("ConstantValue", ConstantValue.class),
CODE("Code", Code.class),
UNKNOWN(null, Unknown.class);
private String name;
private Class<? extends Attribute> clazz;
AttributeType(String name, Class<? extends Attribute> clazz)
{
this.name = name;
this.clazz = clazz;
}
public String getName()
{
return name;
}
public Class<? extends Attribute> getAttributeClass()
{
return clazz;
}
public static AttributeType findType(String name)
{
for (AttributeType t : AttributeType.values())
if (t.getName() != null && t.getName().equals(name))
return t;
return UNKNOWN;
}
}

View File

@@ -0,0 +1,31 @@
package info.sigterm.deob.attributes;
import info.sigterm.deob.Attributes;
import info.sigterm.deob.attributes.code.Exceptions;
import java.io.DataInputStream;
import java.io.IOException;
public class Code extends Attribute
{
private int maxStack;
private int maxLocals;
private Exceptions exceptions;
private Attributes attributes;
public Code(Attributes attributes) throws IOException
{
super(attributes, AttributeType.CODE);
DataInputStream is = attributes.getStream();
maxStack = is.readUnsignedShort();
maxLocals = is.readUnsignedShort();
int codeLen = is.readInt();
is.skip(codeLen);
exceptions = new Exceptions(this);
attributes = new Attributes(this);
}
}

View File

@@ -0,0 +1,19 @@
package info.sigterm.deob.attributes;
import info.sigterm.deob.Attributes;
import java.io.DataInputStream;
import java.io.IOException;
public class ConstantValue extends Attribute
{
private int constantVlaueIndex;
public ConstantValue(Attributes attributes) throws IOException
{
super(attributes, AttributeType.CONSTANT_VALUE);
DataInputStream is = attributes.getStream();
constantVlaueIndex = is.readUnsignedShort();
}
}

View File

@@ -0,0 +1,34 @@
package info.sigterm.deob.attributes;
import info.sigterm.deob.Attributes;
import java.io.DataInputStream;
import java.io.IOException;
public class Unknown extends Attribute
{
private byte[] data;
public Unknown(Attributes attributes) throws IOException
{
super(attributes, AttributeType.UNKNOWN);
int len = this.getLength();
DataInputStream is = attributes.getStream();
data = new byte[len];
int read = 0;
while (read < len)
{
int i = is.read(data, read, len - read);
if (i < 0)
throw new IOException("EOF");
read += i;
}
assert read == len;
}
}

View File

@@ -0,0 +1,26 @@
package info.sigterm.deob.attributes.code;
import java.io.DataInputStream;
import java.io.IOException;
class Exception
{
private Exceptions exceptions;
private int startPc;
private int endPc;
private int handlerPc;
private int catchType;
Exception(Exceptions exceptions) throws IOException
{
this.exceptions = exceptions;
DataInputStream is = exceptions.getCode().getAttributes().getStream();
startPc = is.readUnsignedShort();
endPc = is.readUnsignedShort();
handlerPc = is.readUnsignedShort();
catchType = is.readUnsignedShort();
}
}

View File

@@ -0,0 +1,30 @@
package info.sigterm.deob.attributes.code;
import info.sigterm.deob.attributes.Code;
import java.io.DataInputStream;
import java.io.IOException;
public class Exceptions
{
private Code code;
private Exception[] exceptions;
public Exceptions(Code code) throws IOException
{
this.code = code;
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);
}
public Code getCode()
{
return code;
}
}

View File

@@ -0,0 +1,19 @@
package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool;
import java.io.DataInputStream;
import java.io.IOException;
public class Class extends PoolEntry
{
private int index;
public Class(ConstantPool pool) throws IOException
{
super(pool, ConstantType.CLASS);
DataInputStream is = pool.getClassFile().getStream();
index = is.readUnsignedShort();
}
}

View File

@@ -0,0 +1,43 @@
package info.sigterm.deob.pool;
public enum ConstantType
{
CLASS(7, Class.class),
FIELDREF(9, Field.class),
METHODREF(10, Method.class),
INTERFACE_METHOD_REF(11, InterfaceMethod.class),
STRING(8, String.class),
INTEGER(3, Integer.class),
FLOAT(4, Float.class),
LONG(5, Long.class),
DOUBLE(6, Double.class),
NAME_AND_TYPE(12, NameAndType.class),
UTF8(1, UTF8.class);
private int value;
private java.lang.Class<? extends PoolEntry> clazz;
ConstantType(int value, java.lang.Class<? extends PoolEntry> clazz)
{
this.value = value;
this.clazz = clazz;
}
public int getType()
{
return value;
}
public java.lang.Class<? extends PoolEntry> getPoolClass()
{
return clazz;
}
public static ConstantType findFromType(int type)
{
for (ConstantType t : ConstantType.values())
if (t.getType() == type)
return t;
return null;
}
}

View File

@@ -0,0 +1,26 @@
package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool;
import java.io.DataInputStream;
import java.io.IOException;
public class Double extends PoolEntry
{
private double value;
public Double(ConstantPool pool) throws IOException
{
super(pool, ConstantType.DOUBLE);
DataInputStream is = pool.getClassFile().getStream();
value = is.readDouble();
}
@Override
public int getSlots()
{
return 2;
}
}

View File

@@ -0,0 +1,22 @@
package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool;
import java.io.DataInputStream;
import java.io.IOException;
public class Field extends PoolEntry
{
private int classIndex;
private int nameAndTypeIndex;
public Field(ConstantPool pool) throws IOException
{
super(pool, ConstantType.FIELDREF);
DataInputStream is = pool.getClassFile().getStream();
classIndex = is.readUnsignedShort();
nameAndTypeIndex = is.readUnsignedShort();
}
}

View File

@@ -0,0 +1,20 @@
package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool;
import java.io.DataInputStream;
import java.io.IOException;
public class Float extends PoolEntry
{
private float value;
public Float(ConstantPool pool) throws IOException
{
super(pool, ConstantType.FLOAT);
DataInputStream is = pool.getClassFile().getStream();
value = is.readFloat();
}
}

View File

@@ -0,0 +1,20 @@
package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool;
import java.io.DataInputStream;
import java.io.IOException;
public class Integer extends PoolEntry
{
private int value;
public Integer(ConstantPool pool) throws IOException
{
super(pool, ConstantType.INTEGER);
DataInputStream is = pool.getClassFile().getStream();
value = is.readInt();
}
}

View File

@@ -0,0 +1,22 @@
package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool;
import java.io.DataInputStream;
import java.io.IOException;
public class InterfaceMethod extends PoolEntry
{
private int classIndex;
private int nameAndTypeIndex;
public InterfaceMethod(ConstantPool pool) throws IOException
{
super(pool, ConstantType.INTERFACE_METHOD_REF);
DataInputStream is = pool.getClassFile().getStream();
classIndex = is.readUnsignedShort();
nameAndTypeIndex = is.readUnsignedShort();
}
}

View File

@@ -0,0 +1,26 @@
package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool;
import java.io.DataInputStream;
import java.io.IOException;
public class Long extends PoolEntry
{
private long value;
public Long(ConstantPool pool) throws IOException
{
super(pool, ConstantType.LONG);
DataInputStream is = pool.getClassFile().getStream();
value = is.readLong();
}
@Override
public int getSlots()
{
return 2;
}
}

View File

@@ -0,0 +1,22 @@
package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool;
import java.io.DataInputStream;
import java.io.IOException;
public class Method extends PoolEntry
{
private int classIndex;
private int nameAndTypeIndex;
public Method(ConstantPool pool) throws IOException
{
super(pool, ConstantType.METHODREF);
DataInputStream is = pool.getClassFile().getStream();
classIndex = is.readUnsignedShort();
nameAndTypeIndex = is.readUnsignedShort();
}
}

View File

@@ -0,0 +1,22 @@
package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool;
import java.io.DataInputStream;
import java.io.IOException;
public class NameAndType extends PoolEntry
{
private int nameIndex;
private int descriptorIndex;
public NameAndType(ConstantPool pool) throws IOException
{
super(pool, ConstantType.NAME_AND_TYPE);
DataInputStream is = pool.getClassFile().getStream();
nameIndex = is.readUnsignedShort();
descriptorIndex = is.readUnsignedShort();
}
}

View File

@@ -0,0 +1,20 @@
package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool;
public abstract class PoolEntry
{
private ConstantPool pool;
private ConstantType type;
protected PoolEntry(ConstantPool pool, ConstantType type)
{
this.pool = pool;
this.type = type;
}
public int getSlots()
{
return 1;
}
}

View File

@@ -0,0 +1,20 @@
package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool;
import java.io.DataInputStream;
import java.io.IOException;
public class String extends PoolEntry
{
private int stringIndex;
public String(ConstantPool pool) throws IOException
{
super(pool, ConstantType.STRING);
DataInputStream is = pool.getClassFile().getStream();
stringIndex = is.readUnsignedShort();
}
}

View File

@@ -0,0 +1,48 @@
package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool;
import java.io.DataInputStream;
import java.io.IOException;
public class UTF8 extends PoolEntry
{
private StringBuilder sb = new StringBuilder();
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;
}
}
}
public java.lang.String getValue()
{
return sb.toString();
}
}