diff --git a/src/main/java/net/runelite/deob/Deob.java b/src/main/java/net/runelite/deob/Deob.java index 07d494528d..fa1a32bb15 100644 --- a/src/main/java/net/runelite/deob/Deob.java +++ b/src/main/java/net/runelite/deob/Deob.java @@ -39,72 +39,76 @@ public class Deob ClassGroup group = loadJar(args[0]); -// run(group, new RenameUnique()); -// -// // remove except RuntimeException -// run(group, new RuntimeExceptions()); -// -// // remove unused methods -// run(group, new UnusedMethods()); -// -// run(group, new UnreachedCode()); -// -// // remove illegal state exceptions, frees up some parameters -// run(group, new IllegalStateExceptions()); -// -// // remove constant logically dead parameters -// run(group, new ConstantParameter()); -// -// // remove unhit blocks -// run(group, new UnreachedCode()); -// run(group, new UnusedMethods()); -// -// // remove unused parameters -// run(group, new UnusedParameters()); -// -// // remove jump obfuscation -// //new Jumps().run(group); -// -// // remove unused fields -// run(group, new UnusedFields()); -// -// // remove unused methods, again? -// run(group, new UnusedMethods()); -// -// run(group, new MethodInliner()); -// -// // broken because rename was removed -// //run(group, new MethodMover()); -// -// run(group, new FieldInliner()); -// -// // XXX this is broken because when moving clinit around, some fields can depend on other fields -// // (like multianewarray) -// //new FieldMover().run(group); -// -// run(group, new UnusedClass()); - - ModArith mod = new ModArith(); - mod.run(group); + run(group, new RenameUnique()); + + // remove except RuntimeException + run(group, new RuntimeExceptions()); - int last = -1, cur; - while ((cur = mod.runOnce()) > 0) - { - new MultiplicationDeobfuscator().run(group); + // remove unused methods + run(group, new UnusedMethods()); + + run(group, new UnreachedCode()); + + // remove illegal state exceptions, frees up some parameters + run(group, new IllegalStateExceptions()); + + // remove constant logically dead parameters + run(group, new ConstantParameter()); + + // remove unhit blocks + run(group, new UnreachedCode()); + run(group, new UnusedMethods()); - new MultiplyOneDeobfuscator().run(group); + // remove unused parameters + run(group, new UnusedParameters()); + + // remove jump obfuscation + //new Jumps().run(group); + + // remove unused fields + run(group, new UnusedFields()); + + // remove unused methods, again? + run(group, new UnusedMethods()); - new MultiplyZeroDeobfuscator().run(group); - - if (last == cur) - { - System.out.println("break"); - break; - } - - last = cur; - //break; - } + run(group, new MethodInliner()); + + // broken because rename was removed + //run(group, new MethodMover()); + + run(group, new FieldInliner()); + + // XXX this is broken because when moving clinit around, some fields can depend on other fields + // (like multianewarray) + //new FieldMover().run(group); + + run(group, new UnusedClass()); + +// ModArith mod = new ModArith(); +// mod.run(group); +// +// int last = -1, cur; +// while ((cur = mod.runOnce()) > 0) +// { +// new MultiplicationDeobfuscator().run(group); +// +// new MultiplyOneDeobfuscator().run(group); +// +// new MultiplyZeroDeobfuscator().run(group); +// +// if (last == cur) +// { +// System.out.println("break"); +// break; +// } +// +// last = cur; +// //break; +// } + + // eval constant fields (only set once to a constant in ctor) maybe just inline them + + // make fields private saveJar(group, args[1]); diff --git a/src/main/java/net/runelite/deob/attributes/code/Instruction.java b/src/main/java/net/runelite/deob/attributes/code/Instruction.java index e55c40d6fb..78fbbf7166 100644 --- a/src/main/java/net/runelite/deob/attributes/code/Instruction.java +++ b/src/main/java/net/runelite/deob/attributes/code/Instruction.java @@ -112,6 +112,7 @@ public abstract class Instruction public boolean removeStack() { block = null; + assert instructions != null; // update instructions which jump here to jump to the next instruction List ins = instructions.getInstructions(); diff --git a/src/main/java/net/runelite/deob/deobfuscators/ConstantParameter.java b/src/main/java/net/runelite/deob/deobfuscators/ConstantParameter.java index 8a84e0e71d..010a15c08f 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/ConstantParameter.java +++ b/src/main/java/net/runelite/deob/deobfuscators/ConstantParameter.java @@ -449,6 +449,9 @@ public class ConstantParameter implements Deobfuscator Instruction ins = ctx.getInstruction(); boolean branch = op.branch; // branch that is always taken + if (ins.getInstructions() == null) + continue; // ins already removed? + Instructions instructions = ins.getInstructions(); instructions.buildJumpGraph(); diff --git a/src/main/java/net/runelite/deob/deobfuscators/IllegalStateExceptions.java b/src/main/java/net/runelite/deob/deobfuscators/IllegalStateExceptions.java index b021725e40..67d2b480a3 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/IllegalStateExceptions.java +++ b/src/main/java/net/runelite/deob/deobfuscators/IllegalStateExceptions.java @@ -64,6 +64,7 @@ public class IllegalStateExceptions implements Deobfuscator // remove stack of if. boolean found = false; + outer: for (Frame f : execution.processedFrames) if (f.getMethod() == m) { @@ -75,6 +76,7 @@ public class IllegalStateExceptions implements Deobfuscator if (ins instanceof If) ic.removeStack(1); ic.removeStack(0); + break outer; } } if (!found) @@ -128,6 +130,7 @@ public class IllegalStateExceptions implements Deobfuscator public void run(ClassGroup group) { group.buildClassGraph(); + Execution execution = new Execution(group); execution.populateInitialMethods(); execution.run(); @@ -136,7 +139,7 @@ public class IllegalStateExceptions implements Deobfuscator int passes = 0; int i; do - { + { i = checkOnce(execution, group); System.out.println("ise removal pass " + passes + " removed " + i); diff --git a/src/main/java/net/runelite/deob/deobfuscators/UnusedParameters.java b/src/main/java/net/runelite/deob/deobfuscators/UnusedParameters.java index 28fdde0267..817972dfcb 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/UnusedParameters.java +++ b/src/main/java/net/runelite/deob/deobfuscators/UnusedParameters.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; +import net.runelite.deob.execution.StackContext; import org.apache.commons.collections4.CollectionUtils; @@ -117,6 +118,11 @@ public class UnusedParameters implements Deobfuscator if (!ins.getInvokes().isEmpty() && methods.containsAll(ins.getInvokes())) { int pops = signature.size() - paramIndex - 1; // index from top of stack of parameter. 0 is the last parameter + + StackContext sctx = ins.getPops().get(pops); + if (sctx.getPushed().getInstruction().getInstructions() == null) + continue; + ins.removeStack(pops); // remove parameter from stack if (done.contains(ins.getInstruction())) diff --git a/src/main/java/net/runelite/deob/execution/Execution.java b/src/main/java/net/runelite/deob/execution/Execution.java index c920535e83..a315253c1e 100644 --- a/src/main/java/net/runelite/deob/execution/Execution.java +++ b/src/main/java/net/runelite/deob/execution/Execution.java @@ -42,6 +42,8 @@ public class Execution public void populateInitialMethods() { + group.buildClassGraph(); // required when looking up methods + for (ClassFile cf : group.getClasses()) { for (Method m : cf.getMethods().getMethods())