diff --git a/src/main/java/net/runelite/asm/execution/Execution.java b/src/main/java/net/runelite/asm/execution/Execution.java index 25d152f7da..23d6164bf9 100644 --- a/src/main/java/net/runelite/asm/execution/Execution.java +++ b/src/main/java/net/runelite/asm/execution/Execution.java @@ -22,7 +22,6 @@ public class Execution private MultiValueMap invokes = new MultiValueMap<>(); public boolean paused; public boolean step = false; - public boolean processInvokes = true; private List visitors = new ArrayList<>(); private List frameVisitors = new ArrayList<>(); private List methodContextVisitors = new ArrayList<>(); @@ -98,9 +97,6 @@ public class Execution if (step) // step executor return null; - if (!processInvokes) - return null; - if (hasInvoked(from, to)) return 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 071a4e6131..1039894abe 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java @@ -29,7 +29,6 @@ import net.runelite.asm.attributes.code.instructions.LDC2_W; import net.runelite.asm.attributes.code.instructions.LDC_W; import net.runelite.asm.attributes.code.instructions.LMul; import net.runelite.asm.execution.Execution; -import net.runelite.asm.execution.Frame; import net.runelite.asm.execution.InstructionContext; import net.runelite.asm.execution.StackContext; import net.runelite.asm.pool.PoolEntry; @@ -41,6 +40,7 @@ import net.runelite.asm.attributes.code.instructions.If; import net.runelite.asm.attributes.code.instructions.If0; import net.runelite.asm.attributes.code.instructions.LAdd; import net.runelite.asm.attributes.code.instructions.LCmp; +import net.runelite.asm.execution.MethodContext; import org.apache.commons.collections4.CollectionUtils; public class ModArith implements Deobfuscator @@ -82,128 +82,122 @@ public class ModArith implements Deobfuscator return l; } - private void findObfuscatedFields() + private void findObfuscatedFields(MethodContext mctx) { - // find a direct big*field with no other fields involved - obfuscatedFields.clear(); - - for (Frame f : execution.processedFrames) + for (InstructionContext ctx : mctx.getInstructionContexts()) { - for (InstructionContext ctx : f.getInstructions()) + if (ctx.getInstruction() instanceof SetFieldInstruction) { - if (ctx.getInstruction() instanceof SetFieldInstruction) - { - SetFieldInstruction sfi = (SetFieldInstruction) ctx.getInstruction(); - - InstructionContext pushedsfi = ctx.getPops().get(0).getPushed(); - pushedsfi = pushedsfi.resolve(ctx.getPops().get(0)); - 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) - { - 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 - || pushedsfi.getInstruction() instanceof IAdd || pushedsfi.getInstruction() instanceof LAdd) - { - Instruction one = pushedsfi.getPops().get(0).getPushed().getInstruction(); - Instruction two = pushedsfi.getPops().get(1).getPushed().getInstruction(); + SetFieldInstruction sfi = (SetFieldInstruction) ctx.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) + InstructionContext pushedsfi = ctx.getPops().get(0).getPushed(); + pushedsfi = pushedsfi.resolve(ctx.getPops().get(0)); + 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) + { + 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 + || pushedsfi.getInstruction() instanceof IAdd || pushedsfi.getInstruction() instanceof LAdd) + { + 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) + continue; + + if (other instanceof GetFieldInstruction) + { + GetFieldInstruction gfi = (GetFieldInstruction) other; + + if (gfi.getMyField() != sfi.getMyField()) continue; - - if (other instanceof GetFieldInstruction) - { - GetFieldInstruction gfi = (GetFieldInstruction) other; - - if (gfi.getMyField() != sfi.getMyField()) - continue; - } - - 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 - this.obfuscatedFields.add(sfi.getMyField()); - } } - } - - // field * imul - if (!(ctx.getInstruction() instanceof IMul) && !(ctx.getInstruction() instanceof LMul)) - continue; - - Instruction one = ctx.getPops().get(0).getPushed().getInstruction(); - Instruction two = ctx.getPops().get(1).getPushed().getInstruction(); - - PushConstantInstruction pc = null; - GetFieldInstruction other = null; - if ((one instanceof LDC_W || one instanceof LDC2_W) && two instanceof GetFieldInstruction) - { - pc = (PushConstantInstruction) one; - other = (GetFieldInstruction) two; - } - else if ((two instanceof LDC_W || two instanceof LDC2_W) && one instanceof GetFieldInstruction) - { - pc = (PushConstantInstruction) two; - other = (GetFieldInstruction) one; - } - if (pc == null || other == null) - { - continue; - } - - if (!(pc.getConstant().getObject() instanceof Integer) && !(pc.getConstant().getObject() instanceof Long)) - continue; - - Number ivalue = (Number) pc.getConstant().getObject(); - if (!DMath.isBig(ivalue)) - continue; - - try - { - MultiplicationExpression expr = MultiplicationDeobfuscator.parseExpression(execution, ctx, ctx.getInstruction().getClass()); - if (expr.hasFieldOtherThan(other.getMyField())) - continue; - } - catch (IllegalStateException ex) - { - continue; - } - - InstructionContext popped = ctx.getPushes().get(0).getPopped().isEmpty() ? null : ctx.getPushes().get(0).getPopped().get(0); - if (popped != null && popped.getInstruction() instanceof SetFieldInstruction) - { - SetFieldInstruction sfi = (SetFieldInstruction) popped.getInstruction(); - - if (sfi.getMyField() != null)// && sfi.getMyField() != field) + if (pci.getConstant().getObject() instanceof Integer || pci.getConstant().getObject() instanceof Long) { - continue; + Number i = (Number) pci.getConstant().getObject(); + if (DMath.isBig(i)) + // field = constant * not other field + this.obfuscatedFields.add(sfi.getMyField()); } } - - this.obfuscatedFields.add(other.getMyField()); } + + // field * imul + if (!(ctx.getInstruction() instanceof IMul) && !(ctx.getInstruction() instanceof LMul)) + continue; + + Instruction one = ctx.getPops().get(0).getPushed().getInstruction(); + Instruction two = ctx.getPops().get(1).getPushed().getInstruction(); + + PushConstantInstruction pc = null; + GetFieldInstruction other = null; + if ((one instanceof LDC_W || one instanceof LDC2_W) && two instanceof GetFieldInstruction) + { + pc = (PushConstantInstruction) one; + other = (GetFieldInstruction) two; + } + else if ((two instanceof LDC_W || two instanceof LDC2_W) && one instanceof GetFieldInstruction) + { + pc = (PushConstantInstruction) two; + other = (GetFieldInstruction) one; + } + + if (pc == null || other == null) + { + continue; + } + + if (!(pc.getConstant().getObject() instanceof Integer) && !(pc.getConstant().getObject() instanceof Long)) + continue; + + Number ivalue = (Number) pc.getConstant().getObject(); + if (!DMath.isBig(ivalue)) + continue; + + try + { + MultiplicationExpression expr = MultiplicationDeobfuscator.parseExpression(ctx, ctx.getInstruction().getClass()); + if (expr.hasFieldOtherThan(other.getMyField())) + continue; + } + catch (IllegalStateException ex) + { + continue; + } + + InstructionContext popped = ctx.getPushes().get(0).getPopped().isEmpty() ? null : ctx.getPushes().get(0).getPopped().get(0); + if (popped != null && popped.getInstruction() instanceof SetFieldInstruction) + { + SetFieldInstruction sfi = (SetFieldInstruction) popped.getInstruction(); + + if (sfi.getMyField() != null)// && sfi.getMyField() != field) + { + continue; + } + } + + this.obfuscatedFields.add(other.getMyField()); } } @@ -215,176 +209,174 @@ public class ModArith implements Deobfuscator } private MultiValueMap constants = new MultiValueMap(); - private void findUses2() + private void findUses2(MethodContext mctx) { - for (Frame f : execution.processedFrames) - for (InstructionContext ctx : f.getInstructions()) + for (InstructionContext ctx : mctx.getInstructionContexts()) + { + if (ctx.getInstruction() instanceof FieldInstruction) { - if (ctx.getInstruction() instanceof FieldInstruction) + FieldInstruction fi = (FieldInstruction) ctx.getInstruction(); + + if (fi.getMyField() == null) + continue; + + if ((!fi.getField().getNameAndType().getDescriptorType().getType().equals("I") + && !fi.getField().getNameAndType().getDescriptorType().getType().equals("J")) + || fi.getField().getNameAndType().getDescriptorType().getArrayDims() != 0) + continue; + + List l = this.getInsInExpr(ctx, new HashSet()); + boolean other = false; // check if this contains another field + for (InstructionContext i : l) { - FieldInstruction fi = (FieldInstruction) ctx.getInstruction(); - - if (fi.getMyField() == null) - continue; - - if ((!fi.getField().getNameAndType().getDescriptorType().getType().equals("I") - && !fi.getField().getNameAndType().getDescriptorType().getType().equals("J")) - || fi.getField().getNameAndType().getDescriptorType().getArrayDims() != 0) - continue; - - List l = this.getInsInExpr(ctx, new HashSet()); - boolean other = false; // check if this contains another field - for (InstructionContext i : l) + if (i.getInstruction() instanceof FieldInstruction) { - if (i.getInstruction() instanceof FieldInstruction) - { - FieldInstruction fi2 = (FieldInstruction) i.getInstruction(); - Field myField = fi2.getMyField(); - - if (myField != null && myField != fi.getMyField()) - { - Type t = myField.getType(); - if (t.equals(fi.getMyField().getType())) - { - other = true; - } - } - } - } + FieldInstruction fi2 = (FieldInstruction) i.getInstruction(); + Field myField = fi2.getMyField(); - boolean constant = false; - if (fi instanceof SetFieldInstruction) - { - InstructionContext pushedsfi = ctx.getPops().get(0).getPushed(); // value being set - pushedsfi = pushedsfi.resolve(ctx.getPops().get(0)); - - if (pushedsfi.getInstruction() instanceof LDC_W || pushedsfi.getInstruction() instanceof LDC2_W) + if (myField != null && myField != fi.getMyField()) { - constant = true; - } - } - - for (InstructionContext i : l) - { - if (i.getInstruction() instanceof LDC_W || i.getInstruction() instanceof LDC2_W) - { - PushConstantInstruction w = (PushConstantInstruction) i.getInstruction(); - if (w.getConstant().getObject() instanceof Integer || w.getConstant().getObject() instanceof Long) + Type t = myField.getType(); + if (t.equals(fi.getMyField().getType())) { - AssociatedConstant n = new AssociatedConstant(); - n.value = (Number) w.getConstant().getObject(); - n.other = other; - n.constant = constant; - constants.put(fi.getMyField(), n); + other = true; } } } } - } - } - private void findUses() - { - for (Frame f : execution.processedFrames) - for (InstructionContext ctx : f.getInstructions()) - { - if (ctx.getInstruction() instanceof IMul || ctx.getInstruction() instanceof LMul) + boolean constant = false; + if (fi instanceof SetFieldInstruction) { - 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(); - if (field == null) - continue; - - Number value = (Number) pc.getConstant().getObject(); - - if (DMath.equals(value, 1) || DMath.equals(value, 0)) - continue; - - // field * constant - constantGetters.put(field, value); - } - else if (ctx.getInstruction() instanceof SetFieldInstruction) - { - SetFieldInstruction sf = (SetFieldInstruction) ctx.getInstruction(); - - Field field = sf.getMyField(); - if (field == null) - continue; - InstructionContext pushedsfi = ctx.getPops().get(0).getPushed(); // value being set pushedsfi = pushedsfi.resolve(ctx.getPops().get(0)); - if (!(pushedsfi.getInstruction() instanceof IMul) && !(pushedsfi.getInstruction() instanceof LMul) - && !(pushedsfi.getInstruction() instanceof IAdd) && !(pushedsfi.getInstruction() instanceof LAdd)) + if (pushedsfi.getInstruction() instanceof LDC_W || pushedsfi.getInstruction() instanceof LDC2_W) { - 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) - { - Number i = (Number) ldc.getConstant().getObject(); - - if (DMath.isBig(i)) - // field = constant - constantSetters.put(field, i); - } - } - continue; + constant = true; } - - Instruction one = pushedsfi.getPops().get(0).getPushed().getInstruction(); - Instruction two = pushedsfi.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; - - Number value2 = (Number) pc.getConstant().getObject(); - - if (DMath.equals(value2, 1) || DMath.equals(value2, 0)) - continue; + } - if (pushedsfi.getInstruction() instanceof IAdd || pushedsfi.getInstruction() instanceof LAdd) + for (InstructionContext i : l) + { + if (i.getInstruction() instanceof LDC_W || i.getInstruction() instanceof LDC2_W) { - if (!DMath.isBig(value2)) - continue; + PushConstantInstruction w = (PushConstantInstruction) i.getInstruction(); + if (w.getConstant().getObject() instanceof Integer || w.getConstant().getObject() instanceof Long) + { + AssociatedConstant n = new AssociatedConstant(); + n.value = (Number) w.getConstant().getObject(); + n.other = other; + n.constant = constant; + constants.put(fi.getMyField(), n); + } } - - // field = something * constant - constantSetters.put(field, value2); } } + } + } + + private void findUses(MethodContext mctx) + { + for (InstructionContext ctx : mctx.getInstructionContexts()) + { + if (ctx.getInstruction() instanceof IMul || ctx.getInstruction() instanceof LMul) + { + 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(); + if (field == null) + continue; + + Number value = (Number) pc.getConstant().getObject(); + + if (DMath.equals(value, 1) || DMath.equals(value, 0)) + continue; + + // field * constant + constantGetters.put(field, value); + } + else if (ctx.getInstruction() instanceof SetFieldInstruction) + { + SetFieldInstruction sf = (SetFieldInstruction) ctx.getInstruction(); + + Field field = sf.getMyField(); + if (field == null) + continue; + + InstructionContext pushedsfi = ctx.getPops().get(0).getPushed(); // value being set + pushedsfi = pushedsfi.resolve(ctx.getPops().get(0)); + + if (!(pushedsfi.getInstruction() instanceof IMul) && !(pushedsfi.getInstruction() instanceof LMul) + && !(pushedsfi.getInstruction() instanceof IAdd) && !(pushedsfi.getInstruction() instanceof LAdd)) + { + 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) + { + Number i = (Number) ldc.getConstant().getObject(); + + if (DMath.isBig(i)) + // field = constant + constantSetters.put(field, i); + } + } + continue; + } + + Instruction one = pushedsfi.getPops().get(0).getPushed().getInstruction(); + Instruction two = pushedsfi.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; + + Number value2 = (Number) pc.getConstant().getObject(); + + if (DMath.equals(value2, 1) || DMath.equals(value2, 0)) + continue; + + if (pushedsfi.getInstruction() instanceof IAdd || pushedsfi.getInstruction() instanceof LAdd) + { + if (!DMath.isBig(value2)) + continue; + } + + // field = something * constant + constantSetters.put(field, value2); + } + } } private Pair guess(Field field, Collection constants) @@ -708,14 +700,20 @@ public class ModArith implements Deobfuscator constantGetters.clear(); constantSetters.clear(); constants.clear(); + + // find a direct big*field with no other fields involved + obfuscatedFields.clear(); execution = new Execution(group); + execution.addMethodContextVisitor(i -> findObfuscatedFields(i)); + execution.addMethodContextVisitor(i -> findUses(i)); + execution.addMethodContextVisitor(i -> findUses2(i)); execution.populateInitialMethods(); execution.run(); - findObfuscatedFields(); - findUses(); - findUses2(); +// findObfuscatedFields(); +// findUses(); +// findUses2(); reduce2(); int i = 0; diff --git a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/MultiplicationDeobfuscator.java b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/MultiplicationDeobfuscator.java index a2f01960e2..b9224fbaf2 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/MultiplicationDeobfuscator.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/MultiplicationDeobfuscator.java @@ -4,10 +4,8 @@ import java.util.Collection; import java.util.HashSet; import java.util.Set; import net.runelite.asm.ClassGroup; -import net.runelite.asm.Method; import net.runelite.deob.Deobfuscator; import net.runelite.asm.attributes.code.Instruction; -import net.runelite.asm.attributes.code.Instructions; import net.runelite.asm.attributes.code.instruction.types.DupInstruction; import net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction; import net.runelite.asm.attributes.code.instruction.types.LVTInstruction; @@ -25,7 +23,6 @@ import net.runelite.asm.attributes.code.instructions.LMul; import net.runelite.asm.attributes.code.instructions.LSub; import net.runelite.asm.attributes.code.instructions.SiPush; import net.runelite.asm.execution.Execution; -import net.runelite.asm.execution.Frame; import net.runelite.asm.execution.InstructionContext; import net.runelite.asm.execution.MethodContext; import net.runelite.asm.execution.StackContext; @@ -245,7 +242,6 @@ public class MultiplicationDeobfuscator implements Deobfuscator { assert ctx.getInstruction() instanceof IMul || ctx.getInstruction() instanceof LMul; - // XXX this needs to be all in all frames Collection ins = ctx.getFrame().getMethodCtx().getInstructonContexts(ctx.getInstruction()); for (InstructionContext i : ins) { @@ -346,7 +342,6 @@ public class MultiplicationDeobfuscator implements Deobfuscator count = 0; Execution e = new Execution(group); - //e.addFrameVisitor(f -> visit(f)); e.addMethodContextVisitor(m -> visit(m)); e.populateInitialMethods(); e.run(); diff --git a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/MultiplyOneDeobfuscator.java b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/MultiplyOneDeobfuscator.java index 4413dbae94..6f19d91a63 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/MultiplyOneDeobfuscator.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/MultiplyOneDeobfuscator.java @@ -1,6 +1,5 @@ package net.runelite.deob.deobfuscators.arithmetic; -import java.util.ArrayList; import java.util.List; import net.runelite.asm.ClassGroup; import net.runelite.deob.Deobfuscator; @@ -11,100 +10,77 @@ import net.runelite.asm.attributes.code.instructions.IMul; import net.runelite.asm.attributes.code.instructions.LMul; import net.runelite.asm.attributes.code.instructions.NOP; import net.runelite.asm.execution.Execution; -import net.runelite.asm.execution.Frame; import net.runelite.asm.execution.InstructionContext; +import net.runelite.asm.execution.MethodContext; import net.runelite.asm.execution.StackContext; -class MPair -{ - int removeIdx; - InstructionContext ctx; - - public MPair(int removeIdx, InstructionContext ctx) - { - this.removeIdx = removeIdx; - this.ctx = ctx; - } -} - public class MultiplyOneDeobfuscator implements Deobfuscator { private int count; - private List pairs = new ArrayList<>(); - private void visit(InstructionContext ictx) + private void visit(MethodContext mctx) { - Instruction instruction = ictx.getInstruction(); - - if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) + for (InstructionContext ictx : mctx.getInstructionContexts()) { - return; - } + Instruction instruction = ictx.getInstruction(); - Instructions ins = ictx.getInstruction().getInstructions(); - if (ins == null) - { - return; - } - - List ilist = ins.getInstructions(); - - if (!ilist.contains(ictx.getInstruction())) - { - return; // already done - } - StackContext one = ictx.getPops().get(0); - StackContext two = ictx.getPops().get(1); - - int removeIdx = -1; - if (one.getPushed().getInstruction() instanceof PushConstantInstruction - && DMath.equals((Number) ((PushConstantInstruction) one.getPushed().getInstruction()).getConstant().getObject(), 1)) - { - removeIdx = 0; - } - else if (two.getPushed().getInstruction() instanceof PushConstantInstruction - && DMath.equals((Number) ((PushConstantInstruction) two.getPushed().getInstruction()).getConstant().getObject(), 1)) - { - removeIdx = 1; - } - - if (removeIdx == -1) - { - return; - } - - pairs.add(new MPair(removeIdx, ictx)); - - ++count; - } - - private void visit(Frame f) - { - for (MPair p : pairs) - { - StackContext one = p.ctx.getPops().get(0); - StackContext two = p.ctx.getPops().get(1); - - if (!MultiplicationDeobfuscator.isOnlyPath(p.ctx, p.removeIdx == 0 ? one : two)) + if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) { continue; } - - p.ctx.removeStack(p.removeIdx); - p.ctx.getInstruction().getInstructions().replace(p.ctx.getInstruction(), new NOP(p.ctx.getInstruction().getInstructions())); + + Instructions ins = ictx.getInstruction().getInstructions(); + if (ins == null) + { + continue; + } + + List ilist = ins.getInstructions(); + + if (!ilist.contains(ictx.getInstruction())) + { + continue; // already done + } + StackContext one = ictx.getPops().get(0); + StackContext two = ictx.getPops().get(1); + + int removeIdx = -1; + if (one.getPushed().getInstruction() instanceof PushConstantInstruction + && DMath.equals((Number) ((PushConstantInstruction) one.getPushed().getInstruction()).getConstant().getObject(), 1)) + { + removeIdx = 0; + } + else if (two.getPushed().getInstruction() instanceof PushConstantInstruction + && DMath.equals((Number) ((PushConstantInstruction) two.getPushed().getInstruction()).getConstant().getObject(), 1)) + { + removeIdx = 1; + } + + if (removeIdx == -1) + { + continue; + } + + if (!MultiplicationDeobfuscator.isOnlyPath(ictx, removeIdx == 0 ? one : two)) + { + continue; + } + + ictx.removeStack(removeIdx); + ins.replace(ictx.getInstruction(), new NOP(ins)); + + ++count; } - pairs.clear(); } - + @Override public void run(ClassGroup group) { Execution e = new Execution(group); - e.addExecutionVisitor(i -> visit(i)); - e.addFrameVisitor(v -> visit(v)); + e.addMethodContextVisitor(i -> visit(i)); e.populateInitialMethods(); e.run(); - + System.out.println("Removed " + count + " 1 multiplications"); } diff --git a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/MultiplyZeroDeobfuscator.java b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/MultiplyZeroDeobfuscator.java index d05fd414f7..ea9621d156 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/MultiplyZeroDeobfuscator.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/MultiplyZeroDeobfuscator.java @@ -1,6 +1,5 @@ package net.runelite.deob.deobfuscators.arithmetic; -import java.util.ArrayList; import java.util.List; import net.runelite.asm.ClassGroup; import net.runelite.deob.Deobfuscator; @@ -12,86 +11,74 @@ import net.runelite.asm.attributes.code.instructions.LDC2_W; import net.runelite.asm.attributes.code.instructions.LDC_W; import net.runelite.asm.attributes.code.instructions.LMul; import net.runelite.asm.execution.Execution; -import net.runelite.asm.execution.Frame; import net.runelite.asm.execution.InstructionContext; +import net.runelite.asm.execution.MethodContext; import net.runelite.asm.execution.StackContext; public class MultiplyZeroDeobfuscator implements Deobfuscator { private int count; - private List pending = new ArrayList<>(); - - private void visit(InstructionContext ictx) + + private void visit(MethodContext mctx) { - Instruction instruction = ictx.getInstruction(); - Instructions ins = instruction.getInstructions(); - if (ins == null) - { - return; - } - - if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) - { - return; - } - - List ilist = ins.getInstructions(); - - StackContext one = ictx.getPops().get(0); - StackContext two = ictx.getPops().get(1); - - Instruction ione = one.getPushed().getInstruction(), - itwo = two.getPushed().getInstruction(); - - boolean remove = false; - if (ione instanceof PushConstantInstruction) - { - PushConstantInstruction pci = (PushConstantInstruction) ione; - Number value = (Number) pci.getConstant().getObject(); - - if (DMath.equals(value, 0)) - { - remove = true; - } - } - if (itwo instanceof PushConstantInstruction) - { - PushConstantInstruction pci = (PushConstantInstruction) itwo; - Number value = (Number) pci.getConstant().getObject(); - - if (DMath.equals(value, 0)) - { - remove = true; - } - } - - if (remove == false) - { - return; - } - - if (!ilist.contains(instruction)) - { - return; // already done - } - - pending.add(ictx); - - ++count; - } - - private void visit(Frame frame) - { - for (InstructionContext ictx : pending) + for (InstructionContext ictx : mctx.getInstructionContexts()) { Instruction instruction = ictx.getInstruction(); Instructions ins = instruction.getInstructions(); - + if (ins == null) + { + continue; + } + + if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) + { + continue; + } + + List ilist = ins.getInstructions(); + + StackContext one = ictx.getPops().get(0); + StackContext two = ictx.getPops().get(1); + + Instruction ione = one.getPushed().getInstruction(), + itwo = two.getPushed().getInstruction(); + + boolean remove = false; + if (ione instanceof PushConstantInstruction) + { + PushConstantInstruction pci = (PushConstantInstruction) ione; + Number value = (Number) pci.getConstant().getObject(); + + if (DMath.equals(value, 0)) + { + remove = true; + } + } + if (itwo instanceof PushConstantInstruction) + { + PushConstantInstruction pci = (PushConstantInstruction) itwo; + Number value = (Number) pci.getConstant().getObject(); + + if (DMath.equals(value, 0)) + { + remove = true; + } + } + + if (remove == false) + { + continue; + } + + if (!ilist.contains(instruction)) + { + continue; // already done + } if (!MultiplicationDeobfuscator.isOnlyPath(ictx, null)) { continue; } - + // remove both, remove imul, push 0 ictx.removeStack(1); ictx.removeStack(0); @@ -108,16 +95,17 @@ public class MultiplyZeroDeobfuscator implements Deobfuscator { throw new IllegalStateException(); } + + ++count; + } - pending.clear(); } @Override public void run(ClassGroup group) { Execution e = new Execution(group); - e.addExecutionVisitor(i -> visit(i)); - e.addFrameVisitor(v -> visit(v)); + e.addMethodContextVisitor(i -> visit(i)); e.populateInitialMethods(); e.run(); diff --git a/src/test/java/net/runelite/deob/deobfuscators/arithmetic/MultiplicationDeobfuscatorTest.java b/src/test/java/net/runelite/deob/deobfuscators/arithmetic/MultiplicationDeobfuscatorTest.java index 0b77d861f5..eaf9a50750 100644 --- a/src/test/java/net/runelite/deob/deobfuscators/arithmetic/MultiplicationDeobfuscatorTest.java +++ b/src/test/java/net/runelite/deob/deobfuscators/arithmetic/MultiplicationDeobfuscatorTest.java @@ -1,6 +1,5 @@ package net.runelite.deob.deobfuscators.arithmetic; -import java.util.Collection; import net.runelite.asm.ClassGroup; import net.runelite.deob.ClassGroupFactory; import net.runelite.deob.Deobfuscator; @@ -32,7 +31,6 @@ import net.runelite.asm.attributes.code.instructions.NOP; import net.runelite.asm.attributes.code.instructions.Pop; import net.runelite.asm.attributes.code.instructions.VReturn; import net.runelite.asm.execution.Execution; -import net.runelite.asm.execution.InstructionContext; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/net/runelite/deob/deobfuscators/arithmetic/MultiplyZeroDeobfuscatorTest.java b/src/test/java/net/runelite/deob/deobfuscators/arithmetic/MultiplyZeroDeobfuscatorTest.java index ce67c9aef0..3ff2da76d4 100644 --- a/src/test/java/net/runelite/deob/deobfuscators/arithmetic/MultiplyZeroDeobfuscatorTest.java +++ b/src/test/java/net/runelite/deob/deobfuscators/arithmetic/MultiplyZeroDeobfuscatorTest.java @@ -3,31 +3,8 @@ package net.runelite.deob.deobfuscators.arithmetic; import java.io.File; import java.io.IOException; import net.runelite.asm.ClassGroup; -import net.runelite.deob.ClassGroupFactory; -import net.runelite.deob.Deobfuscator; -import net.runelite.asm.attributes.Code; -import net.runelite.asm.attributes.code.Instruction; -import net.runelite.asm.attributes.code.Instructions; -import net.runelite.asm.attributes.code.instructions.Goto; -import net.runelite.asm.attributes.code.instructions.IConst_1; -import net.runelite.asm.attributes.code.instructions.IConst_2; -import net.runelite.asm.attributes.code.instructions.IConst_3; -import net.runelite.asm.attributes.code.instructions.IConst_M1; -import net.runelite.asm.attributes.code.instructions.IDiv; -import net.runelite.asm.attributes.code.instructions.ILoad; -import net.runelite.asm.attributes.code.instructions.IMul; -import net.runelite.asm.attributes.code.instructions.IStore_0; -import net.runelite.asm.attributes.code.instructions.IStore_1; -import net.runelite.asm.attributes.code.instructions.IfEq; -import net.runelite.asm.attributes.code.instructions.IfICmpEq; -import net.runelite.asm.attributes.code.instructions.LDC_W; -import net.runelite.asm.attributes.code.instructions.NOP; -import net.runelite.asm.attributes.code.instructions.SiPush; -import net.runelite.asm.attributes.code.instructions.VReturn; -import net.runelite.asm.execution.Execution; import net.runelite.deob.util.JarUtil; import org.junit.After; -import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -35,7 +12,7 @@ import org.junit.rules.TemporaryFolder; public class MultiplyZeroDeobfuscatorTest { - private static final File GAMEPACK = new File("c:/rs/gamepack_v19.jar"); + private static final File GAMEPACK = new File("d:/rs/07/gamepack_v19.jar"); @Rule public TemporaryFolder folder = new TemporaryFolder();