Use instruction ctx to see if a jump has already happened. Not sure if it works but it runs.

This commit is contained in:
Adam
2015-08-12 18:01:12 -04:00
parent f8fe552287
commit 9b4230154c
16 changed files with 114 additions and 98 deletions

View File

@@ -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();

View File

@@ -29,6 +29,8 @@ public class AThrow extends Instruction
StackContext exception = stack.pop();
ins.pop(exception);
frame.addInstructionContext(ins);
frame.stop();
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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<InstructionContext> instructions = new ArrayList<>(); // instructions executed in this frame
private Map<Instruction, List<Instruction>> visited; // shared
private MultiValueMap<InstructionContext, Instruction> 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<Instruction> l = visited.get(from);
if (l == null)
{
List<Instruction> l2 = new ArrayList<>();
l2.add(to);
visited.put(from, l2);
}
else
{
l.add(to);
}
}
private boolean hasJumped(Instruction from, Instruction to)
{
List<Instruction> i = visited.get(from);
Collection<Instruction> 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;