jump to exception handlers more reliably. fix finaliers

This commit is contained in:
Adam
2015-08-09 17:22:00 -04:00
parent 1090dfee7e
commit 0e626afd0a
8 changed files with 69 additions and 177 deletions

View File

@@ -64,7 +64,7 @@ public class Deob
// new ConstantParameter().run(group);
// bdur = System.currentTimeMillis() - bstart;
// System.out.println("constant param took " + bdur/1000L + " seconds");
//
// // remove unhit blocks
// bstart = System.currentTimeMillis();
// new UnreachedCode().run(group);

View File

@@ -29,37 +29,37 @@ public class AThrow extends Instruction
StackContext exception = stack.pop();
ins.pop(exception);
// Clear stack
while (stack.getSize() > 0)
{
StackContext value = stack.pop();
ins.pop(value);
}
// push exception back
exception = new StackContext(ins, exception.getType());
stack.push(exception);
// 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();
f.jump(e.getHandler());
}
}
frame.addInstructionContext(ins);
// // Clear stack
// while (stack.getSize() > 0)
// {
// StackContext value = stack.pop();
// ins.pop(value);
// }
//
// // push exception back
// exception = new StackContext(ins, exception.getType());
// stack.push(exception);
//
// // 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();
// f.jump(e.getHandler());
// }
// }
//
// frame.addInstructionContext(ins);
frame.stop();
}

View File

@@ -90,8 +90,6 @@ public class InvokeInterface extends Instruction implements InvokeInstruction
StackContext object = stack.pop();
ins.pop(object);
handleExceptions(frame);
if (!method.getNameAndType().isVoid())
{
StackContext ctx = new StackContext(ins, new Type(method.getNameAndType().getDescriptor().getReturnValue()).toStackType());
@@ -109,39 +107,6 @@ public class InvokeInterface extends Instruction implements InvokeInstruction
frame.addInstructionContext(ins);
}
private void handleExceptions(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();
while (stack.getSize() > 0)
stack.pop();
InstructionContext ins = new InstructionContext(this, f);
StackContext ctx = new StackContext(ins, new Type("java/lang/Exception"));
stack.push(ctx);
ins.push(ctx);
f.jump(e.getHandler());
}
}
}
@Override
public void removeParameter(int idx)

View File

@@ -77,8 +77,6 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction
StackContext object = stack.pop();
ins.pop(object);
handleExceptions(frame);
if (!method.getNameAndType().isVoid())
{
StackContext ctx = new StackContext(ins, new Type(method.getNameAndType().getDescriptor().getReturnValue()).toStackType());
@@ -96,39 +94,6 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction
frame.addInstructionContext(ins);
}
private void handleExceptions(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();
while (stack.getSize() > 0)
stack.pop();
InstructionContext ins = new InstructionContext(this, f);
StackContext ctx = new StackContext(ins, new Type("java/lang/Exception"));
stack.push(ctx);
ins.push(ctx);
f.jump(e.getHandler());
}
}
}
@Override
public String getDesc(Frame frame)

View File

@@ -74,8 +74,6 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
ins.pop(arg);
}
handleExceptions(frame);
if (!method.getNameAndType().isVoid())
{
StackContext ctx = new StackContext(ins, new Type(method.getNameAndType().getDescriptor().getReturnValue()).toStackType());
@@ -93,40 +91,7 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
frame.addInstructionContext(ins);
}
private void handleExceptions(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();
while (stack.getSize() > 0)
stack.pop();
InstructionContext ins = new InstructionContext(this, f);
StackContext ctx = new StackContext(ins, new Type("java/lang/Exception"));
stack.push(ctx);
ins.push(ctx);
f.jump(e.getHandler());
}
}
}
@Override
public String getDesc(Frame frame)
{

View File

@@ -60,8 +60,6 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction
StackContext object = stack.pop();
ins.pop(object);
handleExceptions(frame);
if (!method.getNameAndType().isVoid())
{
StackContext ctx = new StackContext(ins, new Type(method.getNameAndType().getDescriptor().getReturnValue()).toStackType());
@@ -108,39 +106,6 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction
findMethodFromClass(list, cf);
}
private void handleExceptions(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();
while (stack.getSize() > 0)
stack.pop();
InstructionContext ins = new InstructionContext(this, f);
StackContext ctx = new StackContext(ins, new Type("java/lang/Exception"));
stack.push(ctx);
ins.push(ctx);
f.jump(e.getHandler());
}
}
}
@Override
public void removeParameter(int idx)
{

View File

@@ -186,7 +186,7 @@ public class ConstantParameter implements Deobfuscator
Instruction ins = (Instruction) comparison;
assert (comparison instanceof If0) == (otherValue == null);
assert otherValue == null || otherValue instanceof Integer || otherValue instanceof Byte;
assert otherValue == null || otherValue instanceof Integer;
switch (ins.getType())
{

View File

@@ -19,7 +19,6 @@ public class Frame
private Execution execution;
private Method method;
private boolean executing = true;
private int pc;
private Instruction cur; // current instruction
private Stack stack;
private Variables variables;
@@ -58,7 +57,6 @@ public class Frame
this.execution = other.execution;
this.method = other.method;
this.executing = other.executing;
this.pc = other.pc;
this.cur = other.cur;
this.stack = new Stack(other.stack);
this.variables = new Variables(other.variables);
@@ -89,7 +87,7 @@ public class Frame
public int getPc()
{
return pc;
return cur.getPc();
}
public Stack getStack()
@@ -141,6 +139,8 @@ public class Frame
execution.executed.add(oldCur);
processExceptions(oldCur);
if (!executing)
break;
@@ -157,6 +157,38 @@ public class Frame
}
}
private void processExceptions(Instruction i)
{
Code code = method.getCode();
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();
while (stack.getSize() > 0)
stack.pop();
InstructionContext ins = new InstructionContext(i, f);
StackContext ctx = new StackContext(ins, new Type("java/lang/Exception"));
stack.push(ctx);
ins.push(ctx);
// at this point maybe cur != i, and f.jump() uses cur, so
f.cur = e.getHandler();
assert f.executing;
}
}
}
private void doJump(Instruction from, Instruction to)
{
List<Instruction> l = visited.get(from);