diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/GetStatic.java b/src/main/java/net/runelite/deob/attributes/code/instructions/GetStatic.java index bcf957ebca..68b2451a5d 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/GetStatic.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/GetStatic.java @@ -50,7 +50,7 @@ public class GetStatic extends Instruction implements GetFieldInstruction Encryption encryption = frame.getExecution().getEncryption(); net.runelite.deob.Field f = getMyField(); - if (f != null) + if (f != null && encryption != 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 8d95e1c4e9..a8911d329a 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 @@ -41,11 +41,14 @@ public class IMul extends Instruction // '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 (other != 1 && other != 0) + { + int o = other * DMath.modInverse(one.encryption); + + System.out.println(other + " -> " + o); + + encryption.change(pci, o); + } // if (one.encryption == other) // { @@ -57,11 +60,14 @@ public class IMul extends Instruction 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); + if (other != 1 && other != 0) + { + int o = other * DMath.modInverse(two.encryption); + + System.out.println(other + " -> " + o); + + encryption.change(pci, o); + } } } 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 050af727ce..0dd9038839 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 @@ -64,9 +64,12 @@ public class PutStatic extends Instruction implements SetFieldInstruction PushConstantInstruction pci = (PushConstantInstruction) ctx.getInstruction(); int value = (int) pci.getConstant().getObject(); - value = value * pair.getter; - - encryption.change(pci, value); + if (value != 0 && value != 1) + { + value = value * pair.getter; + + encryption.change(pci, value); + } } if (ctx.getInstruction() instanceof ISub) { @@ -97,9 +100,12 @@ public class PutStatic extends Instruction implements SetFieldInstruction // field is encrypted with pair // divide value by setter - value = value * pair.getter; - - encryption.change(pci, value); + if (value != 0 && value != 1) + { + value = value * pair.getter; + + encryption.change(pci, value); + } } else if (two.getPushed().getInstruction() instanceof PushConstantInstruction) @@ -110,9 +116,12 @@ public class PutStatic extends Instruction implements SetFieldInstruction // field is encrypted with pair // divide value by setter - value = value * pair.getter; - - encryption.change(pci, value); + if (value != 0 && value != 1) + { + value = value * pair.getter; + + encryption.change(pci, value); + } } else assert false; 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 b71b502a94..a9abba21c5 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/Encryption.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/Encryption.java @@ -10,36 +10,34 @@ public class Encryption { private Map fields = new HashMap<>(); private Map changes = new HashMap<>(); - int i; - private Pair p; - public Encryption(int i) + public void addPair(Pair pair) { - this.i = i; + fields.put(pair.field, pair); } public Pair getField(Field field) { - if (i == 0 && field.getName().equals("field1170")) - { - Pair p = new Pair(); - p.field = field; - p.getter = -1570098313; - p.setter = DMath.modInverse(p.getter); - assert p.setter == 1237096007; - return p; - } - if (i == 1 && field.getName().equals("field700")) - { - Pair p = new Pair(); - p.field = field; - p.getter = -478315765; - p.setter = DMath.modInverse(p.getter); - //assert p.setter == - return p; - } - return null; - //return fields.get(field); +// if (i == 0 && field.getName().equals("field1170")) +// { +// Pair p = new Pair(); +// p.field = field; +// p.getter = -1570098313; +// p.setter = DMath.modInverse(p.getter); +// assert p.setter == 1237096007; +// return p; +// } +// if (i == 1 && field.getName().equals("field700")) +// { +// Pair p = new Pair(); +// p.field = field; +// p.getter = -478315765; +// p.setter = DMath.modInverse(p.getter); +// //assert p.setter == +// return p; +// } +// return null; + return fields.get(field); } public void change(PushConstantInstruction pci, int 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 9f06cf2a40..5b4671dadb 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java @@ -15,6 +15,8 @@ import net.runelite.deob.attributes.code.instruction.types.FieldInstruction; import net.runelite.deob.attributes.code.instruction.types.GetFieldInstruction; import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction; import net.runelite.deob.attributes.code.instruction.types.PushConstantInstruction; +import net.runelite.deob.attributes.code.instruction.types.SetFieldInstruction; +import net.runelite.deob.attributes.code.instructions.IMul; import net.runelite.deob.execution.Execution; import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; @@ -30,12 +32,15 @@ public class ModArith implements Deobfuscator { private ClassGroup group; private Execution execution; - private MultiValueMap fieldIns = new MultiValueMap<>(); + private MultiValueMap constants = new MultiValueMap<>(); + //private MultiValueMap fieldIns = new MultiValueMap<>(); - private void findGetField(InstructionContext ctx) - { - - } + + +// private void findGetField(InstructionContext ctx) +// { +// +// } private void findUses() { @@ -44,65 +49,122 @@ public class ModArith implements Deobfuscator for (Frame f : execution.processedFrames) for (InstructionContext ctx : f.getInstructions()) { - Instruction i = ctx.getInstruction(); - - if (!(i instanceof FieldInstruction)) - continue; - - FieldInstruction fi = (FieldInstruction) i; - - Field fifield = fi.getMyField(); - - if (fifield == null) - continue; - - fieldIns.put(fifield, ctx); -// if (i instanceof GetFieldInstruction) -// { -// findGetField(ctx); -// } + if (ctx.getInstruction() instanceof IMul) + { + Instruction one = ctx.getPops().get(0).getPushed().getInstruction(); + Instruction two = ctx.getPops().get(1).getPushed().getInstruction(); + + PushConstantInstruction pc = null; + GetFieldInstruction gf = null; + if (one instanceof PushConstantInstruction && two instanceof GetFieldInstruction) + { + pc = (PushConstantInstruction) one; + gf = (GetFieldInstruction) two; + } + else if (two instanceof PushConstantInstruction && one instanceof GetFieldInstruction) + { + pc = (PushConstantInstruction) two; + gf = (GetFieldInstruction) one; + } + + if (pc == null) + continue; + + Field field = gf.getMyField(); + int value = (int) pc.getConstant().getObject(); + + constants.put(field, value); + } + else if (ctx.getInstruction() instanceof SetFieldInstruction) + { + SetFieldInstruction sf = (SetFieldInstruction) ctx.getInstruction(); + + StackContext value = ctx.getPops().get(0); // what setfield pops as value + if (!(value.getPushed().getInstruction() instanceof IMul)) + continue; + + Instruction one = value.getPushed().getPops().get(0).getPushed().getInstruction(); + Instruction two = value.getPushed().getPops().get(1).getPushed().getInstruction(); + + PushConstantInstruction pc = null; + Instruction other = null; + if (one instanceof PushConstantInstruction) + { + pc = (PushConstantInstruction) one; + other = two; + } + else if (two instanceof PushConstantInstruction) + { + pc = (PushConstantInstruction) two; + other = one; + } + + if (pc == null) + continue; + + Field field = sf.getMyField(); + int value2 = (int) pc.getConstant().getObject(); + + constants.put(field, value2); + } } - - //return list; -// for (ClassFile cf : group.getClasses()) -// for (Field f : cf.getFields().getFields()) -// { -// -// } } - public void calculate(Field field) + private void reduce() { - Collection c = fieldIns.getCollection(field); - if (c == null) - return; + MultiValueMap values = constants; + constants = new MultiValueMap<>(); - List constants = new ArrayList<>(); - for (InstructionContext ctx : c) + for (Field field : values.keySet()) { - if (ctx.getInstruction() instanceof GetFieldInstruction) - { - List fields = getFieldsInExpression(ctx, constants); - if (fields.size() == 1) - { + Collection col = values.getCollection(field); + + Map map = CollectionUtils.getCardinalityMap(col); + int max = Collections.max(map.values()); + + for (final Map.Entry entry : map.entrySet()) { + if (max == entry.getValue()) { + int constant = entry.getKey(); + + constants.put(field, constant); + break; } } } - - Map map = CollectionUtils.getCardinalityMap(constants); - int max = Collections.max(map.values()); - - for (final Map.Entry entry : map.entrySet()) { - if (max == entry.getValue()) { - int constant = entry.getKey(); - - System.out.println(constant); - assert DMath.isInversable(constant); - break; - } - } } +// public void calculate(Field field) +// { +// Collection c = fieldIns.getCollection(field); +// if (c == null) +// return; +// +// List constants = new ArrayList<>(); +// for (InstructionContext ctx : c) +// { +// if (ctx.getInstruction() instanceof GetFieldInstruction) +// { +// List fields = getFieldsInExpression(ctx, constants); +// if (fields.size() == 1) +// { +// } +// } +// } +// +// Map map = CollectionUtils.getCardinalityMap(constants); +// int max = Collections.max(map.values()); +// +// for (final Map.Entry entry : map.entrySet()) { +// if (max == entry.getValue()) { +// int constant = entry.getKey(); +// +// System.out.println(constant); +// assert DMath.isInversable(constant); +// break; +// } +// } +// } + private List getFieldsInExpression(InstructionContext ctx, List constants) { return check(ctx, new HashSet(), constants); @@ -166,24 +228,60 @@ public class ModArith implements Deobfuscator execution = new Execution(group); execution.populateInitialMethods(); - - Encryption encr = new Encryption(0); - execution.setEncryption(encr); - execution.run(); - encr.doChange(); + findUses(); + reduce(); + int i = 0; + for (Field field : constants.keySet()) + { + System.out.println("Processing " + field.getName()); + int getter = constants.getCollection(field).iterator().next(); + + if (i > 5) + break; + + Pair pair = new Pair(); + pair.field = field; + pair.getter = getter; + pair.setter = DMath.modInverse(getter); + + Encryption encr = new Encryption(); + encr.addPair(pair); + + execution = new Execution(group); + execution.populateInitialMethods(); + execution.setEncryption(encr); + execution.run(); + + encr.doChange(); + System.out.println("Changed" + ++i); + } - execution = new Execution(group); - execution.populateInitialMethods(); + Encryption encr = new Encryption(); + System.out.println(constants); - encr = new Encryption(1); - execution.setEncryption(encr); - - execution.run(); - - encr.doChange(); +// execution = new Execution(group); +// execution.populateInitialMethods(); +// +// Encryption encr = new Encryption(0); +// execution.setEncryption(encr); +// +// execution.run(); +// +// encr.doChange(); +// +// +// execution = new Execution(group); +// execution.populateInitialMethods(); +// +// encr = new Encryption(1); +// execution.setEncryption(encr); +// +// execution.run(); +// +// encr.doChange(); // findUses(); //