From b7d4d4981f4712a99e8c9b5cd429619ef6a8db80 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 12 Jul 2015 21:43:40 -0400 Subject: [PATCH] Debugging stuff. --- src/main/java/info/sigterm/deob/Deob.java | 16 ++++----- src/main/java/info/sigterm/deob/Field.java | 5 +++ .../deob/attributes/code/Exception.java | 11 ------- .../deob/attributes/code/Exceptions.java | 1 - .../deob/attributes/code/Instruction.java | 4 +-- .../deob/attributes/code/Instructions.java | 1 + .../code/instructions/GetField.java | 17 +++++++--- .../code/instructions/GetStatic.java | 17 +++++++--- .../code/instructions/MultiANewArray.java | 6 ++-- .../code/instructions/PutField.java | 17 +++++++--- .../code/instructions/PutStatic.java | 17 +++++++--- .../{attributes/code => block}/Block.java | 5 ++- .../sigterm/deob/deobfuscators/Jumps.java | 2 +- .../deob/deobfuscators/RenameUnique.java | 5 +++ .../deob/deobfuscators/UnusedBlocks.java | 33 ++++++++++++------- .../java/info/sigterm/deob/pool/Class.java | 10 ++++++ 16 files changed, 113 insertions(+), 54 deletions(-) rename src/main/java/info/sigterm/deob/{attributes/code => block}/Block.java (70%) diff --git a/src/main/java/info/sigterm/deob/Deob.java b/src/main/java/info/sigterm/deob/Deob.java index 5ad4347f3c..71d02eaea9 100644 --- a/src/main/java/info/sigterm/deob/Deob.java +++ b/src/main/java/info/sigterm/deob/Deob.java @@ -14,12 +14,12 @@ import info.sigterm.deob.execution.Frame; import info.sigterm.deob.pool.NameAndType; import info.sigterm.deob.signature.Signature; import info.sigterm.deob.attributes.Code; -import info.sigterm.deob.attributes.code.Block; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.instructions.Goto; import info.sigterm.deob.attributes.code.instructions.GotoW; import info.sigterm.deob.attributes.code.instructions.Return; +import info.sigterm.deob.block.Block; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -47,29 +47,29 @@ public class Deob new RuntimeExceptions().run(group); // the blocks of runtime exceptions may contain interesting things like other obfuscations we identify later, but now that // it can't be reached by the execution phase, those things become confused. so remove blocks here. - //new UnusedBlocks().run(group); + new UnusedBlocks().run(group); // remove unused methods - //new UnusedMethods().run(group); + new UnusedMethods().run(group); // remove illegal state exceptions, frees up some parameters - //new IllegalStateExceptions().run(group); + new IllegalStateExceptions().run(group); // remove unhit blocks - //new UnusedBlocks().run(group); + new UnusedBlocks().run(group); // remove unused parameters - //new UnusedParameters().run(group); + new UnusedParameters().run(group); // remove jump obfuscation new Jumps().run(group); // remove unused fields - //new UnusedFields().run(group); + new UnusedFields().run(group); //new ModularArithmeticDeobfuscation().run(group); - //new RenameUnique().run(group); + new RenameUnique().run(group); saveJar(group, args[1]); diff --git a/src/main/java/info/sigterm/deob/Field.java b/src/main/java/info/sigterm/deob/Field.java index 57f5fd138e..528e43f900 100644 --- a/src/main/java/info/sigterm/deob/Field.java +++ b/src/main/java/info/sigterm/deob/Field.java @@ -77,6 +77,11 @@ public class Field { return type; } + + public void setType(Type type) + { + this.type = type; + } public Attributes getAttributes() { diff --git a/src/main/java/info/sigterm/deob/attributes/code/Exception.java b/src/main/java/info/sigterm/deob/attributes/code/Exception.java index e729312356..5f33b3c91a 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Exception.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Exception.java @@ -35,13 +35,6 @@ public class Exception assert start != null; assert end != null; assert handler != null; - - handler.exce.add(this); - } - - protected void remove() - { - handler.exce.remove(this); } public void write(DataOutputStream out) throws IOException @@ -83,11 +76,7 @@ public class Exception end = newi; if (handler == oldi) - { - handler.exce.remove(this); handler = newi; - handler.exce.add(this); - } } public Class getCatchType() diff --git a/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java b/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java index 0716101903..b9a8023c20 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java @@ -28,7 +28,6 @@ public class Exceptions public void remove(Exception e) { - e.remove(); exceptions.remove(e); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/Instruction.java b/src/main/java/info/sigterm/deob/attributes/code/Instruction.java index 7bfe972d3d..30af1372c7 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instruction.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instruction.java @@ -4,6 +4,7 @@ import info.sigterm.deob.ClassFile; import info.sigterm.deob.ConstantPool; import info.sigterm.deob.Field; import info.sigterm.deob.Method; +import info.sigterm.deob.block.Block; import info.sigterm.deob.execution.Frame; import java.io.DataOutputStream; @@ -22,7 +23,6 @@ public abstract class Instruction public List jump = new ArrayList<>(), // instructions which this instruction jumps to from = new ArrayList<>(); // instructions which jump to this instruction - public List exce = new ArrayList<>(); // exception handlers which start here public Instruction(Instructions instructions, InstructionType type, int pc) { @@ -48,7 +48,6 @@ public abstract class Instruction } assert from.isEmpty(); // because this is empty no jumping instructions point here - assert exce.isEmpty(); } public void replace(Instruction other) @@ -97,7 +96,6 @@ public abstract class Instruction { e.replace(this, other); } - assert exce.isEmpty(); // replace ins int index = ins.indexOf(this); diff --git a/src/main/java/info/sigterm/deob/attributes/code/Instructions.java b/src/main/java/info/sigterm/deob/attributes/code/Instructions.java index 27433159b3..7a91a79bec 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instructions.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instructions.java @@ -5,6 +5,7 @@ import info.sigterm.deob.Field; import info.sigterm.deob.Method; import info.sigterm.deob.attributes.Code; import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction; +import info.sigterm.deob.block.Block; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetField.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetField.java index fe7644b6e2..79a5cffbcf 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetField.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetField.java @@ -66,16 +66,25 @@ public class GetField extends Instruction implements GetFieldInstruction { if (field.getClassEntry().getName().equals(cf.getName())) field = new Field(new Class(name), field.getNameAndType()); + + if (field.getNameAndType().getDescriptorType().getType().equals("L" + cf.getName() + ";")) + field = new Field(field.getClassEntry(), new NameAndType(field.getNameAndType().getName(), new info.sigterm.deob.signature.Type("L" + name + ";", field.getNameAndType().getDescriptorType().getArrayDims()))); } @Override public void renameField(info.sigterm.deob.Field f, String name) { - if (field.getNameAndType().getName().equals(f.getName()) && field.getClassEntry().getName().equals(f.getFields().getClassFile().getName())) + Class clazz = field.getClassEntry(); + NameAndType nat = field.getNameAndType(); + + ClassFile cf = this.getInstructions().getCode().getAttributes().getClassFile().getGroup().findClass(clazz.getName()); + if (cf == null) + return; + + info.sigterm.deob.Field f2 = cf.findFieldDeep(nat); + + if (f2 == f) { - Class clazz = field.getClassEntry(); - NameAndType nat = field.getNameAndType(); - NameAndType newNat = new NameAndType(name, nat.getDescriptorType()); field = new Field(clazz, newNat); } 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 2ea2f1257c..906765590c 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 @@ -79,16 +79,25 @@ public class GetStatic extends Instruction implements GetFieldInstruction { if (field.getClassEntry().getName().equals(cf.getName())) field = new Field(new Class(name), field.getNameAndType()); + + if (field.getNameAndType().getDescriptorType().getType().equals("L" + cf.getName() + ";")) + field = new Field(field.getClassEntry(), new NameAndType(field.getNameAndType().getName(), new info.sigterm.deob.signature.Type("L" + name + ";", field.getNameAndType().getDescriptorType().getArrayDims()))); } @Override public void renameField(info.sigterm.deob.Field f, String name) { - if (field.getNameAndType().getName().equals(f.getName()) && field.getClassEntry().getName().equals(f.getFields().getClassFile().getName())) + Class clazz = field.getClassEntry(); + NameAndType nat = field.getNameAndType(); + + ClassFile cf = this.getInstructions().getCode().getAttributes().getClassFile().getGroup().findClass(clazz.getName()); + if (cf == null) + return; + + info.sigterm.deob.Field f2 = cf.findFieldDeep(nat); + + if (f2 == f) { - Class clazz = field.getClassEntry(); - NameAndType nat = field.getNameAndType(); - NameAndType newNat = new NameAndType(name, nat.getDescriptorType()); field = new Field(clazz, newNat); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/MultiANewArray.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/MultiANewArray.java index d18303405b..6d25c73e6d 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/MultiANewArray.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/MultiANewArray.java @@ -62,7 +62,9 @@ public class MultiANewArray extends Instruction @Override public void renameClass(ClassFile cf, String name) { - if (clazz.getName().equals(cf.getName())) - clazz = new Class(name); + // class is an array type, ugh. + info.sigterm.deob.signature.Type t = new info.sigterm.deob.signature.Type(cf.getName()); + if (t.getType().equals(cf.getName())) + clazz = new Class(name, t.getArrayDims()); } } 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 fcdfbfc16d..9099ebc38c 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 @@ -61,16 +61,25 @@ public class PutField extends Instruction implements SetFieldInstruction { if (field.getClassEntry().getName().equals(cf.getName())) field = new Field(new Class(name), field.getNameAndType()); + + if (field.getNameAndType().getDescriptorType().getType().equals("L" + cf.getName() + ";")) + field = new Field(field.getClassEntry(), new NameAndType(field.getNameAndType().getName(), new info.sigterm.deob.signature.Type("L" + name + ";", field.getNameAndType().getDescriptorType().getArrayDims()))); } @Override public void renameField(info.sigterm.deob.Field f, String name) { - if (field.getNameAndType().getName().equals(f.getName()) && field.getClassEntry().getName().equals(f.getFields().getClassFile().getName())) + Class clazz = field.getClassEntry(); + NameAndType nat = field.getNameAndType(); + + ClassFile cf = this.getInstructions().getCode().getAttributes().getClassFile().getGroup().findClass(clazz.getName()); + if (cf == null) + return; + + info.sigterm.deob.Field f2 = cf.findFieldDeep(nat); + + if (f2 == f) { - Class clazz = field.getClassEntry(); - NameAndType nat = field.getNameAndType(); - NameAndType newNat = new NameAndType(name, nat.getDescriptorType()); field = new Field(clazz, newNat); } 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 fb37db12ab..42b073ec75 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 @@ -60,16 +60,25 @@ public class PutStatic extends Instruction implements SetFieldInstruction { if (field.getClassEntry().getName().equals(cf.getName())) field = new Field(new Class(name), field.getNameAndType()); + + if (field.getNameAndType().getDescriptorType().getType().equals("L" + cf.getName() + ";")) + field = new Field(field.getClassEntry(), new NameAndType(field.getNameAndType().getName(), new info.sigterm.deob.signature.Type("L" + name + ";", field.getNameAndType().getDescriptorType().getArrayDims()))); } @Override public void renameField(info.sigterm.deob.Field f, String name) { - if (field.getNameAndType().getName().equals(f.getName()) && field.getClassEntry().getName().equals(f.getFields().getClassFile().getName())) + Class clazz = field.getClassEntry(); + NameAndType nat = field.getNameAndType(); + + ClassFile cf = this.getInstructions().getCode().getAttributes().getClassFile().getGroup().findClass(clazz.getName()); + if (cf == null) + return; + + info.sigterm.deob.Field f2 = cf.findFieldDeep(nat); + + if (f2 == f) { - Class clazz = field.getClassEntry(); - NameAndType nat = field.getNameAndType(); - NameAndType newNat = new NameAndType(name, nat.getDescriptorType()); field = new Field(clazz, newNat); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/Block.java b/src/main/java/info/sigterm/deob/block/Block.java similarity index 70% rename from src/main/java/info/sigterm/deob/attributes/code/Block.java rename to src/main/java/info/sigterm/deob/block/Block.java index f6496eb7ff..3a2e069bcf 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Block.java +++ b/src/main/java/info/sigterm/deob/block/Block.java @@ -1,4 +1,7 @@ -package info.sigterm.deob.attributes.code; +package info.sigterm.deob.block; + +import info.sigterm.deob.attributes.code.Exception; +import info.sigterm.deob.attributes.code.Instruction; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/info/sigterm/deob/deobfuscators/Jumps.java b/src/main/java/info/sigterm/deob/deobfuscators/Jumps.java index d2b25021c0..9da44e0764 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/Jumps.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/Jumps.java @@ -4,11 +4,11 @@ import info.sigterm.deob.ClassFile; import info.sigterm.deob.ClassGroup; import info.sigterm.deob.Deobfuscator; import info.sigterm.deob.Method; -import info.sigterm.deob.attributes.code.Block; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.instructions.Goto; import info.sigterm.deob.attributes.code.instructions.GotoW; +import info.sigterm.deob.block.Block; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/info/sigterm/deob/deobfuscators/RenameUnique.java b/src/main/java/info/sigterm/deob/deobfuscators/RenameUnique.java index ce7cce12e3..e072808d6e 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/RenameUnique.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/RenameUnique.java @@ -72,6 +72,11 @@ public class RenameUnique implements Deobfuscator if (method.getExceptions() != null) method.getExceptions().renameClass(cf, name); } + + // rename on fields + for (Field field : c.getFields().getFields()) + if (field.getType().getType().equals("L" + cf.getName() + ";")) + field.setType(new Type("L" + name + ";", field.getType().getArrayDims())); } cf.setName(name); diff --git a/src/main/java/info/sigterm/deob/deobfuscators/UnusedBlocks.java b/src/main/java/info/sigterm/deob/deobfuscators/UnusedBlocks.java index 9d00700783..6fec8dfce1 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/UnusedBlocks.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/UnusedBlocks.java @@ -4,17 +4,16 @@ import info.sigterm.deob.ClassFile; import info.sigterm.deob.ClassGroup; import info.sigterm.deob.Deobfuscator; import info.sigterm.deob.Method; -import info.sigterm.deob.attributes.code.Block; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.block.Block; import java.util.ArrayList; public class UnusedBlocks implements Deobfuscator { - @Override - public void run(ClassGroup group) + public int pass(ClassGroup group) { - int i = 0; + int removed = 0; for (ClassFile cf : group.getClasses()) { for (Method m : new ArrayList<>(cf.getMethods().getMethods())) @@ -25,21 +24,33 @@ public class UnusedBlocks implements Deobfuscator Instructions ins = m.getCode().getInstructions(); ins.buildBlocks(); - int count = 0; - for (Block b : new ArrayList<>(ins.getBlocks())) + for (int i = 0; i < ins.getBlocks().size(); ++i) { + Block block = ins.getBlocks().get(i); + // first block is the entrypoint, so its always used - if (count++ == 0) + if (i == 0) continue; - if (b.begin.from.isEmpty() && b.begin.exce.isEmpty()) + Block prev = ins.getBlocks().get(i - 1); + + if (prev.end.isTerminal() && block.begin.from.isEmpty() && block.handlers.isEmpty()) { - ins.remove(b); - ++i; + ins.remove(block); + ++removed; + break; } } } } - System.out.println("Removed " + i + " unused blocks"); + + System.out.println("Removed " + removed + " unused blocks"); + return removed; + } + + @Override + public void run(ClassGroup group) + { + while (pass(group) > 0); } } diff --git a/src/main/java/info/sigterm/deob/pool/Class.java b/src/main/java/info/sigterm/deob/pool/Class.java index 4cb3bdddef..76a50565dc 100644 --- a/src/main/java/info/sigterm/deob/pool/Class.java +++ b/src/main/java/info/sigterm/deob/pool/Class.java @@ -27,6 +27,16 @@ public class Class extends PoolEntry this.name = name; } + public Class(java.lang.String name, int dimms) + { + super(ConstantType.CLASS); + + while (dimms-- > 0) + name = "[" + name; + + this.name = name; + } + @Override public void resolve(ConstantPool pool) {