debugging, idr, exception handler execution support
This commit is contained in:
@@ -52,10 +52,6 @@ public class Deob
|
|||||||
// remove jump obfuscation
|
// remove jump obfuscation
|
||||||
new Jumps().run(group);
|
new Jumps().run(group);
|
||||||
|
|
||||||
//group.buildClassGraph();
|
|
||||||
//group.buildInstructionGraph();
|
|
||||||
//group.buildCallGraph();
|
|
||||||
|
|
||||||
saveJar(group, args[1]);
|
saveJar(group, args[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import info.sigterm.deob.execution.Execution;
|
|||||||
import info.sigterm.deob.execution.Frame;
|
import info.sigterm.deob.execution.Frame;
|
||||||
import info.sigterm.deob.execution.InstructionContext;
|
import info.sigterm.deob.execution.InstructionContext;
|
||||||
import info.sigterm.deob.pool.NameAndType;
|
import info.sigterm.deob.pool.NameAndType;
|
||||||
|
import info.sigterm.deob.pool.PoolEntry;
|
||||||
import info.sigterm.deob.signature.Signature;
|
import info.sigterm.deob.signature.Signature;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
@@ -72,11 +73,13 @@ public class Method
|
|||||||
Method caller = n.from;
|
Method caller = n.from;
|
||||||
|
|
||||||
// find frames on the caller
|
// find frames on the caller
|
||||||
|
boolean found = false;
|
||||||
for (Frame f : execution.processedFrames)
|
for (Frame f : execution.processedFrames)
|
||||||
if (f.getMethod() == caller)
|
if (f.getMethod() == caller)
|
||||||
for (InstructionContext ins : f.getInstructions())
|
for (InstructionContext ins : f.getInstructions())
|
||||||
if (ins.getInstruction() == n.ins) // this instruction invokes the function we're removing a parameter from
|
if (ins.getInstruction() == n.ins) // this instruction invokes the function we're removing a parameter from
|
||||||
{
|
{
|
||||||
|
found = true;
|
||||||
if (done.contains(ins.getInstruction()))
|
if (done.contains(ins.getInstruction()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -88,8 +91,54 @@ public class Method
|
|||||||
|
|
||||||
done.add(ins.getInstruction());
|
done.add(ins.getInstruction());
|
||||||
}
|
}
|
||||||
|
if (found == false)
|
||||||
|
{
|
||||||
|
System.err.println("Method " + caller.getName() + " in " + caller.getMethods().getClassFile().getName() + " calls " + this.getName() + " in " + this.getMethods().getClassFile().getName() + ", but was unable to find any execution frame doing this");
|
||||||
|
assert false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this double checks that all calls to this have been located
|
||||||
|
for (ClassFile cf : methods.getClassFile().getGroup().getClasses())
|
||||||
|
for (Method m : cf.getMethods().getMethods())
|
||||||
|
{
|
||||||
|
Code c = m.getCode();
|
||||||
|
if (c == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (Instruction i : c.getInstructions().getInstructions())
|
||||||
|
{
|
||||||
|
if (i instanceof InvokeInstruction)
|
||||||
|
{
|
||||||
|
InvokeInstruction ii = (InvokeInstruction) i;
|
||||||
|
PoolEntry pool = ii.getMethod();
|
||||||
|
|
||||||
|
if (pool instanceof info.sigterm.deob.pool.Method)
|
||||||
|
{
|
||||||
|
info.sigterm.deob.pool.Method pm = (info.sigterm.deob.pool.Method) pool;
|
||||||
|
|
||||||
|
if (pm.getClassEntry().getName().equals(this.getMethods().getClassFile().getName()) && pm.getNameAndType().equals(this.getNameAndType()) && !done.contains(i))
|
||||||
|
{
|
||||||
|
// for some reason this wasn't removed above?
|
||||||
|
System.err.println("Method " + m.getName() + " in " + cf.getName() + " calls " + pm.getNameAndType().getName() + " in " + pm.getClassEntry().getName() + " at " + i.getPc() + ", but this instruction was not found during execution");
|
||||||
|
//assert false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pool instanceof info.sigterm.deob.pool.InterfaceMethod)
|
||||||
|
{
|
||||||
|
info.sigterm.deob.pool.InterfaceMethod pm = (info.sigterm.deob.pool.InterfaceMethod) pool;
|
||||||
|
|
||||||
|
if (pm.getClassEntry().getName().equals(this.getMethods().getClassFile().getName()) && pm.getNameAndType().equals(this.getNameAndType()) && !done.contains(i))
|
||||||
|
{
|
||||||
|
// for some reason this wasn't removed above?
|
||||||
|
System.err.println("Method " + m.getName() + " in " + cf.getName() + " calls " + pm.getNameAndType().getName() + " in " + pm.getClassEntry().getName() + " at " + i.getPc() + ", but this instruction was not found during execution");
|
||||||
|
//assert false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// adjust lvt indexes to get rid of idx in the method
|
// adjust lvt indexes to get rid of idx in the method
|
||||||
for (Instruction ins : new ArrayList<>(getCode().getInstructions().getInstructions()))
|
for (Instruction ins : new ArrayList<>(getCode().getInstructions().getInstructions()))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
package info.sigterm.deob.attributes.code.instruction.types;
|
package info.sigterm.deob.attributes.code.instruction.types;
|
||||||
|
|
||||||
|
import info.sigterm.deob.Method;
|
||||||
|
import info.sigterm.deob.pool.PoolEntry;
|
||||||
|
|
||||||
public interface InvokeInstruction
|
public interface InvokeInstruction
|
||||||
{
|
{
|
||||||
public void removeParameter(int idx);
|
public void removeParameter(int idx);
|
||||||
|
|
||||||
|
public PoolEntry getMethod();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,11 @@ 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.InstructionContext;
|
||||||
import info.sigterm.deob.execution.Stack;
|
import info.sigterm.deob.execution.Stack;
|
||||||
|
import info.sigterm.deob.execution.StackContext;
|
||||||
|
import info.sigterm.deob.execution.Type;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class AThrow extends Instruction
|
public class AThrow extends Instruction
|
||||||
{
|
{
|
||||||
@@ -21,13 +25,38 @@ public class AThrow extends Instruction
|
|||||||
InstructionContext ins = new InstructionContext(this, frame);
|
InstructionContext ins = new InstructionContext(this, frame);
|
||||||
Stack stack = frame.getStack();
|
Stack stack = frame.getStack();
|
||||||
|
|
||||||
// XXX this actually clears the stack and puts only the value on, after jumping to the handler
|
// get exception
|
||||||
//StackContext value = stack.pop();
|
StackContext exception = stack.pop();
|
||||||
//ins.pop(value);
|
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())
|
||||||
|
{
|
||||||
|
Instruction start = e.getStart(),
|
||||||
|
end = e.getEnd();
|
||||||
|
|
||||||
|
// [start, end)
|
||||||
|
if (this.getPc() >= start.getPc() && this.getPc() < end.getPc())
|
||||||
|
{
|
||||||
|
Frame f = frame.dup();
|
||||||
|
f.jumpAbsolute(e.getHandler().getPc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
|
|
||||||
frame.throwException(null);//value.getType());
|
frame.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -36,17 +36,35 @@ public class CheckCast extends Instruction
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Frame frame)
|
public void execute(Frame frame)
|
||||||
{
|
{
|
||||||
Frame other = frame.dup();
|
// jump to instruction handlers that can catch exceptions here
|
||||||
Stack stack = other.getStack();
|
for (info.sigterm.deob.attributes.code.Exception e : this.getInstructions().getCode().getExceptions().getExceptions())
|
||||||
|
{
|
||||||
InstructionContext ins = new InstructionContext(this, other);
|
Instruction start = e.getStart(),
|
||||||
|
end = e.getEnd();
|
||||||
StackContext what = stack.pop();
|
|
||||||
|
// [start, end)
|
||||||
ins.pop(what);
|
if (this.getPc() >= start.getPc() && this.getPc() < end.getPc())
|
||||||
|
{
|
||||||
other.throwException(new Type("java.lang.ClassCastException"));
|
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);
|
||||||
|
|
||||||
|
f.addInstructionContext(ins);
|
||||||
|
|
||||||
|
f.jumpAbsolute(e.getHandler().getPc());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ public class If0 extends Instruction implements JumpingInstruction
|
|||||||
|
|
||||||
ins.pop(one);
|
ins.pop(one);
|
||||||
|
|
||||||
|
frame.addInstructionContext(ins);
|
||||||
|
|
||||||
Frame other = frame.dup();
|
Frame other = frame.dup();
|
||||||
other.jump(offset);
|
other.jump(offset);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import info.sigterm.deob.execution.Type;
|
|||||||
import info.sigterm.deob.pool.InterfaceMethod;
|
import info.sigterm.deob.pool.InterfaceMethod;
|
||||||
import info.sigterm.deob.pool.Method;
|
import info.sigterm.deob.pool.Method;
|
||||||
import info.sigterm.deob.pool.NameAndType;
|
import info.sigterm.deob.pool.NameAndType;
|
||||||
|
import info.sigterm.deob.pool.PoolEntry;
|
||||||
import info.sigterm.deob.signature.Signature;
|
import info.sigterm.deob.signature.Signature;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
@@ -77,6 +78,8 @@ 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());
|
||||||
@@ -85,6 +88,32 @@ 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())
|
||||||
|
{
|
||||||
|
Instruction start = e.getStart(),
|
||||||
|
end = e.getEnd();
|
||||||
|
|
||||||
|
// [start, end)
|
||||||
|
if (this.getPc() >= start.getPc() && this.getPc() < end.getPc())
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
f.jumpAbsolute(e.getHandler().getPc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeParameter(int idx)
|
public void removeParameter(int idx)
|
||||||
@@ -99,4 +128,10 @@ public class InvokeInterface extends Instruction implements InvokeInstruction
|
|||||||
// create new method pool object
|
// create new method pool object
|
||||||
method = new InterfaceMethod(method.getPool(), clazz, new NameAndType(nat.getPool(), nat.getName(), sig));
|
method = new InterfaceMethod(method.getPool(), clazz, new NameAndType(nat.getPool(), nat.getName(), sig));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PoolEntry getMethod()
|
||||||
|
{
|
||||||
|
return method;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import info.sigterm.deob.execution.StackContext;
|
|||||||
import info.sigterm.deob.execution.Type;
|
import info.sigterm.deob.execution.Type;
|
||||||
import info.sigterm.deob.pool.Method;
|
import info.sigterm.deob.pool.Method;
|
||||||
import info.sigterm.deob.pool.NameAndType;
|
import info.sigterm.deob.pool.NameAndType;
|
||||||
|
import info.sigterm.deob.pool.PoolEntry;
|
||||||
import info.sigterm.deob.signature.Signature;
|
import info.sigterm.deob.signature.Signature;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
@@ -72,6 +73,8 @@ 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());
|
||||||
@@ -80,6 +83,32 @@ 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())
|
||||||
|
{
|
||||||
|
Instruction start = e.getStart(),
|
||||||
|
end = e.getEnd();
|
||||||
|
|
||||||
|
// [start, end)
|
||||||
|
if (this.getPc() >= start.getPc() && this.getPc() < end.getPc())
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
f.jumpAbsolute(e.getHandler().getPc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDesc(Frame frame)
|
public String getDesc(Frame frame)
|
||||||
@@ -100,4 +129,10 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction
|
|||||||
// create new method pool object
|
// create new method pool object
|
||||||
method = new Method(method.getPool(), clazz, new NameAndType(nat.getPool(), nat.getName(), sig));
|
method = new Method(method.getPool(), clazz, new NameAndType(nat.getPool(), nat.getName(), sig));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PoolEntry getMethod()
|
||||||
|
{
|
||||||
|
return method;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import info.sigterm.deob.execution.StackContext;
|
|||||||
import info.sigterm.deob.execution.Type;
|
import info.sigterm.deob.execution.Type;
|
||||||
import info.sigterm.deob.pool.Method;
|
import info.sigterm.deob.pool.Method;
|
||||||
import info.sigterm.deob.pool.NameAndType;
|
import info.sigterm.deob.pool.NameAndType;
|
||||||
|
import info.sigterm.deob.pool.PoolEntry;
|
||||||
import info.sigterm.deob.signature.Signature;
|
import info.sigterm.deob.signature.Signature;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
@@ -69,6 +70,8 @@ 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());
|
||||||
@@ -78,6 +81,32 @@ 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())
|
||||||
|
{
|
||||||
|
Instruction start = e.getStart(),
|
||||||
|
end = e.getEnd();
|
||||||
|
|
||||||
|
// [start, end)
|
||||||
|
if (this.getPc() >= start.getPc() && this.getPc() < end.getPc())
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
f.jumpAbsolute(e.getHandler().getPc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDesc(Frame frame)
|
public String getDesc(Frame frame)
|
||||||
{
|
{
|
||||||
@@ -97,4 +126,10 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
|
|||||||
// create new method pool object
|
// create new method pool object
|
||||||
method = new Method(method.getPool(), clazz, new NameAndType(nat.getPool(), nat.getName(), sig));
|
method = new Method(method.getPool(), clazz, new NameAndType(nat.getPool(), nat.getName(), sig));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PoolEntry getMethod()
|
||||||
|
{
|
||||||
|
return method;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import info.sigterm.deob.execution.StackContext;
|
|||||||
import info.sigterm.deob.execution.Type;
|
import info.sigterm.deob.execution.Type;
|
||||||
import info.sigterm.deob.pool.Method;
|
import info.sigterm.deob.pool.Method;
|
||||||
import info.sigterm.deob.pool.NameAndType;
|
import info.sigterm.deob.pool.NameAndType;
|
||||||
|
import info.sigterm.deob.pool.PoolEntry;
|
||||||
import info.sigterm.deob.signature.Signature;
|
import info.sigterm.deob.signature.Signature;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
@@ -73,6 +74,8 @@ 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());
|
||||||
@@ -82,6 +85,32 @@ public class InvokeVirtual 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())
|
||||||
|
{
|
||||||
|
Instruction start = e.getStart(),
|
||||||
|
end = e.getEnd();
|
||||||
|
|
||||||
|
// [start, end)
|
||||||
|
if (this.getPc() >= start.getPc() && this.getPc() < end.getPc())
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
f.jumpAbsolute(e.getHandler().getPc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeParameter(int idx)
|
public void removeParameter(int idx)
|
||||||
{
|
{
|
||||||
@@ -95,4 +124,10 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction
|
|||||||
// create new method pool object
|
// create new method pool object
|
||||||
method = new Method(method.getPool(), clazz, new NameAndType(nat.getPool(), nat.getName(), sig));
|
method = new Method(method.getPool(), clazz, new NameAndType(nat.getPool(), nat.getName(), sig));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PoolEntry getMethod()
|
||||||
|
{
|
||||||
|
return method;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ public class UnusedParameters
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
int collide = 0;
|
int collide = 0;
|
||||||
int overrides = 0;
|
int overrides = 0;
|
||||||
|
|
||||||
|
group.buildCallGraph(); // method.removeParameter uses the callgraph
|
||||||
|
|
||||||
for (ClassFile cf : group.getClasses())
|
for (ClassFile cf : group.getClasses())
|
||||||
{
|
{
|
||||||
for (Method m : cf.getMethods().getMethods())
|
for (Method m : cf.getMethods().getMethods())
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package info.sigterm.deob.execution;
|
|||||||
import info.sigterm.deob.ClassFile;
|
import info.sigterm.deob.ClassFile;
|
||||||
import info.sigterm.deob.ClassGroup;
|
import info.sigterm.deob.ClassGroup;
|
||||||
import info.sigterm.deob.Method;
|
import info.sigterm.deob.Method;
|
||||||
|
import info.sigterm.deob.attributes.code.Exceptions;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -26,8 +27,10 @@ public class Execution
|
|||||||
{
|
{
|
||||||
if (method.getCode() == null)
|
if (method.getCode() == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Frame f = new Frame(this, method);
|
Frame f = new Frame(this, method);
|
||||||
frames.add(f);
|
frames.add(f);
|
||||||
|
|
||||||
fcount += this.runFrames();
|
fcount += this.runFrames();
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,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, Instruction> visited; // shared
|
private Map<Instruction, List<Instruction>> visited; // shared
|
||||||
|
|
||||||
public Frame(Execution execution, Method method)
|
public Frame(Execution execution, Method method)
|
||||||
{
|
{
|
||||||
@@ -73,11 +73,6 @@ public class Frame
|
|||||||
executing = false;
|
executing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void throwException(Type type)
|
|
||||||
{
|
|
||||||
executing = false; // XXX
|
|
||||||
}
|
|
||||||
|
|
||||||
public Method getMethod()
|
public Method getMethod()
|
||||||
{
|
{
|
||||||
return method;
|
return method;
|
||||||
@@ -154,17 +149,33 @@ public class Frame
|
|||||||
|
|
||||||
private void doJump(Instruction from, Instruction to)
|
private void doJump(Instruction from, Instruction to)
|
||||||
{
|
{
|
||||||
visited.put(from, 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)
|
private boolean hasJumped(Instruction from, Instruction to)
|
||||||
{
|
{
|
||||||
Instruction i = visited.get(from);
|
List<Instruction> i = visited.get(from);
|
||||||
if (from instanceof TableSwitch || from instanceof LookupSwitch) // XXX magic instructions which jump to multiple different places
|
if (i != null && i.contains(to))
|
||||||
if (i != null)
|
return true;
|
||||||
return true;
|
|
||||||
assert i == null || i == to;
|
if (i == null)
|
||||||
return i == to;
|
{
|
||||||
|
i = new ArrayList<>();
|
||||||
|
visited.put(from, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
i.add(to);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void jump(int offset)
|
public void jump(int offset)
|
||||||
|
|||||||
Reference in New Issue
Block a user