Descriptor stuff

This commit is contained in:
Adam
2015-05-10 15:01:39 -04:00
parent 4af719032d
commit ba7486b98b
11 changed files with 163 additions and 52 deletions

View File

@@ -6,17 +6,17 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<attributes>
<attribute name="maven.pomderived" value="true"/>

View File

@@ -43,7 +43,7 @@ public class Deob
group.buildCallGraph();
checkCallGraph(group);
//checkParameters(group);
checkParameters(group);
//execute(group);

View File

@@ -2,6 +2,7 @@ package info.sigterm.deob;
import info.sigterm.deob.attributes.Attributes;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.signature.Type;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -23,7 +24,8 @@ public class Field
private Fields fields;
private short accessFlags;
private String name, descriptor;
private String name;
private Type type;
private Attributes attributes;
private ArrayList<Instruction> instructions = new ArrayList<Instruction>(); // instructions which reference this field
@@ -37,7 +39,7 @@ public class Field
accessFlags = is.readShort();
name = pool.getUTF8(is.readUnsignedShort());
descriptor = pool.getUTF8(is.readUnsignedShort());
type = new Type(pool.getUTF8(is.readUnsignedShort()));
attributes = new Attributes(this);
}
@@ -47,7 +49,7 @@ public class Field
out.writeShort(accessFlags);
out.writeShort(pool.makeUTF8(name));
out.writeShort(pool.makeUTF8(descriptor));
out.writeShort(pool.makeUTF8(type.toString()));
attributes.write(out);
}
@@ -66,9 +68,9 @@ public class Field
return name;
}
public String getDescriptor()
public Type getType()
{
return descriptor;
return type;
}
public Attributes getAttributes()

View File

@@ -46,7 +46,7 @@ public class Fields
public Field findField(NameAndType nat)
{
for (Field f : fields)
if (f.getName().equals(nat.getName()) && f.getDescriptor().equals(nat.getDescriptor()))
if (f.getName().equals(nat.getName()) && f.getType().equals(nat.getDescriptorType()))
return f;
return null;
}

View File

@@ -7,6 +7,7 @@ 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.signature.Signature;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -22,7 +23,7 @@ public class Method
private short accessFlags;
private String name;
private String descriptor;
private Signature arguments;
private Attributes attributes;
private List<Node> callsTo = new ArrayList<>(),
callsFrom = new ArrayList<>();
@@ -36,7 +37,7 @@ public class Method
accessFlags = is.readShort();
name = pool.getUTF8(is.readUnsignedShort());
descriptor = pool.getUTF8(is.readUnsignedShort());
arguments = new Signature(pool.getUTF8(is.readUnsignedShort()));
attributes = new Attributes(this);
}
@@ -46,7 +47,7 @@ public class Method
out.writeShort(accessFlags);
out.writeShort(pool.makeUTF8(name));
out.writeShort(pool.makeUTF8(descriptor));
out.writeShort(pool.makeUTF8(arguments.toString()));
attributes.write(out);
}
@@ -65,14 +66,14 @@ public class Method
return name;
}
public String getDescriptor()
public Signature getDescriptor()
{
return descriptor;
return arguments;
}
public NameAndType getNameAndType()
{
return new NameAndType(name, descriptor);
return new NameAndType(name, arguments);
}
public boolean isStatic()

View File

@@ -1,6 +1,7 @@
package info.sigterm.deob;
import info.sigterm.deob.pool.NameAndType;
import info.sigterm.deob.signature.Signature;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -57,7 +58,7 @@ public class Methods
return null;
}
public Method findMethod(String name, String type)
public Method findMethod(String name, Signature type)
{
for (Method m : methods)
if (m.getName().equals(name) && m.getDescriptor().equals(type))

View File

@@ -55,7 +55,7 @@ public class ClassInstance
public StaticFieldInstance findStaticField(NameAndType nat)
{
for (StaticFieldInstance f : fields)
if (f.getField().getName().equals(nat.getName()) && f.getField().getDescriptor().equals(nat.getDescriptor()))
if (f.getField().getName().equals(nat.getName()) && f.getField().getType().equals(nat.getDescriptorType()))
return f;
return null;
}

View File

@@ -44,7 +44,7 @@ public class ObjectInstance extends ObjectInstanceBase
public FieldInstance getField(NameAndType nat)
{
for (FieldInstance f : fields)
if (f.getField().getName().equals(nat.getName()) && f.getField().getDescriptor().equals(nat.getDescriptor()))
if (f.getField().getName().equals(nat.getName()) && f.getField().getType().equals(nat.getDescriptorType()))
return f;
return null;
}

View File

@@ -1,17 +1,24 @@
package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool;
import info.sigterm.deob.signature.Signature;
import info.sigterm.deob.signature.Type;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NameAndType extends PoolEntry
{
private int nameIndex, descriptorIndex;
private java.lang.String name, descriptor;
private java.lang.String name;
/* method signature */
private Signature signature;
/* type */
private Type type;
public NameAndType(ConstantPool pool) throws IOException
{
@@ -23,26 +30,34 @@ public class NameAndType extends PoolEntry
descriptorIndex = is.readUnsignedShort();
}
public NameAndType(java.lang.String name, java.lang.String type)
public NameAndType(java.lang.String name, Signature type)
{
super(null, ConstantType.NAME_AND_TYPE);
this.name = name;
descriptor = type;
signature = type;
}
@Override
public void resolve()
{
name = this.getPool().getUTF8(nameIndex);
descriptor = this.getPool().getUTF8(descriptorIndex);
java.lang.String sig = this.getPool().getUTF8(descriptorIndex);
if (sig.startsWith("("))
signature = new Signature(sig);
else
type = new Type(sig);
}
@Override
public void prime()
{
nameIndex = this.getPool().makeUTF8(name);
descriptorIndex = this.getPool().makeUTF8(descriptor);
if (signature != null)
descriptorIndex = this.getPool().makeUTF8(signature.toString());
else
descriptorIndex = this.getPool().makeUTF8(type.toString());
}
@Override
@@ -52,7 +67,7 @@ public class NameAndType extends PoolEntry
return false;
NameAndType nat = (NameAndType) other;
return name.equals(nat.name) && descriptor.equals(nat.descriptor);
return name.equals(nat.name) && Objects.equals(signature, nat.signature) && Objects.equals(type, nat.type);
}
public java.lang.String getName()
@@ -60,15 +75,19 @@ public class NameAndType extends PoolEntry
return name;
}
public java.lang.String getDescriptor()
public Signature getDescriptor()
{
return descriptor;
return signature;
}
public Type getDescriptorType()
{
return type;
}
public Object getStackObject()
{
java.lang.String desc = getDescriptor();
switch (desc)
switch (type.toString())
{
case "B":
return (byte) 0;
@@ -90,33 +109,17 @@ public class NameAndType extends PoolEntry
return null;
}
}
private static Pattern allParamsPattern = Pattern.compile("(\\(.*?\\))");
private static Pattern paramsPattern = Pattern.compile("(\\[?)(B|C|Z|S|I|J|F|D|(:?L[^;]+;))");
public int getNumberOfArgs()
{
java.lang.String methodRefType = this.getDescriptor();
Matcher m = allParamsPattern.matcher(methodRefType);
if (!m.find())
throw new IllegalArgumentException("Method signature does not contain parameters");
java.lang.String paramsDescriptor = m.group(1);
Matcher mParam = paramsPattern.matcher(paramsDescriptor);
int count = 0;
while (mParam.find())
count++;
return count;
return signature.size();
}
public boolean isNonVoid()
{
java.lang.String methodRefType = this.getDescriptor();
if (this.getName().equals("<init>"))
if (this.getName().equals("<init>") || this.getName().equals("<cinit>"))
return true;
return !methodRefType.endsWith(")V");
return !signature.getReturnValue().equals("V");
}
@Override

View File

@@ -0,0 +1,66 @@
package info.sigterm.deob.signature;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Signature
{
private static Pattern paramRetPattern = Pattern.compile("\\((.*)\\)(.*)"),
paramsPattern = Pattern.compile("(\\[*(?:B|C|Z|S|I|J|F|D|(?:L[^;]*;)))");
private List<Type> arguments = new ArrayList<>();
private Type rv;
public Signature(String str)
{
Matcher m = paramRetPattern.matcher(str);
if (!m.find())
throw new IllegalArgumentException("Signature has no arguments");
String args = m.group(1), ret = m.group(2);
m = paramsPattern.matcher(args);
while (m.find())
{
String arg = m.group(1);
arguments.add(new Type(arg));
}
rv = new Type(ret);
}
@Override
public boolean equals(Object other)
{
if (!(other instanceof Signature))
return false;
Signature a = (Signature) other;
return arguments.equals(a.arguments) && rv.equals(a.rv);
}
@Override
public String toString()
{
StringBuffer sb = new StringBuffer();
sb.append('(');
for (Type a : arguments)
sb.append(a.toString());
sb.append(')');
sb.append(rv.toString());
return sb.toString();
}
public int size()
{
return arguments.size();
}
public Type getReturnValue()
{
return rv;
}
}

View File

@@ -0,0 +1,38 @@
package info.sigterm.deob.signature;
public class Type
{
private String type;
private int arrayDimms;
public Type(String str)
{
while (str.startsWith("["))
{
++arrayDimms;
str = str.substring(1);
}
type = str;
}
@Override
public boolean equals(Object other)
{
if (!(other instanceof Type))
return false;
Type a = (Type) other;
return type.equals(a.type) && arrayDimms == a.arrayDimms;
}
@Override
public String toString()
{
StringBuffer sb = new StringBuffer();
for (int i = 0; i < arrayDimms; ++i)
sb.append('[');
sb.append(type);
return sb.toString();
}
}