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"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </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"> <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes> <attributes>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </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"> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<attributes> <attributes>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>

View File

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

View File

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

View File

@@ -46,7 +46,7 @@ public class Fields
public Field findField(NameAndType nat) public Field findField(NameAndType nat)
{ {
for (Field f : fields) 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 f;
return null; 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.attributes.code.instruction.types.LVTInstruction;
import info.sigterm.deob.callgraph.Node; import info.sigterm.deob.callgraph.Node;
import info.sigterm.deob.pool.NameAndType; import info.sigterm.deob.pool.NameAndType;
import info.sigterm.deob.signature.Signature;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@@ -22,7 +23,7 @@ public class Method
private short accessFlags; private short accessFlags;
private String name; private String name;
private String descriptor; private Signature arguments;
private Attributes attributes; private Attributes attributes;
private List<Node> callsTo = new ArrayList<>(), private List<Node> callsTo = new ArrayList<>(),
callsFrom = new ArrayList<>(); callsFrom = new ArrayList<>();
@@ -36,7 +37,7 @@ public class Method
accessFlags = is.readShort(); accessFlags = is.readShort();
name = pool.getUTF8(is.readUnsignedShort()); name = pool.getUTF8(is.readUnsignedShort());
descriptor = pool.getUTF8(is.readUnsignedShort()); arguments = new Signature(pool.getUTF8(is.readUnsignedShort()));
attributes = new Attributes(this); attributes = new Attributes(this);
} }
@@ -46,7 +47,7 @@ public class Method
out.writeShort(accessFlags); out.writeShort(accessFlags);
out.writeShort(pool.makeUTF8(name)); out.writeShort(pool.makeUTF8(name));
out.writeShort(pool.makeUTF8(descriptor)); out.writeShort(pool.makeUTF8(arguments.toString()));
attributes.write(out); attributes.write(out);
} }
@@ -65,14 +66,14 @@ public class Method
return name; return name;
} }
public String getDescriptor() public Signature getDescriptor()
{ {
return descriptor; return arguments;
} }
public NameAndType getNameAndType() public NameAndType getNameAndType()
{ {
return new NameAndType(name, descriptor); return new NameAndType(name, arguments);
} }
public boolean isStatic() public boolean isStatic()

View File

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

View File

@@ -55,7 +55,7 @@ public class ClassInstance
public StaticFieldInstance findStaticField(NameAndType nat) public StaticFieldInstance findStaticField(NameAndType nat)
{ {
for (StaticFieldInstance f : fields) 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 f;
return null; return null;
} }

View File

@@ -44,7 +44,7 @@ public class ObjectInstance extends ObjectInstanceBase
public FieldInstance getField(NameAndType nat) public FieldInstance getField(NameAndType nat)
{ {
for (FieldInstance f : fields) 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 f;
return null; return null;
} }

View File

@@ -1,17 +1,24 @@
package info.sigterm.deob.pool; package info.sigterm.deob.pool;
import info.sigterm.deob.ConstantPool; import info.sigterm.deob.ConstantPool;
import info.sigterm.deob.signature.Signature;
import info.sigterm.deob.signature.Type;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Objects;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class NameAndType extends PoolEntry public class NameAndType extends PoolEntry
{ {
private int nameIndex, descriptorIndex; 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 public NameAndType(ConstantPool pool) throws IOException
{ {
@@ -23,26 +30,34 @@ public class NameAndType extends PoolEntry
descriptorIndex = is.readUnsignedShort(); 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); super(null, ConstantType.NAME_AND_TYPE);
this.name = name; this.name = name;
descriptor = type; signature = type;
} }
@Override @Override
public void resolve() public void resolve()
{ {
name = this.getPool().getUTF8(nameIndex); 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 @Override
public void prime() public void prime()
{ {
nameIndex = this.getPool().makeUTF8(name); 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 @Override
@@ -52,7 +67,7 @@ public class NameAndType extends PoolEntry
return false; return false;
NameAndType nat = (NameAndType) other; 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() public java.lang.String getName()
@@ -60,15 +75,19 @@ public class NameAndType extends PoolEntry
return name; return name;
} }
public java.lang.String getDescriptor() public Signature getDescriptor()
{ {
return descriptor; return signature;
}
public Type getDescriptorType()
{
return type;
} }
public Object getStackObject() public Object getStackObject()
{ {
java.lang.String desc = getDescriptor(); switch (type.toString())
switch (desc)
{ {
case "B": case "B":
return (byte) 0; return (byte) 0;
@@ -91,32 +110,16 @@ public class NameAndType extends PoolEntry
} }
} }
private static Pattern allParamsPattern = Pattern.compile("(\\(.*?\\))");
private static Pattern paramsPattern = Pattern.compile("(\\[?)(B|C|Z|S|I|J|F|D|(:?L[^;]+;))");
public int getNumberOfArgs() public int getNumberOfArgs()
{ {
java.lang.String methodRefType = this.getDescriptor(); return signature.size();
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;
} }
public boolean isNonVoid() public boolean isNonVoid()
{ {
java.lang.String methodRefType = this.getDescriptor(); if (this.getName().equals("<init>") || this.getName().equals("<cinit>"))
if (this.getName().equals("<init>"))
return true; return true;
return !methodRefType.endsWith(")V"); return !signature.getReturnValue().equals("V");
} }
@Override @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();
}
}