From adcfdc471a7f9333fc1c498292fda4cdd7641593 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 22 Nov 2015 15:07:15 -0600 Subject: [PATCH] Added failing negative mul test --- src/main/java/net/runelite/deob/Deob.java | 82 +++++++++---------- .../deobfuscators/arithmetic/ModArith.java | 5 ++ .../runelite/deob/execution/Execution.java | 8 -- .../arithmetic/ModArithTest.java | 80 ++++++++++++++++-- 4 files changed, 118 insertions(+), 57 deletions(-) diff --git a/src/main/java/net/runelite/deob/Deob.java b/src/main/java/net/runelite/deob/Deob.java index 61dcdf8677..7c5cd3ac88 100644 --- a/src/main/java/net/runelite/deob/Deob.java +++ b/src/main/java/net/runelite/deob/Deob.java @@ -31,47 +31,47 @@ public class Deob ClassGroup group = JarUtil.loadJar(new File(args[0])); - run(group, new RenameUnique()); - - // remove except RuntimeException - run(group, new RuntimeExceptions()); - - // remove unused methods - run(group, new UnreachedCode()); - run(group, new UnusedMethods()); - - // 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 unused fields - run(group, new UnusedFields()); - - // remove unused methods, again? - run(group, new UnusedMethods()); - -// run(group, new MethodInliner()); -// run(group, new UnusedMethods()); // inliner might leave unused methods - -// // 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()); +// run(group, new RenameUnique()); +// +// // remove except RuntimeException +// run(group, new RuntimeExceptions()); +// +// // remove unused methods +// run(group, new UnreachedCode()); +// run(group, new UnusedMethods()); +// +// // 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 unused fields +// run(group, new UnusedFields()); +// +// // remove unused methods, again? +// run(group, new UnusedMethods()); +// +//// run(group, new MethodInliner()); +//// run(group, new UnusedMethods()); // inliner might leave unused methods +// +//// // 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); diff --git a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java index ca08432b6a..4269d24073 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java @@ -695,4 +695,9 @@ public class ModArith implements Deobfuscator } } } + + public Encryption getEncryption() + { + return encryption; + } } diff --git a/src/main/java/net/runelite/deob/execution/Execution.java b/src/main/java/net/runelite/deob/execution/Execution.java index 9c34e1c7e8..13781e5e49 100644 --- a/src/main/java/net/runelite/deob/execution/Execution.java +++ b/src/main/java/net/runelite/deob/execution/Execution.java @@ -124,15 +124,7 @@ public class Execution methods.add(frame.getMethod()); - if (!frame.isExecuting()) - { - frames.remove(0); - processedFrames.add(frame); - continue; - } - ++fcount; - assert frame.isExecuting(); frame.execute(); assert frames.get(0) == frame; diff --git a/src/test/java/net/runelite/deob/deobfuscators/arithmetic/ModArithTest.java b/src/test/java/net/runelite/deob/deobfuscators/arithmetic/ModArithTest.java index 6003bceac1..62fe0db246 100644 --- a/src/test/java/net/runelite/deob/deobfuscators/arithmetic/ModArithTest.java +++ b/src/test/java/net/runelite/deob/deobfuscators/arithmetic/ModArithTest.java @@ -16,7 +16,10 @@ import org.junit.Test; class TestClass { - private static int dummy(Object... args) { return 0; } + private static int dummy(Object... args) + { + return 0; + } private int field1051 = -1611704481; private int field2701; @@ -26,7 +29,7 @@ class TestClass { TestClass tc = new TestClass(); // to trick executor to call the constructor int var = 42; - + if (-1 != this.field1051 * 1928543073) { dummy(this.field1051 * 1928543073); @@ -37,7 +40,7 @@ class TestClass { field2701 += -1868498967 * var; } - + field2138 = tc.dummy() * 1510226873; field2130 = 572701809 * tc.field2138; if (-1722291303 * field2130 >= var) @@ -47,6 +50,27 @@ class TestClass } } +class TestClass2 +{ + int field2863; + int array[]; + + public void test() + { + TestClass2 tc = new TestClass2(); + + field2863 = -1446933277; + + array[378529589 * tc.field2863] = 1; + + int var = 32; + + tc.field2863 = var * 1446933277; + + array[378529589 * tc.field2863] = 1; + } +} + public class ModArithTest { private void checkConstants(ClassFile cf) @@ -56,31 +80,71 @@ public class ModArithTest Code code = m.getCode(); Instructions instructions = code.getInstructions(); for (Instruction i : instructions.getInstructions()) + { if (i instanceof LDC_W) { LDC_W ldc = (LDC_W) i; Assert.assertFalse(DMath.isBig(ldc.getConstantAsInt())); } + } } } + @Test public void test() throws IOException { InputStream in = this.getClass().getClassLoader().getResourceAsStream("net/runelite/deob/deobfuscators/arithmetic/TestClass.class"); Assert.assertNotNull(in); - + ClassGroup group = new ClassGroup(); - + ClassFile cf = new ClassFile(group, new DataInputStream(in)); group.addClass(cf); - + ModArith d1 = new ModArith(); d1.run(group); d1.runOnce(); - + Deobfuscator d2 = new MultiplicationDeobfuscator(); d2.run(group); - + this.checkConstants(cf); } + + @Test + public void test2() throws IOException + { + InputStream in = this.getClass().getClassLoader().getResourceAsStream("net/runelite/deob/deobfuscators/arithmetic/TestClass2.class"); + Assert.assertNotNull(in); + + ClassGroup group = new ClassGroup(); + + ClassFile cf = new ClassFile(group, new DataInputStream(in)); + group.addClass(cf); + + ModArith d1 = new ModArith(); + d1.run(group); + + int last = -1, cur; + while ((cur = d1.runOnce()) > 0) + { + Deobfuscator d2 = new MultiplicationDeobfuscator(); + d2.run(group); + + new MultiplyOneDeobfuscator().run(group); + + new MultiplyZeroDeobfuscator().run(group); + + if (last == cur) + break; + + last = cur; + } + + Encryption e = d1.getEncryption(); + + Pair pair = e.getField(cf.findField("field2863").getPoolField()); + + Assert.assertEquals(378529589, (int) pair.getter); + } }