Descriptor stuff
This commit is contained in:
@@ -43,7 +43,7 @@ public class Deob
|
||||
group.buildCallGraph();
|
||||
|
||||
checkCallGraph(group);
|
||||
//checkParameters(group);
|
||||
checkParameters(group);
|
||||
|
||||
//execute(group);
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
66
src/main/java/info/sigterm/deob/signature/Signature.java
Normal file
66
src/main/java/info/sigterm/deob/signature/Signature.java
Normal 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;
|
||||
}
|
||||
}
|
||||
38
src/main/java/info/sigterm/deob/signature/Type.java
Normal file
38
src/main/java/info/sigterm/deob/signature/Type.java
Normal 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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user