From 4d21fe7daf690c9a267937ec4f689a439a822e3b Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 19 Sep 2015 18:58:00 -0400 Subject: [PATCH] XXX confused. trying something new, by inserting * setter and * getter before/after put/set field --- .../attributes/code/instructions/IAdd.java | 17 ++- .../code/instructions/IConst_2.java | 2 +- .../code/instructions/IConst_3.java | 2 +- .../code/instructions/IConst_4.java | 2 +- .../code/instructions/IConst_5.java | 2 +- .../code/instructions/IConst_M1.java | 2 +- .../attributes/code/instructions/IMul.java | 17 ++- .../attributes/code/instructions/ISub.java | 14 +- .../code/instructions/PutField.java | 4 +- .../code/instructions/PutStatic.java | 58 +++++---- .../deobfuscators/arithmetic/Encryption.java | 12 +- .../deobfuscators/arithmetic/ModArith.java | 120 ++++++++++++++++-- .../net/runelite/deob/execution/Stack.java | 2 +- 13 files changed, 190 insertions(+), 64 deletions(-) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IAdd.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IAdd.java index 960d709e74..b6ec7a2d11 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IAdd.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IAdd.java @@ -42,15 +42,17 @@ public class IAdd extends Instruction PushConstantInstruction pci = (PushConstantInstruction) two.getPushed().getInstruction(); int value = (int) pci.getConstant().getObject(); - if (value != 0 && value != 1) + //if (value != 0 && value != 1) { int o = value * one.encryption; - encryption.change(pci, o); + encryption.change(pci, o, false); } + // field is no longer encrypted + encKey = 1; } - - encKey = one.encryption; + //else + // encKey = one.encryption; } else if (two.encryption != 0) { @@ -61,15 +63,16 @@ public class IAdd extends Instruction PushConstantInstruction pci = (PushConstantInstruction) one.getPushed().getInstruction(); int value = (int) pci.getConstant().getObject(); - if (value != 0 && value != 1) + //if (value != 0 && value != 1) { int o = value * two.encryption; - encryption.change(pci, o); + encryption.change(pci, o, false); } + encKey = 1; } - encKey = two.encryption; + //encKey = two.encryption; } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_2.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_2.java index 8461db8f82..35db6fa314 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_2.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_2.java @@ -42,6 +42,6 @@ public class IConst_2 extends Instruction implements PushConstantInstruction @Override public Instruction setConstant(PoolEntry entry) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + return new LDC_W(this.getInstructions(), entry); } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_3.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_3.java index 2f44c072bc..aefb49894a 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_3.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_3.java @@ -42,6 +42,6 @@ public class IConst_3 extends Instruction implements PushConstantInstruction @Override public Instruction setConstant(PoolEntry entry) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + return new LDC_W(this.getInstructions(), entry); } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_4.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_4.java index b5d011f815..e672610cb9 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_4.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_4.java @@ -42,6 +42,6 @@ public class IConst_4 extends Instruction implements PushConstantInstruction @Override public Instruction setConstant(PoolEntry entry) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + return new LDC_W(this.getInstructions(), entry); } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_5.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_5.java index c991de2308..f071b901cf 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_5.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_5.java @@ -42,6 +42,6 @@ public class IConst_5 extends Instruction implements PushConstantInstruction @Override public Instruction setConstant(PoolEntry entry) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + return new LDC_W(this.getInstructions(), entry); } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_M1.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_M1.java index bdbafebf5f..e0eda969ce 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_M1.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_M1.java @@ -42,6 +42,6 @@ public class IConst_M1 extends Instruction implements PushConstantInstruction @Override public Instruction setConstant(PoolEntry entry) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + return new LDC_W(this.getInstructions(), entry); } } 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 3350195244..d9c347ca83 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 @@ -18,6 +18,11 @@ public class IMul extends Instruction { super(instructions, type, pc); } + + public IMul(Instructions instructions) + { + super(instructions, InstructionType.IMUL, 0); + } @Override public void execute(Frame frame) @@ -42,12 +47,14 @@ public class IMul extends Instruction // 'one' is encrypted and we want to decrypt it by dividing by one.encryption - //if (other != 1 && other != 0) + if (other != 0) { int o = other * DMath.modInverse(one.encryption); - encryption.change(pci, o); + encryption.change(pci, o, false); } + + encKey = 1; } else if (two.encryption != 0) { @@ -56,12 +63,14 @@ public class IMul extends Instruction PushConstantInstruction pci = (PushConstantInstruction) one.getPushed().getInstruction(); int other = (int) pci.getConstant().getObject(); - //if (other != 1 && other != 0) + if (other != 0) { int o = other * DMath.modInverse(two.encryption); - encryption.change(pci, o); + encryption.change(pci, o, false); } + + encKey = 1; } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/ISub.java b/src/main/java/net/runelite/deob/attributes/code/instructions/ISub.java index 1ad181a86c..a1c1b448f9 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/ISub.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/ISub.java @@ -41,15 +41,16 @@ public class ISub extends Instruction PushConstantInstruction pci = (PushConstantInstruction) two.getPushed().getInstruction(); int value = (int) pci.getConstant().getObject(); - if (value != 0 && value != 1) + //if (value != 0 && value != 1) { int o = value * one.encryption; - encryption.change(pci, o); + encryption.change(pci, o, false); } + encKey = 1; } - encKey = one.encryption; + // encKey = one.encryption; } else if (two.encryption != 0) { @@ -60,15 +61,16 @@ public class ISub extends Instruction PushConstantInstruction pci = (PushConstantInstruction) one.getPushed().getInstruction(); int value = (int) pci.getConstant().getObject(); - if (value != 0 && value != 1) + //if (value != 0 && value != 1) { int o = value * two.encryption; - encryption.change(pci, o); + encryption.change(pci, o, false); } + encKey = 1; } - encKey = two.encryption; + //encKey = two.encryption; } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/PutField.java b/src/main/java/net/runelite/deob/attributes/code/instructions/PutField.java index e6f07617cd..89cd1c12e6 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/PutField.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/PutField.java @@ -58,8 +58,8 @@ public class PutField extends Instruction implements SetFieldInstruction if (encryption != null && myField != null) { Pair pair = encryption.getField(myField); - if (pair != null) - translate(encryption, pair, ins, new HashSet()); + //if (pair != null) + // translate(encryption, pair, ins, new HashSet()); // XXX move translate() here // InstructionContext ctx = value.getPushed(); // if (ctx.getInstruction() instanceof IAdd && pair != null) 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 a769b4edd8..c71ec51a10 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 @@ -71,29 +71,33 @@ public class PutStatic extends Instruction implements SetFieldInstruction return null; } - protected static boolean translate(Encryption encryption, Pair pair, InstructionContext ctx, Set visited) + public static boolean translate(Encryption encryption, Pair pair, InstructionContext ctx, Set visited) { if (visited.contains(ctx.getInstruction())) return true; visited.add(ctx.getInstruction()); - if (ctx.getInstruction() instanceof LDC_W) + if (ctx.getInstruction() instanceof PushConstantInstruction) { - LDC_W pci = (LDC_W) ctx.getInstruction(); - int value = (int) pci.getConstant().getObject(); + PushConstantInstruction pci = (PushConstantInstruction) ctx.getInstruction(); - if (encryption.hasChange(pci)) - return true; - - //if (value != 0 && value != 1) + if (pci.getConstant().getObject() instanceof Integer) { - value = value * pair.getter; + int value = (int) pci.getConstant().getObject(); - encryption.change(pci, value); + if (encryption.hasChange(pci)) + return true; + + if (value != 0) + { + value = value * pair.getter; + + encryption.change(pci, value, true); + } + + return true; } - - return true; } boolean ok = ctx.getInstruction() instanceof IAdd || @@ -137,17 +141,21 @@ public class PutStatic extends Instruction implements SetFieldInstruction encryption.end(); - for (StackContext sctx : ctx.getPushes()) - { - InstructionContext i = sctx.getPopped(); - - if (i != null) - translate(encryption, pair, i, visited); // XXX? - else - // this hasn't been popped yet, so it hasn't been executed yet, - // so mark it as encrypted so that when it is executed, we will decrypt it - sctx.encryption = pair.getter; - } +// for (StackContext sctx : ctx.getPushes()) +// { +// InstructionContext i = sctx.getPopped(); +// +// if (i != null) +// { +// boolean b = translate(encryption, pair, i, visited); // XXX? +// //System.out.println("up translate res " + b); +// } +// else +// assert false; +// // this hasn't been popped yet, so it hasn't been executed yet, +// // so mark it as encrypted so that when it is executed, we will decrypt it +// //sctx.encryption = pair.getter; +// } return retVal; } @@ -166,8 +174,8 @@ public class PutStatic extends Instruction implements SetFieldInstruction if (encryption != null && myField != null) { Pair pair = encryption.getField(myField); - if (pair != null) - translate(encryption, pair, ins, new HashSet()); + //if (pair != null) + // translate(encryption, pair, ins, new HashSet()); // InstructionContext ctx = object.getPushed(); // if (ctx.getInstruction() instanceof IAdd && pair != null) // { 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 cc9f7dc65a..db58756b34 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/Encryption.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/Encryption.java @@ -36,10 +36,18 @@ public class Encryption return changes.containsKey(pci); } - public void change(PushConstantInstruction pci, int value) + public void change(PushConstantInstruction pci, int value, boolean mul) { + //Integer i = changes.get(pci); assert !changes.containsKey(pci) || changes.get(pci) == value; - changes.put(pci, value); +// if (i == null) +// changes.put(pci, value); +// else if (mul) +// changes.put(pci, value * i); +// else + changes.put(pci, value); + // assert i == value; + if (stack.isEmpty()) return; PendingStack ps = stack.peek(); 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 f023e19b54..bc52be249a 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java @@ -11,14 +11,17 @@ import net.runelite.deob.ClassFile; import net.runelite.deob.ClassGroup; import net.runelite.deob.Deobfuscator; import net.runelite.deob.Field; +import net.runelite.deob.Method; +import net.runelite.deob.attributes.Code; import net.runelite.deob.attributes.code.Instruction; +import net.runelite.deob.attributes.code.Instructions; 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.attributes.code.instructions.LDC_W; +import net.runelite.deob.attributes.code.instructions.PutStatic; import net.runelite.deob.execution.Execution; import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; @@ -289,11 +292,11 @@ public class ModArith implements Deobfuscator Pair answer = reduce(getters, setters); - if (answer == null) - answer = guess(f, getters, true); + //if (answer == null) + // answer = guess(f, getters, true); - if (answer == null) - answer = guess(f, setters, false); + //if (answer == null) + // answer = guess(f, setters, false); if (answer == null) continue; @@ -307,6 +310,9 @@ public class ModArith implements Deobfuscator public void run(ClassGroup group) { this.group = group; + runOnce(); + if (true) return; + int passes = 0, total = 0, i; while ((i = runOnce()) > 0) { @@ -316,6 +322,79 @@ public class ModArith implements Deobfuscator System.out.println("Finished arith deob on " + total + " fields in " + passes + " passes"); } + private void translateSetFields(Execution e) + { + //Set visited = new HashSet<>(); + for (Frame f : e.processedFrames) + for (InstructionContext ins : f.getInstructions()) + if (ins.getInstruction() instanceof SetFieldInstruction) + { + SetFieldInstruction sfi = (SetFieldInstruction) ins.getInstruction(); + Pair pair = e.getEncryption().getField(sfi.getMyField()); + + if (pair != null) + PutStatic.translate(e.getEncryption(), pair, ins, new HashSet()); + // + } + } + + private void insertGetterSetterMuls(Encryption encr) + { + // after getfield insert imul * setter + // before setfield insert inul * getter + for (ClassFile cf : group.getClasses()) + for (Method m : cf.getMethods().getMethods()) + { + Code code = m.getCode(); + if (code == null) + continue; + + Instructions ins = code.getInstructions(); + List ilist = ins.getInstructions(); + + for (int i = 0; i < ilist.size(); ++i) + { + Instruction in = ilist.get(i); + + if (in instanceof SetFieldInstruction) + { + SetFieldInstruction sfi = (SetFieldInstruction) in; + Field f = sfi.getMyField(); + + if (f == null) + continue; + + Pair p = encr.getField(f); + if (p == null) + continue; + + // insert push getter + // insert imul + + ilist.add(i++, new LDC_W(ins, new net.runelite.deob.pool.Integer(p.getter))); + ilist.add(i++, new IMul(ins)); + } + else if (in instanceof GetFieldInstruction) + { + GetFieldInstruction sfi = (GetFieldInstruction) in; + Field f = sfi.getMyField(); + + if (f == null) + continue; + + Pair p = encr.getField(f); + if (p == null) + continue; + + // add after: push setter + // imul + ilist.add(++i, new LDC_W(ins, new net.runelite.deob.pool.Integer(p.setter))); + ilist.add(++i, new IMul(ins)); + } + } + } + } + private int runOnce() { group.buildClassGraph(); @@ -336,7 +415,10 @@ public class ModArith implements Deobfuscator { Field field = pair.field; - if (!field.getName().equals("field933") && !field.getName().equals("field743")) + //field933 = -193434591 * field743; + // var143.field3014 = (var143.field2960 = 1 * var92.field2960) * 1496783801; + //if (!field.getName().equals("field3014") && !field.getName().equals("field2960")) + if (!field.getName().equals("field2201")) { // continue; } @@ -346,19 +428,33 @@ public class ModArith implements Deobfuscator Encryption encr = new Encryption(); encr.addPair(pair); - execution = new Execution(group); - execution.populateInitialMethods(); - execution.setEncryption(encr); - execution.run(); + insertGetterSetterMuls(encr); +// +// execution = new Execution(group); +// execution.populateInitialMethods(); +// execution.setEncryption(encr); +// execution.run(); +// +// encr.doChange(); +// +// insertSetterMuls(encr); - encr.doChange(); +// execution = new Execution(group); +// execution.populateInitialMethods(); +// execution.run(); +// +// encr = new Encryption(); +// encr.addPair(pair); +// execution.setEncryption(encr); +// translateSetFields(execution); +// +// encr.doChange(); System.out.println("Changed " + ++i); //assert !deobfuscatedFields.contains(field); deobfuscatedFields.add(field); } - Encryption encr = new Encryption(); System.out.println(pairs); return i; diff --git a/src/main/java/net/runelite/deob/execution/Stack.java b/src/main/java/net/runelite/deob/execution/Stack.java index 0cde672b51..961d4725eb 100644 --- a/src/main/java/net/runelite/deob/execution/Stack.java +++ b/src/main/java/net/runelite/deob/execution/Stack.java @@ -9,7 +9,7 @@ public class Stack public Stack(int sz) { - stack = new StackContext[sz]; + stack = new StackContext[sz*2]; // XXX } protected Stack(Stack other)