diff --git a/src/main/java/info/sigterm/deob/Deob.java b/src/main/java/info/sigterm/deob/Deob.java index c051fd1a54..66d9d44218 100644 --- a/src/main/java/info/sigterm/deob/Deob.java +++ b/src/main/java/info/sigterm/deob/Deob.java @@ -3,7 +3,9 @@ package info.sigterm.deob; import info.sigterm.deob.execution.Execution; import info.sigterm.deob.pool.NameAndType; import info.sigterm.deob.attributes.Code; +import info.sigterm.deob.attributes.code.Block; import info.sigterm.deob.attributes.code.Instruction; +import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.instruction.types.LVTInstruction; import java.io.ByteArrayOutputStream; @@ -132,27 +134,18 @@ public class Deob if (m.getCode() == null) continue; - boolean check = false, remove = false; - for (Instruction ins : new ArrayList<>(m.getCode().getInstructions().getInstructions())) + Instructions ins = m.getCode().getInstructions(); + int count = 0; + for (Block b : new ArrayList<>(ins.getBlocks())) { - if (remove) + // first block is the entrypoint, so its always used + if (count++ == 0) + continue; + + if (b.begin.from.isEmpty() && b.begin.exce.isEmpty()) { - m.getCode().getInstructions().remove(ins); - } - if (check) - { - if (ins.from.isEmpty() && ins.exce.isEmpty()) - { - remove = true; - m.getCode().getInstructions().remove(ins); - ++i; - } - check = false; - } - if (ins.isTerminal()) - { - check = true; - remove = false; + ins.remove(b); + ++i; } } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/Block.java b/src/main/java/info/sigterm/deob/attributes/code/Block.java new file mode 100644 index 0000000000..c590c911e3 --- /dev/null +++ b/src/main/java/info/sigterm/deob/attributes/code/Block.java @@ -0,0 +1,10 @@ +package info.sigterm.deob.attributes.code; + +import java.util.ArrayList; +import java.util.List; + +public class Block +{ + public Instruction begin, end; + public List instructions = new ArrayList<>(); +} diff --git a/src/main/java/info/sigterm/deob/attributes/code/Instruction.java b/src/main/java/info/sigterm/deob/attributes/code/Instruction.java index c6206e3ae7..80fb5ddd25 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instruction.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instruction.java @@ -11,6 +11,7 @@ import java.util.List; public abstract class Instruction { private Instructions instructions; + public Block block; private InstructionType type; private int pc; // offset into method this instructions resides at @@ -29,6 +30,8 @@ public abstract class Instruction protected void remove() { + assert block == null; + for (Instruction i : jump) i.from.remove(this); jump.clear(); diff --git a/src/main/java/info/sigterm/deob/attributes/code/Instructions.java b/src/main/java/info/sigterm/deob/attributes/code/Instructions.java index fa26565e4e..ee92c54664 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instructions.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instructions.java @@ -14,6 +14,7 @@ public class Instructions { private Code code; private List instructions = new ArrayList<>(); + private List blocks = new ArrayList<>(); public Instructions(Code code) throws IOException { @@ -48,6 +49,7 @@ public class Instructions assert pc == length; buildJumpGraph(); + buildBlocks(); } public List getInstructions() @@ -55,12 +57,46 @@ public class Instructions return instructions; } + public List getBlocks() + { + return blocks; + } + public void remove(Instruction ins) { ins.remove(); instructions.remove(ins); } + public void remove(Block block) + { + blocks.remove(block); + + for (Instruction i : block.instructions) + instructions.remove(i); + } + + public void buildBlocks() + { + Block current = null; + for (Instruction i : instructions) + { + if (current == null) + { + current = new Block(); + current.begin = i; + } + i.block = current; + current.instructions.add(i); + if (i.isTerminal()) + { + current.end = i; + blocks.add(current); + current = null; + } + } + } + public void write(DataOutputStream out) throws IOException { ByteArrayOutputStream b = new ByteArrayOutputStream();