From 7ac2b0e977afe34b2cafe821f97b2db687fe902c Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 23 Aug 2015 18:22:51 -0400 Subject: [PATCH] Working on doing arith deob during exec --- .../code/instructions/GetField.java | 2 +- .../attributes/code/instructions/IMul.java | 39 ++++++++++++ .../code/instructions/PutStatic.java | 61 +++++++++++++++++++ .../deobfuscators/arithmetic/Encryption.java | 20 ++++++ .../deobfuscators/arithmetic/ModArith.java | 12 +++- .../runelite/deob/execution/Execution.java | 5 ++ 6 files changed, 135 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/GetField.java b/src/main/java/net/runelite/deob/attributes/code/instructions/GetField.java index 9449bedc2c..67da2bdf62 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/GetField.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/GetField.java @@ -53,7 +53,7 @@ public class GetField extends Instruction implements GetFieldInstruction Encryption encryption = frame.getExecution().getEncryption(); net.runelite.deob.Field f = getMyField(); - if (f != null) + if (encryption != null && f != null) { Pair pair = encryption.getField(f); if (pair != null) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IMul.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IMul.java index c1688b0c9c..8d95e1c4e9 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IMul.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IMul.java @@ -3,6 +3,10 @@ package net.runelite.deob.attributes.code.instructions; import net.runelite.deob.attributes.code.Instruction; import net.runelite.deob.attributes.code.InstructionType; import net.runelite.deob.attributes.code.Instructions; +import net.runelite.deob.attributes.code.instruction.types.PushConstantInstruction; +import net.runelite.deob.deobfuscators.arithmetic.DMath; +import net.runelite.deob.deobfuscators.arithmetic.Encryption; +import net.runelite.deob.execution.Execution; import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; import net.runelite.deob.execution.Stack; @@ -26,6 +30,41 @@ public class IMul extends Instruction ins.pop(one, two); + Encryption encryption = frame.getExecution().getEncryption(); + if (encryption != null) + { + if (one.encryption != 0) + { + assert two.encryption == 0; + PushConstantInstruction pci = (PushConstantInstruction) two.getPushed().getInstruction(); + int other = (int) pci.getConstant().getObject(); + + // 'one' is encrypted and we want to decrypt it by dividing by one.encryption + + int o = other * DMath.modInverse(one.encryption); + + System.out.println(other + " -> " + o); + + encryption.change(pci, o); + +// if (one.encryption == other) +// { +// System.out.println("decrr"); +// } + } + else if (two.encryption != 0) + { + PushConstantInstruction pci = (PushConstantInstruction) one.getPushed().getInstruction(); + int other = (int) pci.getConstant().getObject(); + + int o = other * DMath.modInverse(two.encryption); + + System.out.println(other + " -> " + o); + + encryption.change(pci, o); + } + } + StackContext ctx = new StackContext(ins, int.class); stack.push(ctx); diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/PutStatic.java b/src/main/java/net/runelite/deob/attributes/code/instructions/PutStatic.java index b49c30e1f4..e95550f159 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/PutStatic.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/PutStatic.java @@ -16,6 +16,10 @@ import net.runelite.deob.pool.NameAndType; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.List; +import net.runelite.deob.attributes.code.instruction.types.PushConstantInstruction; +import net.runelite.deob.deobfuscators.arithmetic.Encryption; +import net.runelite.deob.deobfuscators.arithmetic.Pair; public class PutStatic extends Instruction implements SetFieldInstruction { @@ -46,6 +50,63 @@ public class PutStatic extends Instruction implements SetFieldInstruction StackContext object = stack.pop(); ins.pop(object); + Encryption encryption = frame.getExecution().getEncryption(); + net.runelite.deob.Field myField = getMyField(); + if (encryption != null && myField != null) + { + Pair pair = encryption.getField(myField); + InstructionContext ctx = object.getPushed(); + if (ctx.getInstruction() instanceof ISub) + { + List stackCtx = ctx.getPops(); + + StackContext one = stackCtx.get(0), two = stackCtx.get(1); + + if (one.getPushed().getInstruction() instanceof IMul) + { + ctx = one.getPushed(); + } + else if (two.getPushed().getInstruction() instanceof IMul) + { + ctx = two.getPushed(); + } + } + if (ctx.getInstruction() instanceof IMul && pair != null) + { + List stackCtx = ctx.getPops(); + + StackContext one = stackCtx.get(0), two = stackCtx.get(1); + + if (one.getPushed().getInstruction() instanceof PushConstantInstruction) + { + PushConstantInstruction pci = (PushConstantInstruction) one.getPushed().getInstruction(); + int value = (int) pci.getConstant().getObject(); + + // field is encrypted with pair + // divide value by setter + + value = value * pair.getter; + + encryption.change(pci, value); + + } + else if (two.getPushed().getInstruction() instanceof PushConstantInstruction) + { + PushConstantInstruction pci = (PushConstantInstruction) two.getPushed().getInstruction(); + int value = (int) pci.getConstant().getObject(); + + // field is encrypted with pair + // divide value by setter + + value = value * pair.getter; + + encryption.change(pci, value); + } + else + assert false; + } + } + frame.addInstructionContext(ins); } diff --git a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/Encryption.java b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/Encryption.java index c6f7c8f435..b05133f860 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/Encryption.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/Encryption.java @@ -2,11 +2,14 @@ package net.runelite.deob.deobfuscators.arithmetic; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import net.runelite.deob.Field; +import net.runelite.deob.attributes.code.instruction.types.PushConstantInstruction; public class Encryption { private Map fields = new HashMap<>(); + private Map changes = new HashMap<>(); public Pair getField(Field field) { @@ -22,4 +25,21 @@ public class Encryption return null; //return fields.get(field); } + + public void change(PushConstantInstruction pci, int value) + { + assert !changes.containsKey(pci) || changes.get(pci) == value; + changes.put(pci, value); + } + + public void doChange() + { + for (Entry e : changes.entrySet()) + { + PushConstantInstruction pci = e.getKey(); + int value = e.getValue(); + + pci.setConstant(new net.runelite.deob.pool.Integer(value)); + } + } } 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 254917cd09..43f3c5ed3f 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java @@ -178,12 +178,18 @@ public class ModArith implements Deobfuscator execution = new Execution(group); execution.populateInitialMethods(); + + Encryption encr = new Encryption(); + execution.setEncryption(encr); + execution.run(); - findUses(); + encr.doChange(); - Field f = group.findClass("class41").findField("field1170"); - calculate(f); +// findUses(); +// +// Field f = group.findClass("class41").findField("field1170"); +// calculate(f); } } diff --git a/src/main/java/net/runelite/deob/execution/Execution.java b/src/main/java/net/runelite/deob/execution/Execution.java index 5e3ba5bdd5..716649bf2d 100644 --- a/src/main/java/net/runelite/deob/execution/Execution.java +++ b/src/main/java/net/runelite/deob/execution/Execution.java @@ -34,6 +34,11 @@ public class Execution return encryption; } + public void setEncryption(Encryption encryption) + { + this.encryption = encryption; + } + public void populateInitialMethods() { for (ClassFile cf : group.getClasses())