diff --git a/src/main/java/info/sigterm/deob/Deob.java b/src/main/java/info/sigterm/deob/Deob.java index 440a8be1d9..c051fd1a54 100644 --- a/src/main/java/info/sigterm/deob/Deob.java +++ b/src/main/java/info/sigterm/deob/Deob.java @@ -2,6 +2,7 @@ package info.sigterm.deob; import info.sigterm.deob.execution.Execution; import info.sigterm.deob.pool.NameAndType; +import info.sigterm.deob.attributes.Code; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.instruction.types.LVTInstruction; @@ -43,7 +44,9 @@ public class Deob group.buildCallGraph(); checkCallGraph(group); - checkParameters(group); + removeExceptionObfuscation(group); + checkBlockGraph(group); + //checkParameters(group); //execute(group); @@ -95,6 +98,68 @@ public class Deob System.out.println("Removed " + i + " methods"); } + private static void removeExceptionObfuscation(ClassGroup group) + { + int i = 0; + for (ClassFile cf : group.getClasses()) + { + for (Method m : new ArrayList<>(cf.getMethods().getMethods())) + { + Code c = m.getCode(); + if (c == null) + continue; + + for (info.sigterm.deob.attributes.code.Exception e : new ArrayList<>(c.getExceptions().getExceptions())) + { + if (e.getCatchType() != null && e.getCatchType().getName().equals("java/lang/RuntimeException")) + { + c.getExceptions().remove(e); + ++i; + } + } + } + } + System.out.println("Removed " + i + " exception handlers"); + } + + private static void checkBlockGraph(ClassGroup group) + { + int i = 0; + for (ClassFile cf : group.getClasses()) + { + for (Method m : new ArrayList<>(cf.getMethods().getMethods())) + { + if (m.getCode() == null) + continue; + + boolean check = false, remove = false; + for (Instruction ins : new ArrayList<>(m.getCode().getInstructions().getInstructions())) + { + if (remove) + { + m.getCode().getInstructions().remove(ins); + } + if (check) + { + if (ins.from.isEmpty() && ins.exce.isEmpty()) + { + remove = true; + m.getCode().getInstructions().remove(ins); + ++i; + } + check = false; + } + if (ins.isTerminal()) + { + check = true; + remove = false; + } + } + } + } + System.out.println("Removed " + i + " unused blocks"); + } + private static boolean parameterUsed(int num, List lv) { if (lv.isEmpty()) @@ -126,6 +191,7 @@ public class Deob if (!parameterUsed(i, lv)) { + //m.removeParameter(i); System.out.println("Not used param " + i + " of " + cf.getName() + " " + m.getName() + " static: " + m.isStatic()); ++count; } diff --git a/src/main/java/info/sigterm/deob/Method.java b/src/main/java/info/sigterm/deob/Method.java index ba880b32a7..f04802c622 100644 --- a/src/main/java/info/sigterm/deob/Method.java +++ b/src/main/java/info/sigterm/deob/Method.java @@ -55,6 +55,17 @@ public class Method { assert callsFrom.isEmpty(); } + + protected void removeParameter(int i) + { + // If this is a non static method parameter 0 is this + if (!this.isStatic()) + --i; + + arguments.remove(i); + + // XXX now remove from code. + } public Methods getMethods() { 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 70ad0644e7..fc32d054d2 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Exception.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Exception.java @@ -14,7 +14,7 @@ public class Exception private int startPc; private int endPc; private int handlerPc; - private Class cacheType; + private Class catchType; public Exception(Exceptions exceptions) throws IOException { @@ -26,7 +26,16 @@ public class Exception startPc = is.readUnsignedShort(); endPc = is.readUnsignedShort(); handlerPc = is.readUnsignedShort(); - cacheType = pool.getClass(is.readUnsignedShort()); + catchType = pool.getClass(is.readUnsignedShort()); + + Instruction ins = exceptions.getCode().getInstructions().findInstruction(handlerPc); + ins.exce.add(this); + } + + protected void remove() + { + Instruction ins = exceptions.getCode().getInstructions().findInstruction(handlerPc); + ins.exce.remove(this); } public void write(DataOutputStream out) throws IOException @@ -36,7 +45,7 @@ public class Exception out.writeShort(startPc); out.writeShort(endPc); out.writeShort(handlerPc); - out.writeShort(cacheType == null ? 0 : pool.make(cacheType)); + out.writeShort(catchType == null ? 0 : pool.make(catchType)); } public Exceptions getExceptions() @@ -58,4 +67,9 @@ public class Exception { return handlerPc; } + + public Class getCatchType() + { + return catchType; + } } 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 412de3d30b..5057c90dfa 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java @@ -26,6 +26,12 @@ public class Exceptions exceptions.add(new Exception(this)); } + public void remove(Exception e) + { + e.remove(); + exceptions.remove(e); + } + public void write(DataOutputStream out) throws IOException { out.writeShort(exceptions.size()); @@ -38,9 +44,14 @@ public class Exceptions return code; } - public Collection getHandlersForPc(int pc) + public List getExceptions() { - ArrayList matches = new ArrayList(); + return exceptions; + } + + public List getHandlersForPc(int pc) + { + List matches = new ArrayList<>(); for (Exception e : exceptions) { 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 019482fbbd..c6206e3ae7 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instruction.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instruction.java @@ -6,6 +6,7 @@ import info.sigterm.deob.execution.Frame; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.List; public abstract class Instruction { @@ -15,8 +16,9 @@ public abstract class Instruction private int pc; // offset into method this instructions resides at protected int length = 1; // length of this instruction - private ArrayList jump = new ArrayList(); // instructions which this instruction jumps to - private ArrayList from = new ArrayList(); // instructions which jump to this 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) { @@ -25,6 +27,16 @@ public abstract class Instruction this.pc = pc; } + protected void remove() + { + for (Instruction i : jump) + i.from.remove(this); + jump.clear(); + + assert from.isEmpty(); + assert exce.isEmpty(); + } + public void write(DataOutputStream out, int pc) throws IOException { out.writeByte(type.getCode()); @@ -78,4 +90,10 @@ public abstract class Instruction } public abstract void execute(Frame e); + + /* does this terminate a block? */ + public boolean isTerminal() + { + return false; + } } 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 aa6ed37024..fa26565e4e 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instructions.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instructions.java @@ -55,6 +55,12 @@ public class Instructions return instructions; } + public void remove(Instruction ins) + { + ins.remove(); + instructions.remove(ins); + } + public void write(DataOutputStream out) throws IOException { ByteArrayOutputStream b = new ByteArrayOutputStream(); diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/AThrow.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/AThrow.java index 886b7ea426..16a4595f36 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/AThrow.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/AThrow.java @@ -21,4 +21,10 @@ public class AThrow extends Instruction ObjectInstance exception = (ObjectInstance) e.getStack().pop(); e.getPath().throwException(this, exception); } + + @Override + public boolean isTerminal() + { + return true; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/Goto.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/Goto.java index e098ed1d70..4b8e516757 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/Goto.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/Goto.java @@ -40,4 +40,10 @@ public class Goto extends Instruction { e.jump(offset); } + + @Override + public boolean isTerminal() + { + return true; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/GotoW.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/GotoW.java index 220c382452..32dd337b6a 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/GotoW.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/GotoW.java @@ -40,4 +40,10 @@ public class GotoW extends Instruction { e.jump(offset); } + + @Override + public boolean isTerminal() + { + return true; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LookupSwitch.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LookupSwitch.java index 20b2e72b27..a9c7daa1dc 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LookupSwitch.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LookupSwitch.java @@ -83,4 +83,10 @@ public class LookupSwitch extends Instruction Path p = e.getPath().dup(); p.getCurrentFrame().jump(def); } + + @Override + public boolean isTerminal() + { + return true; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/Return.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/Return.java index 350b613ab9..ba1a4e4e64 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/Return.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/Return.java @@ -20,4 +20,10 @@ public class Return extends Instruction Object ret = e.getStack().pop(); e.getPath().returnFrame(this, ret); } + + @Override + public boolean isTerminal() + { + return true; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/TableSwitch.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/TableSwitch.java index e652051545..29d1c3f9b1 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/TableSwitch.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/TableSwitch.java @@ -79,4 +79,10 @@ public class TableSwitch extends Instruction Path p = e.getPath().dup(); p.getCurrentFrame().jump(def); } + + @Override + public boolean isTerminal() + { + return true; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/VReturn.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/VReturn.java index 6ad23d4b53..a407496ff2 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/VReturn.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/VReturn.java @@ -20,4 +20,10 @@ public class VReturn extends Instruction // XXX exceptions? e.getPath().returnFrame(); } + + @Override + public boolean isTerminal() + { + return true; + } } diff --git a/src/main/java/info/sigterm/deob/signature/Signature.java b/src/main/java/info/sigterm/deob/signature/Signature.java index bda64af7f0..b2b607a6a4 100644 --- a/src/main/java/info/sigterm/deob/signature/Signature.java +++ b/src/main/java/info/sigterm/deob/signature/Signature.java @@ -59,6 +59,11 @@ public class Signature return arguments.size(); } + public void remove(int i) + { + arguments.remove(i); + } + public Type getReturnValue() { return rv;