diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..b83d22266a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/src/main/java/info/sigterm/deob/ClassFile.java b/src/main/java/info/sigterm/deob/ClassFile.java index 336282f350..228dc5b080 100644 --- a/src/main/java/info/sigterm/deob/ClassFile.java +++ b/src/main/java/info/sigterm/deob/ClassFile.java @@ -102,6 +102,19 @@ public class ClassFile return null; } + + public Method findMethod(NameAndType nat) + { + Method m = methods.findMethod(nat); + if (m != null) + return m; + + ClassFile parent = getParent(); + if (parent != null) + return parent.findMethod(nat); + + return null; + } public void buildClassGraph() { diff --git a/src/main/java/info/sigterm/deob/Method.java b/src/main/java/info/sigterm/deob/Method.java index 6478219fcd..7d1f1115f4 100644 --- a/src/main/java/info/sigterm/deob/Method.java +++ b/src/main/java/info/sigterm/deob/Method.java @@ -3,6 +3,7 @@ package info.sigterm.deob; import info.sigterm.deob.attributes.AttributeType; import info.sigterm.deob.attributes.Attributes; import info.sigterm.deob.attributes.Code; +import info.sigterm.deob.pool.UTF8; import java.io.DataInputStream; import java.io.IOException; @@ -32,6 +33,18 @@ public class Method { return methods; } + + public String getName() + { + UTF8 u = (UTF8) methods.getClassFile().getPool().getEntry(nameIndex); + return u.getValue(); + } + + public String getDescriptor() + { + UTF8 u = (UTF8) methods.getClassFile().getPool().getEntry(descriptorIndex); + return u.getValue(); + } public Code getCode() { diff --git a/src/main/java/info/sigterm/deob/Methods.java b/src/main/java/info/sigterm/deob/Methods.java index 67cef2f1d8..a43a600020 100644 --- a/src/main/java/info/sigterm/deob/Methods.java +++ b/src/main/java/info/sigterm/deob/Methods.java @@ -1,5 +1,7 @@ package info.sigterm.deob; +import info.sigterm.deob.pool.NameAndType; + import java.io.DataInputStream; import java.io.IOException; @@ -27,6 +29,14 @@ public class Methods { return classFile; } + + public Method findMethod(NameAndType nat) + { + for (Method m : methods) + if (m.getName().equals(nat.getName()) && m.getDescriptor().equals(nat.getDescriptor())) + return m; + return null; + } public void buildInstructionGraph() { diff --git a/src/main/java/info/sigterm/deob/attributes/code/InstructionType.java b/src/main/java/info/sigterm/deob/attributes/code/InstructionType.java index 1b47c4fde1..207a628ae4 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/InstructionType.java +++ b/src/main/java/info/sigterm/deob/attributes/code/InstructionType.java @@ -188,7 +188,6 @@ public enum InstructionType INVOKESPECIAL(0xb7, "invokespecial", InvokeSpecial.class), INVOKESTATIC(0xb8, "invokestatic", InvokeStatic.class), INVOKEINTERFACE(0xb9, "invokeinterface", InvokeInterface.class), - INVOKEDYNAMIC(0xba, "invokedynamic", InvokeDynamic.class), NEW(0xbb, "new", New.class), NEWARRAY(0xbc, "newarray", NewArray.class), ANEWARRAY(0xbd, "anewarray", ANewArray.class), diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java index d672b63efd..be60145718 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java @@ -2,7 +2,6 @@ package info.sigterm.deob.attributes.code.instructions; import info.sigterm.deob.ClassFile; import info.sigterm.deob.ConstantPool; -import info.sigterm.deob.attributes.ConstantValue; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; @@ -12,7 +11,6 @@ import info.sigterm.deob.execution.StaticFieldInstance; import info.sigterm.deob.pool.Class; import info.sigterm.deob.pool.Field; import info.sigterm.deob.pool.NameAndType; -import info.sigterm.deob.pool.PoolEntry; import java.io.DataInputStream; import java.io.IOException; @@ -51,10 +49,7 @@ public class GetStatic extends Instruction ClassInstance ci = frame.getPath().getClassInstance(cf); StaticFieldInstance fi = ci.findStaticField(nat); - ConstantValue value = fi.getValue(); - - PoolEntry pe = value.getValue(); - Object ovalue = pe.getObject(); + Object ovalue = fi.getValue(); frame.getStack().push(ovalue); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeDynamic.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeDynamic.java deleted file mode 100644 index 1395e9a44b..0000000000 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeDynamic.java +++ /dev/null @@ -1,24 +0,0 @@ -package info.sigterm.deob.attributes.code.instructions; - -import info.sigterm.deob.attributes.code.Instruction; -import info.sigterm.deob.attributes.code.InstructionType; -import info.sigterm.deob.attributes.code.Instructions; - -import java.io.DataInputStream; -import java.io.IOException; - -public class InvokeDynamic extends Instruction -{ - private int index; - - public InvokeDynamic(Instructions instructions, InstructionType type, int pc) throws IOException - { - super(instructions, type, pc); - - DataInputStream is = instructions.getCode().getAttributes().getStream(); - index = is.readUnsignedShort(); - is.skip(2); - length += 4; - } - -} diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java index bc32434b0d..a0572ed858 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java @@ -1,8 +1,15 @@ package info.sigterm.deob.attributes.code.instructions; +import info.sigterm.deob.ClassFile; +import info.sigterm.deob.ConstantPool; +import info.sigterm.deob.Method; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.execution.ClassInstance; +import info.sigterm.deob.execution.Frame; +import info.sigterm.deob.execution.ObjectInstance; +import info.sigterm.deob.pool.InterfaceMethod; import java.io.DataInputStream; import java.io.IOException; @@ -23,4 +30,24 @@ public class InvokeInterface extends Instruction length += 4; } + @Override + public void execute(Frame e) + { + ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); + + ConstantPool pool = thisClass.getPool(); + InterfaceMethod method = (InterfaceMethod) pool.getEntry(index); + + ObjectInstance object = (ObjectInstance) e.getStack().pop(); + ClassInstance objectType = object.getType(); + + Object[] args = new Object[count + 1]; + args[0] = object; + for (int i = 1; i < count + 1; ++i) + args[i] = e.getStack().pop(); + + Method meth = objectType.getClassFile().findMethod(method.getNameAndType()); + e.getPath().invoke(meth, args); + } + } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/NewArray.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/NewArray.java index b231c3d3db..1f37e672d3 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/NewArray.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/NewArray.java @@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.execution.Frame; import java.io.DataInputStream; import java.io.IOException; @@ -20,4 +21,38 @@ public class NewArray extends Instruction length += 1; } + @Override + public void execute(Frame e) + { + int count = (int) e.getStack().pop(); + + switch (type) + { + case 4: + e.getStack().push(new boolean[count]); + break; + case 5: + e.getStack().push(new char[count]); + break; + case 6: + e.getStack().push(new float[count]); + break; + case 7: + e.getStack().push(new double[count]); + break; + case 8: + e.getStack().push(new byte[count]); + break; + case 9: + e.getStack().push(new short[count]); + break; + case 10: + e.getStack().push(new int[count]); + break; + case 11: + e.getStack().push(new long[count]); + break; + } + } + } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/PutField.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/PutField.java index 90818b5da9..366a61464c 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/PutField.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/PutField.java @@ -1,8 +1,15 @@ package info.sigterm.deob.attributes.code.instructions; +import info.sigterm.deob.ClassFile; +import info.sigterm.deob.ConstantPool; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.execution.FieldInstance; +import info.sigterm.deob.execution.Frame; +import info.sigterm.deob.execution.ObjectInstance; +import info.sigterm.deob.pool.Field; +import info.sigterm.deob.pool.NameAndType; import java.io.DataInputStream; import java.io.IOException; @@ -20,4 +27,20 @@ public class PutField extends Instruction length += 2; } + @Override + public void execute(Frame e) + { + ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); + + ConstantPool pool = thisClass.getPool(); + Field entry = (Field) pool.getEntry(index); + NameAndType nat = entry.getNameAndType(); + + ObjectInstance object = (ObjectInstance) e.getStack().pop(); + Object value = e.getStack().pop(); + + FieldInstance field = object.getField(nat); + field.setValue(value); + } + } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/PutStatic.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/PutStatic.java index d2700378b8..aa496a3079 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/PutStatic.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/PutStatic.java @@ -1,8 +1,16 @@ package info.sigterm.deob.attributes.code.instructions; +import info.sigterm.deob.ClassFile; +import info.sigterm.deob.ConstantPool; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.execution.ClassInstance; +import info.sigterm.deob.execution.Frame; +import info.sigterm.deob.execution.StaticFieldInstance; +import info.sigterm.deob.pool.Class; +import info.sigterm.deob.pool.Field; +import info.sigterm.deob.pool.NameAndType; import java.io.DataInputStream; import java.io.IOException; @@ -20,4 +28,25 @@ public class PutStatic extends Instruction length += 2; } + @Override + public void execute(Frame e) + { + ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile(); + + ConstantPool pool = thisClass.getPool(); + Field entry = (Field) pool.getEntry(index); + Class clazz = entry.getClassEntry(); + NameAndType nat = entry.getNameAndType(); + + Object value = e.getStack().pop(); + + ClassFile cf = thisClass.getGroup().findClass(clazz.getName()); + if (cf == null) + return; + + ClassInstance ci = e.getPath().getClassInstance(cf); + StaticFieldInstance fi = ci.findStaticField(nat); + fi.setField(value); + } + } diff --git a/src/main/java/info/sigterm/deob/execution/Execution.java b/src/main/java/info/sigterm/deob/execution/Execution.java index 8d3f3a7856..0b48433619 100644 --- a/src/main/java/info/sigterm/deob/execution/Execution.java +++ b/src/main/java/info/sigterm/deob/execution/Execution.java @@ -18,7 +18,7 @@ public class Execution public void run(Method method, Object... args) { Path p = new Path(this); - p.init(method, args); + p.invoke(method, args); } public void addPath(Path p) diff --git a/src/main/java/info/sigterm/deob/execution/FieldInstance.java b/src/main/java/info/sigterm/deob/execution/FieldInstance.java index ec35a69302..be641674ab 100644 --- a/src/main/java/info/sigterm/deob/execution/FieldInstance.java +++ b/src/main/java/info/sigterm/deob/execution/FieldInstance.java @@ -24,4 +24,9 @@ public class FieldInstance { return value; } + + public void setValue(Object obj) + { + value = obj; + } } diff --git a/src/main/java/info/sigterm/deob/execution/Frame.java b/src/main/java/info/sigterm/deob/execution/Frame.java index a64fd07675..7bf3380824 100644 --- a/src/main/java/info/sigterm/deob/execution/Frame.java +++ b/src/main/java/info/sigterm/deob/execution/Frame.java @@ -39,14 +39,6 @@ public class Frame { return variables; } - - public void init(Object[] args) - { - for (Object o : args) - stack.push(o); - - execute(); - } public void execute() { diff --git a/src/main/java/info/sigterm/deob/execution/Path.java b/src/main/java/info/sigterm/deob/execution/Path.java index 75159effa6..d3c63c2a85 100644 --- a/src/main/java/info/sigterm/deob/execution/Path.java +++ b/src/main/java/info/sigterm/deob/execution/Path.java @@ -64,13 +64,6 @@ public class Path { return frames.peek(); } - - public void init(Method method, Object[] args) - { - Frame f = new Frame(this, method); - frames.push(f); - f.init(args); - } public Path dup() { @@ -78,4 +71,14 @@ public class Path execution.addPath(other); return other; } + + public void invoke(Method method, Object[] args) + { + Frame f = new Frame(this, method); + Variables vars = f.getVariables(); + for (int i = 0; i < args.length; ++i) + vars.set(i, args[i]); + frames.push(f); + f.execute(); + } } diff --git a/src/main/java/info/sigterm/deob/execution/StaticFieldInstance.java b/src/main/java/info/sigterm/deob/execution/StaticFieldInstance.java index e8be745e71..fec46d08fa 100644 --- a/src/main/java/info/sigterm/deob/execution/StaticFieldInstance.java +++ b/src/main/java/info/sigterm/deob/execution/StaticFieldInstance.java @@ -7,13 +7,13 @@ public class StaticFieldInstance { private ClassInstance clazz; private Field field; - private ConstantValue value; + private Object value; public StaticFieldInstance(ClassInstance clazz, Field field, ConstantValue value) { this.clazz = clazz; this.field = field; - this.value = value; + this.value = value.getValue().getObject(); } public Field getField() @@ -21,8 +21,13 @@ public class StaticFieldInstance return field; } - public ConstantValue getValue() + public Object getValue() { return value; } + + public void setField(Object obj) + { + value = obj; + } } diff --git a/src/main/java/info/sigterm/deob/pool/InterfaceMethod.java b/src/main/java/info/sigterm/deob/pool/InterfaceMethod.java index 4001e74d0c..3dc478f134 100644 --- a/src/main/java/info/sigterm/deob/pool/InterfaceMethod.java +++ b/src/main/java/info/sigterm/deob/pool/InterfaceMethod.java @@ -19,4 +19,14 @@ public class InterfaceMethod extends PoolEntry classIndex = is.readUnsignedShort(); nameAndTypeIndex = is.readUnsignedShort(); } + + public Class getClassEntry() + { + return (Class) this.getPool().getEntry(classIndex); + } + + public NameAndType getNameAndType() + { + return (NameAndType) this.getPool().getEntry(nameAndTypeIndex); + } }