Descriptor stuff
This commit is contained in:
12
.classpath
12
.classpath
@@ -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"/>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class Deob
|
|||||||
group.buildCallGraph();
|
group.buildCallGraph();
|
||||||
|
|
||||||
checkCallGraph(group);
|
checkCallGraph(group);
|
||||||
//checkParameters(group);
|
checkParameters(group);
|
||||||
|
|
||||||
//execute(group);
|
//execute(group);
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -90,33 +109,17 @@ public class NameAndType extends PoolEntry
|
|||||||
return null;
|
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()
|
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
|
||||||
|
|||||||
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