From a826ac3c4725bd8425e2dc2895733e5666d9e6f3 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 12 Sep 2015 22:15:37 -0400 Subject: [PATCH] some guessing, fix dup stuff via magic --- .../code/instructions/PutField.java | 3 +- .../code/instructions/PutStatic.java | 40 ++++++--- .../deobfuscators/arithmetic/ModArith.java | 89 +++---------------- 3 files changed, 42 insertions(+), 90 deletions(-) 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 13e2552d19..e6f07617cd 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 @@ -16,6 +16,7 @@ import net.runelite.deob.pool.NameAndType; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.HashSet; import java.util.List; import net.runelite.deob.attributes.code.instruction.types.PushConstantInstruction; import static net.runelite.deob.attributes.code.instructions.PutStatic.translate; @@ -58,7 +59,7 @@ public class PutField extends Instruction implements SetFieldInstruction { Pair pair = encryption.getField(myField); if (pair != null) - translate(encryption, pair, ins); + 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 c600f80fbb..08c44a7cb5 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,8 +16,9 @@ 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.InvokeInstruction; +import java.util.HashSet; +import java.util.Set; +import net.runelite.deob.attributes.code.instruction.types.DupInstruction; import net.runelite.deob.attributes.code.instruction.types.PushConstantInstruction; import net.runelite.deob.deobfuscators.arithmetic.DMath; import net.runelite.deob.deobfuscators.arithmetic.Encryption; @@ -70,8 +71,13 @@ public class PutStatic extends Instruction implements SetFieldInstruction return null; } - protected static boolean translate(Encryption encryption, Pair pair, InstructionContext ctx) + protected 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) { LDC_W pci = (LDC_W) ctx.getInstruction(); @@ -90,21 +96,17 @@ public class PutStatic extends Instruction implements SetFieldInstruction return true; } -// if (ctx.getInstruction() instanceof InvokeInstruction) -// return false; -// -// if (ctx.getInstruction() instanceof IDiv) -// return false; - boolean ok = ctx.getInstruction() instanceof IAdd || ctx.getInstruction() instanceof ISub || ctx.getInstruction() instanceof IMul || - ctx.getInstruction() instanceof SetFieldInstruction; + ctx.getInstruction() instanceof SetFieldInstruction || + ctx.getInstruction() instanceof DupInstruction; if (!ok) return false; - boolean multipleBranches = ctx.getInstruction() instanceof IAdd || ctx.getInstruction() instanceof ISub; + boolean multipleBranches = ctx.getInstruction() instanceof IAdd || + ctx.getInstruction() instanceof ISub; boolean retVal = false; encryption.begin(); @@ -113,7 +115,7 @@ public class PutStatic extends Instruction implements SetFieldInstruction { InstructionContext i = sctx.getPushed(); - if (translate(encryption, pair, i)) + if (translate(encryption, pair, i, visited)) { retVal = true; @@ -135,6 +137,18 @@ 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; + } + return retVal; } @@ -153,7 +167,7 @@ public class PutStatic extends Instruction implements SetFieldInstruction { Pair pair = encryption.getField(myField); if (pair != null) - translate(encryption, pair, ins); + 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/ModArith.java b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java index f95a28441f..fd5b017150 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java @@ -113,15 +113,14 @@ public class ModArith implements Deobfuscator continue; List constants = null; -// try -// { -// constants = findAssocConstants(field, ctx); -// System.out.println(field.getName() + " " + constants); -// for (int i : constants) -// if (i != 1 && i != 0) -// constantSetters.put(field, i); -// } -// catch (OtherFieldException ex) { } + try + { + constants = findAssocConstants(field, ctx); + for (int i : constants) + if (i != 1 && i != 0) + constantSetters.put(field, i); + } + catch (OtherFieldException ex) { } StackContext value = ctx.getPops().get(0); // the first thing poppe from both putfield and putstatic is the value if (!(value.getPushed().getInstruction() instanceof IMul)) @@ -250,83 +249,21 @@ public class ModArith implements Deobfuscator Collection getters = constantGetters.getCollection(f), setters = constantSetters.getCollection(f); - if (f.getName().equals("field605")) - { - int i =4; - } - if (getters == null || setters == null) continue; Pair answer = reduce(getters, setters); if (answer == null) { - // answer = guess(getters); + answer = guess(getters); if (answer == null) continue; - - System.out.println("Guessing getter for " + f.getName() + " is " + answer.getter + " setter " + answer.setter); } answer.field = f; pairs.add(answer); } } - -// private List getFieldsInExpression(InstructionContext ctx, List constants) -// { -// return check(ctx, new HashSet(), constants); -// } -// -// private List check(InstructionContext context, Set visited, List constants) -// { -// List fields = new ArrayList<>(); -// -// if (visited.contains(context)) -// return fields; -// -// visited.add(context); -// -// if (context.getInstruction() instanceof InvokeInstruction) -// { -// // field = func(field * constant), the output of the function isn't directly related to the result of field * constant -// return fields; -// } -// -// if (context.getInstruction() instanceof FieldInstruction) -// { -// FieldInstruction fi = (FieldInstruction) context.getInstruction(); -// Field myf = fi.getMyField(); -// if (myf != null) -// fields.add(myf); -// } -// -// if (context.getInstruction() instanceof PushConstantInstruction) -// { -// PushConstantInstruction pci = (PushConstantInstruction) context.getInstruction(); -// int i = (int) pci.getConstant().getObject(); -// constants.add(i); -// } -// -// for (StackContext ctx : context.getPops()) -// { -// InstructionContext i = ctx.getPushed(); -// -// fields.addAll(check(i, visited, constants)); -// } -// -// for (StackContext ctx : context.getPushes()) -// { -// InstructionContext i = ctx.getPopped(); -// -// if (i == null) -// continue; -// -// fields.addAll(check(i, visited, constants)); -// } -// -// return fields; -// } @Override public void run(ClassGroup group) @@ -351,16 +288,16 @@ public class ModArith implements Deobfuscator reduce(); int i = 0; - int start = 0, end = pairs.size(); // 0-64 ok + int start = 0, end = pairs.size(); for (int j = start; j < end; ++j) //for (Pair pair : pairs) { Pair pair = pairs.get(j); Field field = pair.field; - - if (!field.getName().equals("field2982") && !field.getName().equals("field2963")) + + if (!field.getName().equals("field1980") && !field.getName().equals("field1961")) { - // continue; +// continue; } System.out.println("Processing " + field.getName() + " getter " + pair.getter + " setter " + pair.setter);