From 4d4dd9715ea1a66b0603650e1dc3b691b316ee51 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 22 Aug 2015 22:53:03 -0400 Subject: [PATCH] Allow inlining methods with exceptions --- src/main/java/net/runelite/deob/Deob.java | 114 +++++++++--------- .../deob/attributes/code/Exception.java | 13 ++ .../deob/attributes/code/Exceptions.java | 8 ++ .../deob/deobfuscators/MethodInliner.java | 34 ++++-- 4 files changed, 103 insertions(+), 66 deletions(-) diff --git a/src/main/java/net/runelite/deob/Deob.java b/src/main/java/net/runelite/deob/Deob.java index c06da885e0..3995fdcab4 100644 --- a/src/main/java/net/runelite/deob/Deob.java +++ b/src/main/java/net/runelite/deob/Deob.java @@ -47,66 +47,66 @@ public class Deob // bdur = System.currentTimeMillis() - bstart; // System.out.println("rename unique took " + bdur/1000L + " seconds"); - // remove except RuntimeException - bstart = System.currentTimeMillis(); - new RuntimeExceptions().run(group); - bdur = System.currentTimeMillis() - bstart; - System.out.println("runtime exception took " + bdur/1000L + " seconds"); - - // remove unused methods - bstart = System.currentTimeMillis(); - new UnusedMethods().run(group); - bdur = System.currentTimeMillis() - bstart; - System.out.println("unused methods took " + bdur/1000L + " seconds"); - - new UnreachedCode().run(group); - - // remove illegal state exceptions, frees up some parameters - bstart = System.currentTimeMillis(); - new IllegalStateExceptions().run(group); - bdur = System.currentTimeMillis() - bstart; - System.out.println("illegal state exception took " + bdur/1000L + " seconds"); - - // remove constant logically dead parameters - bstart = System.currentTimeMillis(); - new ConstantParameter().run(group); - bdur = System.currentTimeMillis() - bstart; - System.out.println("constant param took " + bdur/1000L + " seconds"); - - // remove unhit blocks - bstart = System.currentTimeMillis(); - new UnreachedCode().run(group); - //new UnusedBlocks().run(group); - bdur = System.currentTimeMillis() - bstart; - System.out.println("unused blocks took " + bdur/1000L + " seconds"); - - // remove unused parameters - bstart = System.currentTimeMillis(); - new UnusedParameters().run(group); - bdur = System.currentTimeMillis() - bstart; - System.out.println("unused params took " + bdur/1000L + " seconds"); - - // remove jump obfuscation - //new Jumps().run(group); - - // remove unused fields - bstart = System.currentTimeMillis(); - new UnusedFields().run(group); - bdur = System.currentTimeMillis() - bstart; - System.out.println("unused fields took " + bdur/1000L + " seconds"); - - // remove unused methods, again? - bstart = System.currentTimeMillis(); - new UnusedMethods().run(group); - bdur = System.currentTimeMillis() - bstart; - System.out.println("unused methods took " + bdur/1000L + " seconds"); +// // remove except RuntimeException +// bstart = System.currentTimeMillis(); +// new RuntimeExceptions().run(group); +// bdur = System.currentTimeMillis() - bstart; +// System.out.println("runtime exception took " + bdur/1000L + " seconds"); +// +// // remove unused methods +// bstart = System.currentTimeMillis(); +// new UnusedMethods().run(group); +// bdur = System.currentTimeMillis() - bstart; +// System.out.println("unused methods took " + bdur/1000L + " seconds"); +// +// new UnreachedCode().run(group); +// +// // remove illegal state exceptions, frees up some parameters +// bstart = System.currentTimeMillis(); +// new IllegalStateExceptions().run(group); +// bdur = System.currentTimeMillis() - bstart; +// System.out.println("illegal state exception took " + bdur/1000L + " seconds"); +// +// // remove constant logically dead parameters +// bstart = System.currentTimeMillis(); +// new ConstantParameter().run(group); +// bdur = System.currentTimeMillis() - bstart; +// System.out.println("constant param took " + bdur/1000L + " seconds"); +// +// // remove unhit blocks +// bstart = System.currentTimeMillis(); +// new UnreachedCode().run(group); +// //new UnusedBlocks().run(group); +// bdur = System.currentTimeMillis() - bstart; +// System.out.println("unused blocks took " + bdur/1000L + " seconds"); +// +// // remove unused parameters +// bstart = System.currentTimeMillis(); +// new UnusedParameters().run(group); +// bdur = System.currentTimeMillis() - bstart; +// System.out.println("unused params took " + bdur/1000L + " seconds"); +// +// // remove jump obfuscation +// //new Jumps().run(group); +// +// // remove unused fields +// bstart = System.currentTimeMillis(); +// new UnusedFields().run(group); +// bdur = System.currentTimeMillis() - bstart; +// System.out.println("unused fields took " + bdur/1000L + " seconds"); +// +// // remove unused methods, again? +// bstart = System.currentTimeMillis(); +// new UnusedMethods().run(group); +// bdur = System.currentTimeMillis() - bstart; +// System.out.println("unused methods took " + bdur/1000L + " seconds"); new MethodInliner().run(group); - - new MethodMover().run(group); - - new FieldInliner().run(group); +// +// new MethodMover().run(group); +// +// new FieldInliner().run(group); // XXX this is broken because when moving clinit around, some fields can depend on other fields // (like multianewarray) diff --git a/src/main/java/net/runelite/deob/attributes/code/Exception.java b/src/main/java/net/runelite/deob/attributes/code/Exception.java index b0ae83fa6f..6ad9e1b32c 100644 --- a/src/main/java/net/runelite/deob/attributes/code/Exception.java +++ b/src/main/java/net/runelite/deob/attributes/code/Exception.java @@ -41,6 +41,14 @@ public class Exception { ConstantPool pool = exceptions.getCode().getAttributes().getClassFile().getPool(); + assert start.getInstructions() == exceptions.getCode().getInstructions(); + assert end.getInstructions() == exceptions.getCode().getInstructions(); + assert handler.getInstructions() == exceptions.getCode().getInstructions(); + + assert start.getInstructions().getInstructions().contains(start); + assert end.getInstructions().getInstructions().contains(end); + assert handler.getInstructions().getInstructions().contains(handler); + out.writeShort(start.getPc()); out.writeShort(end.getPc()); out.writeShort(handler.getPc()); @@ -52,6 +60,11 @@ public class Exception return exceptions; } + public void setExceptions(Exceptions exceptions) + { + this.exceptions = exceptions; + } + public Instruction getStart() { return start; diff --git a/src/main/java/net/runelite/deob/attributes/code/Exceptions.java b/src/main/java/net/runelite/deob/attributes/code/Exceptions.java index 417e9f4f53..e9de6f3c31 100644 --- a/src/main/java/net/runelite/deob/attributes/code/Exceptions.java +++ b/src/main/java/net/runelite/deob/attributes/code/Exceptions.java @@ -29,6 +29,11 @@ public class Exceptions exceptions.add(new Exception(this)); } + public void add(Exception e) + { + exceptions.add(e); + } + public void remove(Exception e) { exceptions.remove(e); @@ -38,7 +43,10 @@ public class Exceptions { out.writeShort(exceptions.size()); for (Exception e : exceptions) + { + assert e.getExceptions() == this; e.write(out); + } } public Code getCode() diff --git a/src/main/java/net/runelite/deob/deobfuscators/MethodInliner.java b/src/main/java/net/runelite/deob/deobfuscators/MethodInliner.java index d4b8dd6ea4..c86f15976e 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/MethodInliner.java +++ b/src/main/java/net/runelite/deob/deobfuscators/MethodInliner.java @@ -25,6 +25,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import net.runelite.deob.attributes.code.Exceptions; public class MethodInliner implements Deobfuscator { @@ -100,9 +101,6 @@ public class MethodInliner implements Deobfuscator if (invokedMethod.isSynchronized()) continue; - if (!invokedMethod.getCode().getExceptions().getExceptions().isEmpty()) - continue; - // assign variables on stack to lvt Signature descriptor = invokedMethod.getDescriptor(); @@ -112,7 +110,7 @@ public class MethodInliner implements Deobfuscator lvtIndexes.put(j, idx); idx += descriptor.getTypeOfArg(j).getSlots(); } - + for (int j = descriptor.size() - 1; j >= 0; --j) { Type type = descriptor.getTypeOfArg(j); @@ -131,19 +129,15 @@ public class MethodInliner implements Deobfuscator case "S": case "I": storeIns = new IStore(ins, lvtIndex + paramLvtIndex); - //lvtIndex += type.getSlots(); break; case "J": storeIns = new LStore(ins, lvtIndex + paramLvtIndex); - //lvtIndex += type.getSlots(); break; case "F": storeIns = new FStore(ins, lvtIndex + paramLvtIndex); - //lvtIndex += type.getSlots(); break; case "D": storeIns = new DStore(ins, lvtIndex + paramLvtIndex); - //lvtIndex += type.getSlots(); break; } } @@ -152,7 +146,6 @@ public class MethodInliner implements Deobfuscator { assert storeIns == null; storeIns = new AStore(ins, lvtIndex + paramLvtIndex); - //lvtIndex += type.getSlots(); } assert storeIns != null; @@ -164,6 +157,7 @@ public class MethodInliner implements Deobfuscator code.setMaxStack(maxStack); inline(m, i, invokedMethod, lvtIndex); + moveExceptions(m, invokedMethod); ++inlineCount; break; } @@ -204,6 +198,9 @@ public class MethodInliner implements Deobfuscator } invokeIns.from.clear(); + for (net.runelite.deob.attributes.code.Exception e : invokeMethodCode.getExceptions().getExceptions()) + e.replace(invokeIns, nop); + methodInstructions.remove(invokeIns); for (Instruction i : invokeMethodInstructions.getInstructions()) @@ -225,6 +222,9 @@ public class MethodInliner implements Deobfuscator i2.replace(oldI, i); oldI.from.clear(); + + for (net.runelite.deob.attributes.code.Exception e : invokeMethodCode.getExceptions().getExceptions()) + e.replace(oldI, i); } if (i instanceof LVTInstruction) @@ -245,6 +245,9 @@ public class MethodInliner implements Deobfuscator i2.replace(oldI, i); oldI.from.clear(); + + for (net.runelite.deob.attributes.code.Exception e : invokeMethodCode.getExceptions().getExceptions()) + e.replace(oldI, i); } } @@ -257,6 +260,19 @@ public class MethodInliner implements Deobfuscator removeMethods.add(invokeMethod); } + private void moveExceptions(Method to, Method from) + { + Exceptions exceptions = from.getCode().getExceptions(); + Exceptions toExceptions = to.getCode().getExceptions(); + + for (net.runelite.deob.attributes.code.Exception e : exceptions.getExceptions()) + { + e.setExceptions(toExceptions); + toExceptions.add(e); + } + exceptions.getExceptions().clear(); + } + @Override public void run(ClassGroup group) {