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 d06c53e804..7be1b61a21 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java @@ -37,6 +37,7 @@ public class ModArith implements Deobfuscator { private ClassGroup group; private Execution execution; + private Set obfuscatedFields = new HashSet<>(); private MultiValueMap constantGetters = new MultiValueMap<>(), constantSetters = new MultiValueMap<>(); private List pairs = new ArrayList<>(); @@ -67,11 +68,12 @@ public class ModArith implements Deobfuscator return l; } - private boolean isFieldObfuscated(Execution e, Field field) + private void findObfuscatedFields() { // find a direct big*field with no other fields involved + obfuscatedFields.clear(); - for (Frame f : e.processedFrames) + for (Frame f : execution.processedFrames) { outer: for (InstructionContext ctx : f.getInstructions()) @@ -80,48 +82,45 @@ public class ModArith implements Deobfuscator { SetFieldInstruction sfi = (SetFieldInstruction) ctx.getInstruction(); - if (sfi.getMyField() == field) + InstructionContext pushedsfi = ctx.getPops().get(0).getPushed(); + if (pushedsfi.getInstruction() instanceof LDC_W || pushedsfi.getInstruction() instanceof LDC2_W) { - InstructionContext pushedsfi = ctx.getPops().get(0).getPushed(); - if (pushedsfi.getInstruction() instanceof LDC_W || pushedsfi.getInstruction() instanceof LDC2_W) + PushConstantInstruction ldc = (PushConstantInstruction) pushedsfi.getInstruction(); + if (ldc.getConstant().getObject() instanceof Integer || ldc.getConstant().getObject() instanceof Long) { - PushConstantInstruction ldc = (PushConstantInstruction) pushedsfi.getInstruction(); - if (ldc.getConstant().getObject() instanceof Integer || ldc.getConstant().getObject() instanceof Long) - { - Number it = (Number) ldc.getConstant().getObject(); - if (DMath.isBig(it)) - // field = constant - return true; - } + Number it = (Number) ldc.getConstant().getObject(); + if (DMath.isBig(it)) + // field = constant + this.obfuscatedFields.add(sfi.getMyField()); } - else if (pushedsfi.getInstruction() instanceof IMul || pushedsfi.getInstruction() instanceof LMul) + } + else if (pushedsfi.getInstruction() instanceof IMul || pushedsfi.getInstruction() instanceof LMul) + { + Instruction one = pushedsfi.getPops().get(0).getPushed().getInstruction(); + Instruction two = pushedsfi.getPops().get(1).getPushed().getInstruction(); + + PushConstantInstruction pci = null; + Instruction other = null; + if (one instanceof LDC_W || one instanceof LDC2_W) { - Instruction one = pushedsfi.getPops().get(0).getPushed().getInstruction(); - Instruction two = pushedsfi.getPops().get(1).getPushed().getInstruction(); - - PushConstantInstruction pci = null; - Instruction other = null; - if (one instanceof LDC_W || one instanceof LDC2_W) + pci = (PushConstantInstruction) one; + other = two; + } + else if (two instanceof LDC_W || two instanceof LDC2_W) + { + pci = (PushConstantInstruction) two; + other = one; + } + + if (pci != null + && !(other instanceof GetFieldInstruction)) + { + if (pci.getConstant().getObject() instanceof Integer || pci.getConstant().getObject() instanceof Long) { - pci = (PushConstantInstruction) one; - other = two; - } - else if (two instanceof LDC_W || two instanceof LDC2_W) - { - pci = (PushConstantInstruction) two; - other = one; - } - - if (pci != null - && !(other instanceof GetFieldInstruction)) - { - if (pci.getConstant().getObject() instanceof Integer || pci.getConstant().getObject() instanceof Long) - { - Number i = (Number) pci.getConstant().getObject(); - if (DMath.isBig(i)) - // field = constant * not other field - return true; - } + Number i = (Number) pci.getConstant().getObject(); + if (DMath.isBig(i)) + // field = constant * not other field + this.obfuscatedFields.add(sfi.getMyField()); } } } @@ -152,7 +151,7 @@ public class ModArith implements Deobfuscator continue; } - if (other.getMyField() != null && other.getMyField() != field) + if (other.getMyField() != null) continue; if (!(pc.getConstant().getObject() instanceof Integer) && !(pc.getConstant().getObject() instanceof Long)) @@ -164,8 +163,8 @@ public class ModArith implements Deobfuscator try { - MultiplicationExpression expr = MultiplicationDeobfuscator.parseExpression(e, ctx, ctx.getInstruction().getClass()); - if (expr.hasFieldOtherThan(field)) + MultiplicationExpression expr = MultiplicationDeobfuscator.parseExpression(execution, ctx, ctx.getInstruction().getClass()); + if (expr.hasFieldOtherThan(other.getMyField())) continue; } catch (IllegalStateException ex) @@ -178,15 +177,13 @@ public class ModArith implements Deobfuscator { SetFieldInstruction sfi = (SetFieldInstruction) popped.getInstruction(); - if (sfi.getMyField() != null && sfi.getMyField() != field) + if (sfi.getMyField() != null) continue; } - return true; + this.obfuscatedFields.add(other.getMyField()); } } - - return false; } static class AssociatedConstant @@ -537,7 +534,7 @@ public class ModArith implements Deobfuscator removeDupes(noOther); removeDupes(other); - if (!isFieldObfuscated(execution, f)) + if (!this.obfuscatedFields.contains(f)) continue; // guess with constants not associated with other fields @@ -648,6 +645,7 @@ public class ModArith implements Deobfuscator execution.populateInitialMethods(); execution.run(); + findObfuscatedFields(); findUses(); findUses2(); reduce2(); diff --git a/src/test/java/net/runelite/deob/deobfuscators/ModArithTest.java b/src/test/java/net/runelite/deob/deobfuscators/ModArithTest.java new file mode 100644 index 0000000000..7135978710 --- /dev/null +++ b/src/test/java/net/runelite/deob/deobfuscators/ModArithTest.java @@ -0,0 +1,61 @@ +package net.runelite.deob.deobfuscators; + +import java.io.File; +import java.io.IOException; +import net.runelite.asm.ClassGroup; +import net.runelite.deob.deobfuscators.arithmetic.ModArith; +import net.runelite.deob.deobfuscators.arithmetic.MultiplicationDeobfuscator; +import net.runelite.deob.deobfuscators.arithmetic.MultiplyOneDeobfuscator; +import net.runelite.deob.deobfuscators.arithmetic.MultiplyZeroDeobfuscator; +import net.runelite.deob.util.JarUtil; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class ModArithTest +{ + private static final File GAMEPACK = new File("d:/rs/07/adamin.jar"); + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + private ClassGroup group; + + @Before + public void before() throws IOException + { + group = JarUtil.loadJar(GAMEPACK); + } + + @After + public void after() throws IOException + { + JarUtil.saveJar(group, folder.newFile()); + } + + @Test + public void testRun() + { + 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) + break; + + last = cur; + } + + mod.annotateEncryption(); + } +} diff --git a/src/test/java/net/runelite/deob/deobfuscators/arithmetic/ModArithTest.java b/src/test/java/net/runelite/deob/deobfuscators/arithmetic/SimpleModArithTest.java similarity index 98% rename from src/test/java/net/runelite/deob/deobfuscators/arithmetic/ModArithTest.java rename to src/test/java/net/runelite/deob/deobfuscators/arithmetic/SimpleModArithTest.java index 59a518bf75..9f57dcaa23 100644 --- a/src/test/java/net/runelite/deob/deobfuscators/arithmetic/ModArithTest.java +++ b/src/test/java/net/runelite/deob/deobfuscators/arithmetic/SimpleModArithTest.java @@ -71,7 +71,7 @@ class TestClass2 } } -public class ModArithTest +public class SimpleModArithTest { private void checkConstants(ClassFile cf) {