diff --git a/src/main/java/info/sigterm/deob/Deob.java b/src/main/java/info/sigterm/deob/Deob.java index e710326ac9..c5fd262efb 100644 --- a/src/main/java/info/sigterm/deob/Deob.java +++ b/src/main/java/info/sigterm/deob/Deob.java @@ -41,27 +41,25 @@ public class Deob ClassGroup group = loadJar(args[0]); - /* // remove except RuntimeException new RuntimeExceptions().run(group); + // remove unused methods + new UnusedMethods().run(group); + // remove illegal state exceptions, frees up some parameters new IllegalStateExceptions().run(group); // remove code blocks that used to be the runtime exception handlers - new UnusedBlocks().run(group);*/ + new UnusedBlocks().run(group); - // remove unused methods - new UnusedMethods().run(group); - - /* // remove unused parameters new UnusedParameters().run(group); // remove jump obfuscation new Jumps().run(group); - new ModularArithmeticDeobfuscation().run(group);*/ + //new ModularArithmeticDeobfuscation().run(group); saveJar(group, args[1]); diff --git a/src/main/java/info/sigterm/deob/Method.java b/src/main/java/info/sigterm/deob/Method.java index de6b6d054b..7f500f8274 100644 --- a/src/main/java/info/sigterm/deob/Method.java +++ b/src/main/java/info/sigterm/deob/Method.java @@ -63,39 +63,22 @@ public class Method public void removeParameter(Execution execution, int paramIndex, int lvtIndex) { - /* Set done = new HashSet<>(); - for (Node n : callsFrom) - { - // find everywhere that calls this - // remove parameter from stack - Method caller = n.from; - - // find frames on the caller - boolean found = false; - for (Frame f : execution.processedFrames) - if (f.getMethod() == caller) - for (InstructionContext ins : f.getInstructions()) - if (ins.getInstruction() == n.ins) // this instruction invokes the function we're removing a parameter from - { - found = true; - if (done.contains(ins.getInstruction())) - continue; - - int pops = arguments.size() - paramIndex - 1; // index from top of stack of parameter - ins.removeStack(pops); // remove parameter from stack - - InvokeInstruction iins = (InvokeInstruction) ins.getInstruction(); - iins.removeParameter(paramIndex); // remove parameter from instruction - - done.add(ins.getInstruction()); - } - if (found == false) - { - System.err.println("Method " + caller.getName() + " in " + caller.getMethods().getClassFile().getName() + " calls " + this.getName() + " in " + this.getMethods().getClassFile().getName() + ", but was unable to find any execution frame doing this"); - assert false; - } - } + for (Frame f : execution.processedFrames) + for (InstructionContext ins : f.getInstructions()) + if (ins.getInvokes().contains(this)) + { + int pops = arguments.size() - paramIndex - 1; // index from top of stack of parameter + ins.removeStack(pops); // remove parameter from stack + + if (done.contains(ins.getInstruction())) + continue; + + InvokeInstruction iins = (InvokeInstruction) ins.getInstruction(); + iins.removeParameter(paramIndex); // remove parameter from instruction + + done.add(ins.getInstruction()); + } // this double checks that all calls to this have been located for (ClassFile cf : methods.getClassFile().getGroup().getClasses()) @@ -159,7 +142,6 @@ public class Method } arguments.remove(paramIndex); - */ } public Methods getMethods() 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 989480a1ee..9feb9858a8 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 @@ -98,13 +98,14 @@ public class InvokeInterface extends Instruction implements InvokeInstruction ins.push(ctx); } - frame.addInstructionContext(ins); - for (info.sigterm.deob.Method method : getMethods()) { + ins.invoke(method); // add possible method call to execution frame.getExecution().addMethod(method); } + + frame.addInstructionContext(ins); } private void handleExceptions(Frame frame) diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java index 383acc5053..027ebdc929 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java @@ -84,13 +84,14 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction ins.push(ctx); } - frame.addInstructionContext(ins); - for (info.sigterm.deob.Method method : getMethods()) { + ins.invoke(method); // add possible method call to execution frame.getExecution().addMethod(method); } + + frame.addInstructionContext(ins); } private void handleExceptions(Frame frame) diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java index e68f907f58..07b5866e94 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java @@ -81,13 +81,14 @@ public class InvokeStatic extends Instruction implements InvokeInstruction ins.push(ctx); } - frame.addInstructionContext(ins); - for (info.sigterm.deob.Method method : getMethods()) { + ins.invoke(method); // add possible method call to execution frame.getExecution().addMethod(method); } + + frame.addInstructionContext(ins); } private void handleExceptions(Frame frame) diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java index 6dd50ae7b4..a4685f135b 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java @@ -69,13 +69,14 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction ins.push(ctx); } - frame.addInstructionContext(ins); - for (info.sigterm.deob.Method method : getMethods()) { + ins.invoke(method); // add possible method call to execution frame.getExecution().addMethod(method); } + + frame.addInstructionContext(ins); } // find the possible methods this instruction might be invoking. we can't know for sure diff --git a/src/main/java/info/sigterm/deob/deobfuscators/IllegalStateExceptions.java b/src/main/java/info/sigterm/deob/deobfuscators/IllegalStateExceptions.java index bf3b74cb33..27a239ab66 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/IllegalStateExceptions.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/IllegalStateExceptions.java @@ -29,12 +29,14 @@ public class IllegalStateExceptions for (ClassFile cf : group.getClasses()) { - for (Method m : new ArrayList<>(cf.getMethods().getMethods())) + for (Method m : cf.getMethods().getMethods()) { Code c = m.getCode(); if (c == null) continue; + assert execution.methods.contains(m); + Instructions instructions = c.getInstructions(); instructions.clearBlockGraph(); @@ -63,8 +65,11 @@ public class IllegalStateExceptions // remove stack of if. boolean found = false; + boolean foundMethod = false; for (Frame f : execution.processedFrames) if (f.getMethod() == m) + { + foundMethod = true; for (InstructionContext ic : f.getInstructions()) if (ic.getInstruction() == ins) // this is the if { @@ -74,6 +79,8 @@ public class IllegalStateExceptions ic.removeStack(1); ic.removeStack(0); } + } + assert foundMethod; assert found; // instruction is no longer at 'i' because we've just removed stuff... @@ -116,6 +123,7 @@ public class IllegalStateExceptions public void run(ClassGroup group) { Execution execution = new Execution(group); + execution.populateInitialMethods(); execution.run(); int count = 0; diff --git a/src/main/java/info/sigterm/deob/deobfuscators/ModularArithmeticDeobfuscation.java b/src/main/java/info/sigterm/deob/deobfuscators/ModularArithmeticDeobfuscation.java index c7f857e709..0322554492 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/ModularArithmeticDeobfuscation.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/ModularArithmeticDeobfuscation.java @@ -150,6 +150,7 @@ public class ModularArithmeticDeobfuscation public void run(ClassGroup group) { Execution execution = new Execution(group); + execution.populateInitialMethods(); execution.run(); run(execution, group); diff --git a/src/main/java/info/sigterm/deob/deobfuscators/RuntimeExceptions.java b/src/main/java/info/sigterm/deob/deobfuscators/RuntimeExceptions.java index 62dc6fd223..7acb07e949 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/RuntimeExceptions.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/RuntimeExceptions.java @@ -14,7 +14,7 @@ public class RuntimeExceptions int i = 0; for (ClassFile cf : group.getClasses()) { - for (Method m : new ArrayList<>(cf.getMethods().getMethods())) + for (Method m : cf.getMethods().getMethods()) { Code c = m.getCode(); if (c == null) diff --git a/src/main/java/info/sigterm/deob/deobfuscators/UnusedParameters.java b/src/main/java/info/sigterm/deob/deobfuscators/UnusedParameters.java index 33c8ddd05d..a937ae827e 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/UnusedParameters.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/UnusedParameters.java @@ -78,6 +78,7 @@ public class UnusedParameters public void run(ClassGroup group) { Execution execution = new Execution(group); + execution.populateInitialMethods(); execution.run(); int count = 0; diff --git a/src/main/java/info/sigterm/deob/execution/InstructionContext.java b/src/main/java/info/sigterm/deob/execution/InstructionContext.java index 093ba12703..cfcb7779cb 100644 --- a/src/main/java/info/sigterm/deob/execution/InstructionContext.java +++ b/src/main/java/info/sigterm/deob/execution/InstructionContext.java @@ -3,6 +3,7 @@ package info.sigterm.deob.execution; import java.util.ArrayList; import java.util.List; +import info.sigterm.deob.Method; import info.sigterm.deob.attributes.code.Instruction; public class InstructionContext @@ -12,6 +13,7 @@ public class InstructionContext private List pops = new ArrayList<>(); // stack contexts popped by instruction execution private List pushes = new ArrayList<>(); // stack contexts pushed by instruction execution private List reads = new ArrayList<>(); // lvt reads + private List invokes = new ArrayList<>(); // invokes public InstructionContext(Instruction i, Frame f) { @@ -40,6 +42,11 @@ public class InstructionContext reads.add(c); } + public void invoke(Method method) + { + invokes.add(method); + } + public Instruction getInstruction() { return ins; @@ -55,6 +62,11 @@ public class InstructionContext return pushes; } + public List getInvokes() + { + return invokes; + } + public void removeStack(int idx) { // idx 0 is top of the stack, 1 is one under