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; bdur = System.currentTimeMillis() - bstart;
System.out.println("illegal state exception took " + bdur/1000L + " seconds"); System.out.println("illegal state exception took " + bdur/1000L + " seconds");
// // remove constant logically dead parameters // remove constant logically dead parameters
// bstart = System.currentTimeMillis(); bstart = System.currentTimeMillis();
// new ConstantParameter().run(group); new ConstantParameter().run(group);
// bdur = System.currentTimeMillis() - bstart; bdur = System.currentTimeMillis() - bstart;
// System.out.println("constant param took " + bdur/1000L + " seconds"); System.out.println("constant param took " + bdur/1000L + " seconds");
// // remove unhit blocks // // remove unhit blocks
// bstart = System.currentTimeMillis(); // bstart = System.currentTimeMillis();

View File

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

View File

@@ -37,43 +37,20 @@ public class CheckCast extends Instruction
@Override @Override
public void execute(Frame frame) public void execute(Frame frame)
{ {
// jump to instruction handlers that can catch exceptions here InstructionContext ins = new InstructionContext(this, frame);
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions()) Stack stack = frame.getStack();
{
int startIdx = this.getInstructions().getInstructions().indexOf(e.getStart()), StackContext value = stack.pop();
endIdx = this.getInstructions().getInstructions().indexOf(e.getEnd()),
thisIdx = this.getInstructions().getInstructions().indexOf(this); ins.pop(value);
assert startIdx != -1; StackContext ctx = new StackContext(ins, value.getType());
assert endIdx != -1; stack.push(ctx);
assert thisIdx != -1;
ins.push(ctx);
// [start, end)
if (thisIdx >= startIdx && thisIdx < endIdx) frame.addInstructionContext(ins);
{
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());
}
}
} }
@Override @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.Instructions;
import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction; import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction;
import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@@ -62,9 +63,12 @@ public class Goto extends Instruction implements JumpingInstruction
} }
@Override @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 @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.Instructions;
import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction; import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction;
import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@@ -46,9 +47,12 @@ public class GotoW extends Instruction implements JumpingInstruction
} }
@Override @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 @Override

View File

@@ -63,7 +63,7 @@ public class If extends Instruction implements JumpingInstruction, ComparisonIns
frame.addInstructionContext(ins); frame.addInstructionContext(ins);
Frame other = frame.dup(); Frame other = frame.dup();
other.jump(to); other.jump(ins, to);
} }
@Override @Override

View File

@@ -64,7 +64,7 @@ public class If0 extends Instruction implements JumpingInstruction, ComparisonIn
frame.addInstructionContext(ins); frame.addInstructionContext(ins);
Frame other = frame.dup(); Frame other = frame.dup();
other.jump(to); other.jump(ins, to);
} }
@Override @Override

View File

@@ -111,10 +111,10 @@ public class LookupSwitch extends Instruction implements JumpingInstruction
for (Instruction i : branchi) for (Instruction i : branchi)
{ {
Frame other = frame.dup(); Frame other = frame.dup();
other.jump(i); other.jump(ins, i);
} }
frame.jump(defi); frame.jump(ins, defi);
} }
@Override @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.InstructionType;
import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
import info.sigterm.deob.execution.StackContext;
import java.io.IOException; import java.io.IOException;
@@ -17,6 +19,11 @@ public class Pop extends Instruction
@Override @Override
public void execute(Frame frame) 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) for (Instruction i : branchi)
{ {
Frame other = frame.dup(); Frame other = frame.dup();
other.jump(i); other.jump(ins, i);
} }
frame.jump(defi); frame.jump(ins, defi);
} }
@Override @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.Instructions;
import info.sigterm.deob.attributes.code.instruction.types.ReturnInstruction; import info.sigterm.deob.attributes.code.instruction.types.ReturnInstruction;
import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
import java.io.IOException; import java.io.IOException;
@@ -18,6 +19,9 @@ public class VReturn extends Instruction implements ReturnInstruction
@Override @Override
public void execute(Frame frame) public void execute(Frame frame)
{ {
InstructionContext ins = new InstructionContext(this, frame);
frame.addInstructionContext(ins);
frame.stop(); 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.LVTInstruction;
import info.sigterm.deob.attributes.code.instruction.types.WideInstruction; import info.sigterm.deob.attributes.code.instruction.types.WideInstruction;
import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@@ -47,9 +48,13 @@ public class Wide extends Instruction implements LVTInstruction
} }
@Override @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 @Override

View File

@@ -131,7 +131,7 @@ public class ConstantParameter implements Deobfuscator
{ {
PushConstantInstruction pc = (PushConstantInstruction) ctx.getPushed().getInstruction(); PushConstantInstruction pc = (PushConstantInstruction) ctx.getPushed().getInstruction();
if (!(pc.getConstant().getObject() instanceof Integer) && (!(pc.getConstant().getObject() instanceof Byte))) if (!(pc.getConstant().getObject() instanceof Number))
continue; continue;
ConstantMethodParameter cmp = new ConstantMethodParameter(); 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.LookupSwitch;
import info.sigterm.deob.attributes.code.instructions.TableSwitch; import info.sigterm.deob.attributes.code.instructions.TableSwitch;
import info.sigterm.deob.pool.NameAndType; import info.sigterm.deob.pool.NameAndType;
import org.apache.commons.collections4.MultiMap;
import org.apache.commons.collections4.map.MultiValueMap;
public class Frame public class Frame
{ {
@@ -23,7 +25,7 @@ public class Frame
private Stack stack; private Stack stack;
private Variables variables; private Variables variables;
private List<InstructionContext> instructions = new ArrayList<>(); // instructions executed in this frame 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) public Frame(Execution execution, Method method)
{ {
@@ -35,8 +37,6 @@ public class Frame
stack = new Stack(code.getMaxStack()); stack = new Stack(code.getMaxStack());
variables = new Variables(code.getMaxLocals()); variables = new Variables(code.getMaxLocals());
visited = new HashMap<>();
// initialize LVT // initialize LVT
int pos = 0; int pos = 0;
if (!method.isStatic()) if (!method.isStatic())
@@ -60,7 +60,11 @@ public class Frame
this.cur = other.cur; this.cur = other.cur;
this.stack = new Stack(other.stack); this.stack = new Stack(other.stack);
this.variables = new Variables(other.variables); this.variables = new Variables(other.variables);
//this.instructions = new ArrayList<>(other.instructions); // deep?
this.visited = other.visited; this.visited = other.visited;
// for (InstructionContext ctx : other.instructions)
// instructions.add(new InstructionContext(other, ctx));
} }
public Frame dup() public Frame dup()
@@ -160,16 +164,14 @@ public class Frame
private void processExceptions(Instruction i) private void processExceptions(Instruction i)
{ {
Code code = method.getCode(); Code code = method.getCode();
InstructionContext ictx = instructions.get(instructions.size() - 1);
assert ictx.getInstruction() == i;
for (Exception e : code.getExceptions().getExceptions()) for (Exception e : code.getExceptions().getExceptions())
{ {
if (e.getStart() == i) if (e.getStart() == i)
{ {
if (hasJumped(i, e.getHandler()))
continue;
doJump(i, e.getHandler());
Frame f = dup(); Frame f = dup();
Stack stack = f.getStack(); Stack stack = f.getStack();
@@ -182,57 +184,33 @@ public class Frame
ins.push(ctx); ins.push(ctx);
// at this point maybe cur != i, and f.jump() uses cur, so f.jump(ictx, e.getHandler());
f.cur = e.getHandler();
assert f.executing;
} }
} }
} }
private void doJump(Instruction from, Instruction to) private boolean hasJumped(InstructionContext from, Instruction to)
{ {
List<Instruction> l = visited.get(from); Collection<Instruction> i = visited.getCollection(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);
if (i != null && i.contains(to)) if (i != null && i.contains(to))
return true; return true;
if (i == null) visited.put(from, to);
{
i = new ArrayList<>();
visited.put(from, i);
}
i.add(to);
return false; return false;
} }
public void jump(Instruction to) public void jump(InstructionContext from, Instruction to)
{ {
assert to != null; assert to != null;
assert to.getInstructions() == method.getCode().getInstructions(); assert to.getInstructions() == method.getCode().getInstructions();
assert method.getCode().getInstructions().getInstructions().contains(to); assert method.getCode().getInstructions().getInstructions().contains(to);
if (hasJumped(cur, to)) if (hasJumped(from, to))
{ {
executing = false; executing = false;
return; return;
} }
doJump(cur, to);
cur = to; cur = to;
} }
} }

View File

@@ -5,6 +5,7 @@ import java.util.List;
import info.sigterm.deob.Method; import info.sigterm.deob.Method;
import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.Instruction;
import java.util.Objects;
public class InstructionContext public class InstructionContext
{ {
@@ -77,4 +78,38 @@ public class InstructionContext
// start recursively removing // start recursively removing
ctx.removeStack(); 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 public class StackContext
{ {
private InstructionContext pushed; // instruction which pushed this public InstructionContext pushed; // instruction which pushed this
private InstructionContext popped; // instruction which popped this public InstructionContext popped; // instruction which popped this
private Type type; // type of this public Type type; // type of this
public StackContext(InstructionContext pushed, Type type) public StackContext(InstructionContext pushed, Type type)
{ {
@@ -23,7 +23,7 @@ public class StackContext
this.pushed = pushed; this.pushed = pushed;
type = new Type(c.getName()); type = new Type(c.getName());
} }
public InstructionContext getPushed() public InstructionContext getPushed()
{ {
return pushed; return pushed;