From 9b4230154cbc48575f875d4927325c992b7b9b49 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 12 Aug 2015 18:01:12 -0400 Subject: [PATCH] Use instruction ctx to see if a jump has already happened. Not sure if it works but it runs. --- src/main/java/info/sigterm/deob/Deob.java | 10 ++-- .../attributes/code/instructions/AThrow.java | 2 + .../code/instructions/CheckCast.java | 51 +++++------------- .../attributes/code/instructions/Goto.java | 8 ++- .../attributes/code/instructions/GotoW.java | 8 ++- .../deob/attributes/code/instructions/If.java | 2 +- .../attributes/code/instructions/If0.java | 2 +- .../code/instructions/LookupSwitch.java | 4 +- .../attributes/code/instructions/Pop.java | 9 +++- .../code/instructions/TableSwitch.java | 4 +- .../attributes/code/instructions/VReturn.java | 4 ++ .../attributes/code/instructions/Wide.java | 9 +++- .../deob/deobfuscators/ConstantParameter.java | 2 +- .../info/sigterm/deob/execution/Frame.java | 54 ++++++------------- .../deob/execution/InstructionContext.java | 35 ++++++++++++ .../sigterm/deob/execution/StackContext.java | 8 +-- 16 files changed, 114 insertions(+), 98 deletions(-) diff --git a/src/main/java/info/sigterm/deob/Deob.java b/src/main/java/info/sigterm/deob/Deob.java index defa7f1755..c76916186d 100644 --- a/src/main/java/info/sigterm/deob/Deob.java +++ b/src/main/java/info/sigterm/deob/Deob.java @@ -59,11 +59,11 @@ public class Deob bdur = System.currentTimeMillis() - bstart; System.out.println("illegal state exception took " + bdur/1000L + " seconds"); -// // remove constant logically dead parameters -// bstart = System.currentTimeMillis(); -// new ConstantParameter().run(group); -// bdur = System.currentTimeMillis() - bstart; -// System.out.println("constant param took " + bdur/1000L + " seconds"); + // remove constant logically dead parameters + bstart = System.currentTimeMillis(); + new ConstantParameter().run(group); + bdur = System.currentTimeMillis() - bstart; + System.out.println("constant param took " + bdur/1000L + " seconds"); // // remove unhit blocks // bstart = System.currentTimeMillis(); diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/AThrow.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/AThrow.java index e443284eee..ff83db2742 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/AThrow.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/AThrow.java @@ -29,6 +29,8 @@ public class AThrow extends Instruction StackContext exception = stack.pop(); ins.pop(exception); + frame.addInstructionContext(ins); + frame.stop(); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/CheckCast.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/CheckCast.java index 0f9b279949..f4ba4a17d5 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/CheckCast.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/CheckCast.java @@ -37,43 +37,20 @@ public class CheckCast extends Instruction @Override public void execute(Frame frame) - { - // jump to instruction handlers that can catch exceptions here - for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions()) - { - int startIdx = this.getInstructions().getInstructions().indexOf(e.getStart()), - endIdx = this.getInstructions().getInstructions().indexOf(e.getEnd()), - thisIdx = this.getInstructions().getInstructions().indexOf(this); - - assert startIdx != -1; - assert endIdx != -1; - assert thisIdx != -1; - - // [start, end) - if (thisIdx >= startIdx && thisIdx < endIdx) - { - Frame f = frame.dup(); - Stack stack = f.getStack(); - - InstructionContext ins = new InstructionContext(this, f); - - while (stack.getSize() > 0) - { - StackContext what = stack.pop(); - ins.pop(what); - } - - // push exception back - StackContext exception = new StackContext(ins, new Type("java/lang/Exception")); - stack.push(exception); - - ins.push(exception); - - f.addInstructionContext(ins); - - f.jump(e.getHandler()); - } - } + { + InstructionContext ins = new InstructionContext(this, frame); + Stack stack = frame.getStack(); + + StackContext value = stack.pop(); + + ins.pop(value); + + StackContext ctx = new StackContext(ins, value.getType()); + stack.push(ctx); + + ins.push(ctx); + + frame.addInstructionContext(ins); } @Override diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/Goto.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/Goto.java index 2af510450b..d3cfe12b35 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/Goto.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/Goto.java @@ -5,6 +5,7 @@ import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction; import info.sigterm.deob.execution.Frame; +import info.sigterm.deob.execution.InstructionContext; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -62,9 +63,12 @@ public class Goto extends Instruction implements JumpingInstruction } @Override - public void execute(Frame e) + public void execute(Frame frame) { - e.jump(to); + InstructionContext ctx = new InstructionContext(this, frame); + frame.addInstructionContext(ctx); + + frame.jump(ctx, to); } @Override diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/GotoW.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/GotoW.java index 05f996b58b..02ce1992f2 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/GotoW.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/GotoW.java @@ -5,6 +5,7 @@ import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction; import info.sigterm.deob.execution.Frame; +import info.sigterm.deob.execution.InstructionContext; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -46,9 +47,12 @@ public class GotoW extends Instruction implements JumpingInstruction } @Override - public void execute(Frame e) + public void execute(Frame frame) { - e.jump(to); + InstructionContext ctx = new InstructionContext(this, frame); + frame.addInstructionContext(ctx); + + frame.jump(ctx, to); } @Override diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/If.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/If.java index 3538ecb99b..c11186901d 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/If.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/If.java @@ -63,7 +63,7 @@ public class If extends Instruction implements JumpingInstruction, ComparisonIns frame.addInstructionContext(ins); Frame other = frame.dup(); - other.jump(to); + other.jump(ins, to); } @Override diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/If0.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/If0.java index b53f2d8c09..b03ac3135e 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/If0.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/If0.java @@ -64,7 +64,7 @@ public class If0 extends Instruction implements JumpingInstruction, ComparisonIn frame.addInstructionContext(ins); Frame other = frame.dup(); - other.jump(to); + other.jump(ins, to); } @Override diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LookupSwitch.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LookupSwitch.java index 0b83e21ccc..c1bfe7edbd 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LookupSwitch.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LookupSwitch.java @@ -111,10 +111,10 @@ public class LookupSwitch extends Instruction implements JumpingInstruction for (Instruction i : branchi) { Frame other = frame.dup(); - other.jump(i); + other.jump(ins, i); } - frame.jump(defi); + frame.jump(ins, defi); } @Override diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/Pop.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/Pop.java index c2282c1ab2..bb7cb8283c 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/Pop.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/Pop.java @@ -4,6 +4,8 @@ import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.execution.Frame; +import info.sigterm.deob.execution.InstructionContext; +import info.sigterm.deob.execution.StackContext; import java.io.IOException; @@ -17,6 +19,11 @@ public class Pop extends Instruction @Override public void execute(Frame frame) { - frame.getStack().pop(); + InstructionContext ins = new InstructionContext(this, frame); + + StackContext value = frame.getStack().pop(); + ins.pop(value); + + frame.addInstructionContext(ins); } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/TableSwitch.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/TableSwitch.java index cfed4fc342..83b8a7a947 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/TableSwitch.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/TableSwitch.java @@ -107,10 +107,10 @@ public class TableSwitch extends Instruction implements JumpingInstruction for (Instruction i : branchi) { Frame other = frame.dup(); - other.jump(i); + other.jump(ins, i); } - frame.jump(defi); + frame.jump(ins, defi); } @Override diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/VReturn.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/VReturn.java index 3e448a6505..ae110b4322 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/VReturn.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/VReturn.java @@ -5,6 +5,7 @@ import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.instruction.types.ReturnInstruction; import info.sigterm.deob.execution.Frame; +import info.sigterm.deob.execution.InstructionContext; import java.io.IOException; @@ -18,6 +19,9 @@ public class VReturn extends Instruction implements ReturnInstruction @Override public void execute(Frame frame) { + InstructionContext ins = new InstructionContext(this, frame); + frame.addInstructionContext(ins); + frame.stop(); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/Wide.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/Wide.java index 38f5791e3c..a79da0def1 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/Wide.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/Wide.java @@ -6,6 +6,7 @@ import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.instruction.types.LVTInstruction; import info.sigterm.deob.attributes.code.instruction.types.WideInstruction; import info.sigterm.deob.execution.Frame; +import info.sigterm.deob.execution.InstructionContext; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -47,9 +48,13 @@ public class Wide extends Instruction implements LVTInstruction } @Override - public void execute(Frame e) + public void execute(Frame frame) { - ins.execute(e); + InstructionContext ctx = new InstructionContext(this, frame); + + ins.execute(frame); + + frame.addInstructionContext(ctx); } @Override diff --git a/src/main/java/info/sigterm/deob/deobfuscators/ConstantParameter.java b/src/main/java/info/sigterm/deob/deobfuscators/ConstantParameter.java index 90bfdd0b2a..b48244c0b2 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/ConstantParameter.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/ConstantParameter.java @@ -131,7 +131,7 @@ public class ConstantParameter implements Deobfuscator { PushConstantInstruction pc = (PushConstantInstruction) ctx.getPushed().getInstruction(); - if (!(pc.getConstant().getObject() instanceof Integer) && (!(pc.getConstant().getObject() instanceof Byte))) + if (!(pc.getConstant().getObject() instanceof Number)) continue; ConstantMethodParameter cmp = new ConstantMethodParameter(); diff --git a/src/main/java/info/sigterm/deob/execution/Frame.java b/src/main/java/info/sigterm/deob/execution/Frame.java index 88dd1419d8..71d9f7d203 100644 --- a/src/main/java/info/sigterm/deob/execution/Frame.java +++ b/src/main/java/info/sigterm/deob/execution/Frame.java @@ -13,6 +13,8 @@ import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.instructions.LookupSwitch; import info.sigterm.deob.attributes.code.instructions.TableSwitch; import info.sigterm.deob.pool.NameAndType; +import org.apache.commons.collections4.MultiMap; +import org.apache.commons.collections4.map.MultiValueMap; public class Frame { @@ -23,7 +25,7 @@ public class Frame private Stack stack; private Variables variables; private List instructions = new ArrayList<>(); // instructions executed in this frame - private Map> visited; // shared + private MultiValueMap visited = new MultiValueMap<>(); // shared public Frame(Execution execution, Method method) { @@ -35,8 +37,6 @@ public class Frame stack = new Stack(code.getMaxStack()); variables = new Variables(code.getMaxLocals()); - visited = new HashMap<>(); - // initialize LVT int pos = 0; if (!method.isStatic()) @@ -60,7 +60,11 @@ public class Frame this.cur = other.cur; this.stack = new Stack(other.stack); this.variables = new Variables(other.variables); + //this.instructions = new ArrayList<>(other.instructions); // deep? this.visited = other.visited; + +// for (InstructionContext ctx : other.instructions) +// instructions.add(new InstructionContext(other, ctx)); } public Frame dup() @@ -160,16 +164,14 @@ public class Frame private void processExceptions(Instruction i) { Code code = method.getCode(); + InstructionContext ictx = instructions.get(instructions.size() - 1); + + assert ictx.getInstruction() == i; for (Exception e : code.getExceptions().getExceptions()) { if (e.getStart() == i) { - if (hasJumped(i, e.getHandler())) - continue; - - doJump(i, e.getHandler()); - Frame f = dup(); Stack stack = f.getStack(); @@ -182,57 +184,33 @@ public class Frame ins.push(ctx); - // at this point maybe cur != i, and f.jump() uses cur, so - f.cur = e.getHandler(); - assert f.executing; + f.jump(ictx, e.getHandler()); } } } - private void doJump(Instruction from, Instruction to) + private boolean hasJumped(InstructionContext from, Instruction to) { - List l = visited.get(from); - if (l == null) - { - List l2 = new ArrayList<>(); - l2.add(to); - visited.put(from, l2); - } - else - { - l.add(to); - } - } - - private boolean hasJumped(Instruction from, Instruction to) - { - List i = visited.get(from); + Collection i = visited.getCollection(from); if (i != null && i.contains(to)) return true; - if (i == null) - { - i = new ArrayList<>(); - visited.put(from, i); - } - - i.add(to); + visited.put(from, to); return false; } - public void jump(Instruction to) + public void jump(InstructionContext from, Instruction to) { assert to != null; assert to.getInstructions() == method.getCode().getInstructions(); assert method.getCode().getInstructions().getInstructions().contains(to); - if (hasJumped(cur, to)) + if (hasJumped(from, to)) { executing = false; return; } - doJump(cur, to); cur = to; } } diff --git a/src/main/java/info/sigterm/deob/execution/InstructionContext.java b/src/main/java/info/sigterm/deob/execution/InstructionContext.java index cfcb7779cb..540426dbf7 100644 --- a/src/main/java/info/sigterm/deob/execution/InstructionContext.java +++ b/src/main/java/info/sigterm/deob/execution/InstructionContext.java @@ -5,6 +5,7 @@ import java.util.List; import info.sigterm.deob.Method; import info.sigterm.deob.attributes.code.Instruction; +import java.util.Objects; public class InstructionContext { @@ -77,4 +78,38 @@ public class InstructionContext // start recursively removing ctx.removeStack(); } + + @Override + public boolean equals(Object other) + { + if (!(other instanceof InstructionContext)) + return false; + + InstructionContext ic = (InstructionContext) other; + + if (ins != ic.ins) + return false; + + if (getPops().size() != ic.getPops().size()) + return false; + + for (int i = 0; i < getPops().size(); ++i) + { + StackContext ours = getPops().get(i), + theirs = ic.getPops().get(i); + + if (!ours.getPushed().equals(theirs.getPushed())) + return false; + } + + return true; + } + + @Override + public int hashCode() + { + int hash = 7; + hash = 73 * hash + Objects.hashCode(this.ins); + return hash; + } } diff --git a/src/main/java/info/sigterm/deob/execution/StackContext.java b/src/main/java/info/sigterm/deob/execution/StackContext.java index a35ebe6e78..a8b9d6ba49 100644 --- a/src/main/java/info/sigterm/deob/execution/StackContext.java +++ b/src/main/java/info/sigterm/deob/execution/StackContext.java @@ -2,9 +2,9 @@ package info.sigterm.deob.execution; public class StackContext { - private InstructionContext pushed; // instruction which pushed this - private InstructionContext popped; // instruction which popped this - private Type type; // type of this + public InstructionContext pushed; // instruction which pushed this + public InstructionContext popped; // instruction which popped this + public Type type; // type of this public StackContext(InstructionContext pushed, Type type) { @@ -23,7 +23,7 @@ public class StackContext this.pushed = pushed; type = new Type(c.getName()); } - + public InstructionContext getPushed() { return pushed;