Cleanup block removal

This commit is contained in:
Adam
2015-05-11 10:25:00 -04:00
parent fa3e9c0262
commit 64d41c6f92
4 changed files with 61 additions and 19 deletions

View File

@@ -3,7 +3,9 @@ package info.sigterm.deob;
import info.sigterm.deob.execution.Execution; import info.sigterm.deob.execution.Execution;
import info.sigterm.deob.pool.NameAndType; import info.sigterm.deob.pool.NameAndType;
import info.sigterm.deob.attributes.Code; 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.Instruction;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.attributes.code.instruction.types.LVTInstruction; import info.sigterm.deob.attributes.code.instruction.types.LVTInstruction;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@@ -132,27 +134,18 @@ public class Deob
if (m.getCode() == null) if (m.getCode() == null)
continue; continue;
boolean check = false, remove = false; Instructions ins = m.getCode().getInstructions();
for (Instruction ins : new ArrayList<>(m.getCode().getInstructions().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); ins.remove(b);
} ++i;
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;
} }
} }
} }

View File

@@ -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<Instruction> instructions = new ArrayList<>();
}

View File

@@ -11,6 +11,7 @@ import java.util.List;
public abstract class Instruction public abstract class Instruction
{ {
private Instructions instructions; private Instructions instructions;
public Block block;
private InstructionType type; private InstructionType type;
private int pc; // offset into method this instructions resides at private int pc; // offset into method this instructions resides at
@@ -29,6 +30,8 @@ public abstract class Instruction
protected void remove() protected void remove()
{ {
assert block == null;
for (Instruction i : jump) for (Instruction i : jump)
i.from.remove(this); i.from.remove(this);
jump.clear(); jump.clear();

View File

@@ -14,6 +14,7 @@ public class Instructions
{ {
private Code code; private Code code;
private List<Instruction> instructions = new ArrayList<>(); private List<Instruction> instructions = new ArrayList<>();
private List<Block> blocks = new ArrayList<>();
public Instructions(Code code) throws IOException public Instructions(Code code) throws IOException
{ {
@@ -48,6 +49,7 @@ public class Instructions
assert pc == length; assert pc == length;
buildJumpGraph(); buildJumpGraph();
buildBlocks();
} }
public List<Instruction> getInstructions() public List<Instruction> getInstructions()
@@ -55,12 +57,46 @@ public class Instructions
return instructions; return instructions;
} }
public List<Block> getBlocks()
{
return blocks;
}
public void remove(Instruction ins) public void remove(Instruction ins)
{ {
ins.remove(); ins.remove();
instructions.remove(ins); 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 public void write(DataOutputStream out) throws IOException
{ {
ByteArrayOutputStream b = new ByteArrayOutputStream(); ByteArrayOutputStream b = new ByteArrayOutputStream();