jump to exception handlers more reliably. fix finaliers
This commit is contained in:
@@ -64,7 +64,7 @@ public class Deob
|
|||||||
// 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();
|
||||||
// new UnreachedCode().run(group);
|
// new UnreachedCode().run(group);
|
||||||
|
|||||||
@@ -29,37 +29,37 @@ public class AThrow extends Instruction
|
|||||||
StackContext exception = stack.pop();
|
StackContext exception = stack.pop();
|
||||||
ins.pop(exception);
|
ins.pop(exception);
|
||||||
|
|
||||||
// Clear stack
|
// // Clear stack
|
||||||
while (stack.getSize() > 0)
|
// while (stack.getSize() > 0)
|
||||||
{
|
// {
|
||||||
StackContext value = stack.pop();
|
// StackContext value = stack.pop();
|
||||||
ins.pop(value);
|
// ins.pop(value);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// push exception back
|
// // push exception back
|
||||||
exception = new StackContext(ins, exception.getType());
|
// exception = new StackContext(ins, exception.getType());
|
||||||
stack.push(exception);
|
// stack.push(exception);
|
||||||
|
//
|
||||||
// jump to instruction handlers that can catch exceptions here
|
// // jump to instruction handlers that can catch exceptions here
|
||||||
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
// for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
||||||
{
|
// {
|
||||||
int startIdx = this.getInstructions().getInstructions().indexOf(e.getStart()),
|
// int startIdx = this.getInstructions().getInstructions().indexOf(e.getStart()),
|
||||||
endIdx = this.getInstructions().getInstructions().indexOf(e.getEnd()),
|
// endIdx = this.getInstructions().getInstructions().indexOf(e.getEnd()),
|
||||||
thisIdx = this.getInstructions().getInstructions().indexOf(this);
|
// thisIdx = this.getInstructions().getInstructions().indexOf(this);
|
||||||
|
//
|
||||||
assert startIdx != -1;
|
// assert startIdx != -1;
|
||||||
assert endIdx != -1;
|
// assert endIdx != -1;
|
||||||
assert thisIdx != -1;
|
// assert thisIdx != -1;
|
||||||
|
//
|
||||||
// [start, end)
|
// // [start, end)
|
||||||
if (thisIdx >= startIdx && thisIdx < endIdx)
|
// if (thisIdx >= startIdx && thisIdx < endIdx)
|
||||||
{
|
// {
|
||||||
Frame f = frame.dup();
|
// Frame f = frame.dup();
|
||||||
f.jump(e.getHandler());
|
// f.jump(e.getHandler());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
frame.addInstructionContext(ins);
|
// frame.addInstructionContext(ins);
|
||||||
|
|
||||||
frame.stop();
|
frame.stop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,8 +90,6 @@ public class InvokeInterface extends Instruction implements InvokeInstruction
|
|||||||
StackContext object = stack.pop();
|
StackContext object = stack.pop();
|
||||||
ins.pop(object);
|
ins.pop(object);
|
||||||
|
|
||||||
handleExceptions(frame);
|
|
||||||
|
|
||||||
if (!method.getNameAndType().isVoid())
|
if (!method.getNameAndType().isVoid())
|
||||||
{
|
{
|
||||||
StackContext ctx = new StackContext(ins, new Type(method.getNameAndType().getDescriptor().getReturnValue()).toStackType());
|
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);
|
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
|
@Override
|
||||||
public void removeParameter(int idx)
|
public void removeParameter(int idx)
|
||||||
|
|||||||
@@ -77,8 +77,6 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction
|
|||||||
StackContext object = stack.pop();
|
StackContext object = stack.pop();
|
||||||
ins.pop(object);
|
ins.pop(object);
|
||||||
|
|
||||||
handleExceptions(frame);
|
|
||||||
|
|
||||||
if (!method.getNameAndType().isVoid())
|
if (!method.getNameAndType().isVoid())
|
||||||
{
|
{
|
||||||
StackContext ctx = new StackContext(ins, new Type(method.getNameAndType().getDescriptor().getReturnValue()).toStackType());
|
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);
|
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
|
@Override
|
||||||
public String getDesc(Frame frame)
|
public String getDesc(Frame frame)
|
||||||
|
|||||||
@@ -74,8 +74,6 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
|
|||||||
ins.pop(arg);
|
ins.pop(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleExceptions(frame);
|
|
||||||
|
|
||||||
if (!method.getNameAndType().isVoid())
|
if (!method.getNameAndType().isVoid())
|
||||||
{
|
{
|
||||||
StackContext ctx = new StackContext(ins, new Type(method.getNameAndType().getDescriptor().getReturnValue()).toStackType());
|
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);
|
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
|
@Override
|
||||||
public String getDesc(Frame frame)
|
public String getDesc(Frame frame)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,8 +60,6 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction
|
|||||||
StackContext object = stack.pop();
|
StackContext object = stack.pop();
|
||||||
ins.pop(object);
|
ins.pop(object);
|
||||||
|
|
||||||
handleExceptions(frame);
|
|
||||||
|
|
||||||
if (!method.getNameAndType().isVoid())
|
if (!method.getNameAndType().isVoid())
|
||||||
{
|
{
|
||||||
StackContext ctx = new StackContext(ins, new Type(method.getNameAndType().getDescriptor().getReturnValue()).toStackType());
|
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);
|
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
|
@Override
|
||||||
public void removeParameter(int idx)
|
public void removeParameter(int idx)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ public class ConstantParameter implements Deobfuscator
|
|||||||
Instruction ins = (Instruction) comparison;
|
Instruction ins = (Instruction) comparison;
|
||||||
|
|
||||||
assert (comparison instanceof If0) == (otherValue == null);
|
assert (comparison instanceof If0) == (otherValue == null);
|
||||||
assert otherValue == null || otherValue instanceof Integer || otherValue instanceof Byte;
|
assert otherValue == null || otherValue instanceof Integer;
|
||||||
|
|
||||||
switch (ins.getType())
|
switch (ins.getType())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ public class Frame
|
|||||||
private Execution execution;
|
private Execution execution;
|
||||||
private Method method;
|
private Method method;
|
||||||
private boolean executing = true;
|
private boolean executing = true;
|
||||||
private int pc;
|
|
||||||
private Instruction cur; // current instruction
|
private Instruction cur; // current instruction
|
||||||
private Stack stack;
|
private Stack stack;
|
||||||
private Variables variables;
|
private Variables variables;
|
||||||
@@ -58,7 +57,6 @@ public class Frame
|
|||||||
this.execution = other.execution;
|
this.execution = other.execution;
|
||||||
this.method = other.method;
|
this.method = other.method;
|
||||||
this.executing = other.executing;
|
this.executing = other.executing;
|
||||||
this.pc = other.pc;
|
|
||||||
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);
|
||||||
@@ -89,7 +87,7 @@ public class Frame
|
|||||||
|
|
||||||
public int getPc()
|
public int getPc()
|
||||||
{
|
{
|
||||||
return pc;
|
return cur.getPc();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stack getStack()
|
public Stack getStack()
|
||||||
@@ -141,6 +139,8 @@ public class Frame
|
|||||||
|
|
||||||
execution.executed.add(oldCur);
|
execution.executed.add(oldCur);
|
||||||
|
|
||||||
|
processExceptions(oldCur);
|
||||||
|
|
||||||
if (!executing)
|
if (!executing)
|
||||||
break;
|
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)
|
private void doJump(Instruction from, Instruction to)
|
||||||
{
|
{
|
||||||
List<Instruction> l = visited.get(from);
|
List<Instruction> l = visited.get(from);
|
||||||
|
|||||||
Reference in New Issue
Block a user