diff --git a/.classpath b/.classpath
index bb4ae148a3..9a1998c196 100644
--- a/.classpath
+++ b/.classpath
@@ -6,17 +6,17 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/main/java/info/sigterm/deob/Deob.java b/src/main/java/info/sigterm/deob/Deob.java
index 60748290c7..440a8be1d9 100644
--- a/src/main/java/info/sigterm/deob/Deob.java
+++ b/src/main/java/info/sigterm/deob/Deob.java
@@ -43,7 +43,7 @@ public class Deob
group.buildCallGraph();
checkCallGraph(group);
- //checkParameters(group);
+ checkParameters(group);
//execute(group);
diff --git a/src/main/java/info/sigterm/deob/Field.java b/src/main/java/info/sigterm/deob/Field.java
index 0931b0824a..61119de692 100644
--- a/src/main/java/info/sigterm/deob/Field.java
+++ b/src/main/java/info/sigterm/deob/Field.java
@@ -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 instructions = new ArrayList(); // 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()
diff --git a/src/main/java/info/sigterm/deob/Fields.java b/src/main/java/info/sigterm/deob/Fields.java
index 360bae0602..aa46de1f63 100644
--- a/src/main/java/info/sigterm/deob/Fields.java
+++ b/src/main/java/info/sigterm/deob/Fields.java
@@ -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;
}
diff --git a/src/main/java/info/sigterm/deob/Method.java b/src/main/java/info/sigterm/deob/Method.java
index 7676aeaac7..ba880b32a7 100644
--- a/src/main/java/info/sigterm/deob/Method.java
+++ b/src/main/java/info/sigterm/deob/Method.java
@@ -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 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()
diff --git a/src/main/java/info/sigterm/deob/Methods.java b/src/main/java/info/sigterm/deob/Methods.java
index c3dabe4330..c2de700b95 100644
--- a/src/main/java/info/sigterm/deob/Methods.java
+++ b/src/main/java/info/sigterm/deob/Methods.java
@@ -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))
diff --git a/src/main/java/info/sigterm/deob/execution/ClassInstance.java b/src/main/java/info/sigterm/deob/execution/ClassInstance.java
index dd724f080d..d5156b08f1 100644
--- a/src/main/java/info/sigterm/deob/execution/ClassInstance.java
+++ b/src/main/java/info/sigterm/deob/execution/ClassInstance.java
@@ -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;
}
diff --git a/src/main/java/info/sigterm/deob/execution/ObjectInstance.java b/src/main/java/info/sigterm/deob/execution/ObjectInstance.java
index a396b192f6..bb9b224964 100644
--- a/src/main/java/info/sigterm/deob/execution/ObjectInstance.java
+++ b/src/main/java/info/sigterm/deob/execution/ObjectInstance.java
@@ -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;
}
diff --git a/src/main/java/info/sigterm/deob/pool/NameAndType.java b/src/main/java/info/sigterm/deob/pool/NameAndType.java
index 5a5122071d..6821906301 100644
--- a/src/main/java/info/sigterm/deob/pool/NameAndType.java
+++ b/src/main/java/info/sigterm/deob/pool/NameAndType.java
@@ -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(""))
+ if (this.getName().equals("") || this.getName().equals(""))
return true;
- return !methodRefType.endsWith(")V");
+ return !signature.getReturnValue().equals("V");
}
@Override
diff --git a/src/main/java/info/sigterm/deob/signature/Signature.java b/src/main/java/info/sigterm/deob/signature/Signature.java
new file mode 100644
index 0000000000..bda64af7f0
--- /dev/null
+++ b/src/main/java/info/sigterm/deob/signature/Signature.java
@@ -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 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;
+ }
+}
diff --git a/src/main/java/info/sigterm/deob/signature/Type.java b/src/main/java/info/sigterm/deob/signature/Type.java
new file mode 100644
index 0000000000..0dd118aa66
--- /dev/null
+++ b/src/main/java/info/sigterm/deob/signature/Type.java
@@ -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();
+ }
+}