Some thinking about exceptions

This commit is contained in:
Adam
2015-02-01 21:15:14 -05:00
parent 763d82379e
commit 027dc6eff9
7 changed files with 96 additions and 5 deletions

View File

@@ -47,6 +47,11 @@ public class Attributes
load(); load();
} }
public Method getMethod()
{
return method;
}
public Attribute findType(AttributeType type) public Attribute findType(AttributeType type)
{ {
for (Attribute a : attributes) for (Attribute a : attributes)

View File

@@ -39,6 +39,11 @@ public class Code extends Attribute
return maxLocals; return maxLocals;
} }
public Exceptions getExceptions()
{
return exceptions;
}
public Instructions getInstructions() public Instructions getInstructions()
{ {
return instructions; return instructions;

View File

@@ -1,9 +1,11 @@
package info.sigterm.deob.attributes.code; package info.sigterm.deob.attributes.code;
import info.sigterm.deob.ConstantPool;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
class Exception public class Exception
{ {
private Exceptions exceptions; private Exceptions exceptions;
@@ -23,4 +25,24 @@ class Exception
handlerPc = is.readUnsignedShort(); handlerPc = is.readUnsignedShort();
catchType = is.readUnsignedShort(); catchType = is.readUnsignedShort();
} }
public Exceptions getExceptions()
{
return exceptions;
}
public int getStartPc()
{
return startPc;
}
public int getEndPc()
{
return endPc;
}
public int getHandlerPc()
{
return handlerPc;
}
} }

View File

@@ -1,9 +1,12 @@
package info.sigterm.deob.attributes.code; package info.sigterm.deob.attributes.code;
import info.sigterm.deob.attributes.Code; import info.sigterm.deob.attributes.Code;
import info.sigterm.deob.execution.ObjectInstance;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
public class Exceptions public class Exceptions
{ {
@@ -27,4 +30,20 @@ public class Exceptions
{ {
return code; return code;
} }
public Collection<Exception> getHandlersForPc(int pc)
{
ArrayList<Exception> matches = new ArrayList<Exception>();
for (Exception e : exceptions)
{
if (pc >= e.getStartPc() && pc < e.getEndPc())
{
/* possible match */
matches.add(e);
}
}
return matches;
}
} }

View File

@@ -19,6 +19,6 @@ public class AThrow extends Instruction
public void execute(Frame e) public void execute(Frame e)
{ {
ObjectInstance exception = (ObjectInstance) e.getStack().pop(); ObjectInstance exception = (ObjectInstance) e.getStack().pop();
e.getPath().throwException(exception); e.getPath().throwException(this, exception);
} }
} }

View File

@@ -1,7 +1,10 @@
package info.sigterm.deob.execution; package info.sigterm.deob.execution;
import java.util.Collection;
import info.sigterm.deob.Method; import info.sigterm.deob.Method;
import info.sigterm.deob.attributes.Code; import info.sigterm.deob.attributes.Code;
import info.sigterm.deob.attributes.code.Exception;
import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.Instructions;
@@ -40,6 +43,11 @@ public class Frame
return path; return path;
} }
public Method getMethod()
{
return method;
}
public Stack getStack() public Stack getStack()
{ {
return stack; return stack;
@@ -102,4 +110,14 @@ public class Frame
assert offset != 0; assert offset != 0;
pc += offset; pc += offset;
} }
public void jumpAbsolute(int pc)
{
this.pc = pc;
}
public Collection<Exception> getExceptionHandlers()
{
return method.getCode().getExceptions().getHandlersForPc(this.pc);
}
} }

View File

@@ -2,9 +2,11 @@ package info.sigterm.deob.execution;
import info.sigterm.deob.ClassFile; import info.sigterm.deob.ClassFile;
import info.sigterm.deob.Method; import info.sigterm.deob.Method;
import info.sigterm.deob.attributes.code.Exception;
import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.Instruction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
public class Path public class Path
@@ -112,9 +114,29 @@ public class Path
currentFrame.executing = false; currentFrame.executing = false;
} }
public void throwException(ObjectInstance exception) public void throwException(Instruction ins, ObjectInstance exception)
{ {
System.out.println("XXX throw " + exception); ArrayList<Exception> exceptions = new ArrayList<Exception>();
//XXX
/* collect all existing exception handlers */
for (Frame f : frames)
{
Collection<Exception> handlers = f.getExceptionHandlers();
exceptions.addAll(handlers);
}
for (Exception handler : exceptions)
{
/* jump to handler */
Method handlerMethod = handler.getExceptions().getCode().getAttributes().getMethod();
Path other = this.dup();
/* walk up the frames until we find the one which holds the exception handler */
while (handlerMethod != other.getCurrentFrame().getMethod())
other.returnFrame();
/* handler pc is absolute from the beginning instruction */
other.getCurrentFrame().jumpAbsolute(handler.getHandlerPc());
}
} }
} }