jump to exception handlers more reliably. fix finaliers
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user