Doesn't execute all paths correctly

This commit is contained in:
Adam
2015-02-08 16:35:58 -05:00
parent d00e5b03e1
commit 4dc6bfc949
22 changed files with 160 additions and 42 deletions

View File

@@ -5,11 +5,15 @@ import info.sigterm.deob.ClassGroup;
import info.sigterm.deob.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class Execution
{
private ClassGroup group;
private ArrayList<Path> paths = new ArrayList<Path>(); // paths of execution
private HashMap<Method, HashSet<Integer>> visited = new HashMap<Method, HashSet<Integer>>();
//protected HashSet<Method> methods = new HashSet<Method>();
public Execution(ClassGroup group)
{
@@ -22,13 +26,50 @@ public class Execution
ClassInstance instance = p.getClassInstance(cf);
ObjectInstance object = p.createObject(instance);
int count = 1;
p.invoke(method, object);
//process();
while (!paths.isEmpty())
{
p = paths.remove(0);
++count;
try
{
System.out.println("Resuming path with " + paths.size() + " remaining");
p.resume();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
System.out.println("Done " + count + " paths");
}
public void addPath(Path p)
{
paths.add(p);
}
public boolean visit(Method m)
{
if (visited.containsKey(m))
return false;
visited.put(m, new HashSet<Integer>());
return true;
}
public boolean visit(Method m, int pc)
{
HashSet<Integer> map = visited.get(m);
if (map == null || !map.contains(pc))
{
map.add(pc);
return true;
}
return false;
}
}

View File

@@ -1,6 +1,7 @@
package info.sigterm.deob.execution;
import java.util.Collection;
import java.util.HashSet;
import info.sigterm.deob.Method;
import info.sigterm.deob.attributes.Code;
@@ -47,6 +48,11 @@ public class Frame
{
return method;
}
public int getPc()
{
return pc;
}
public Stack getStack()
{
@@ -67,6 +73,12 @@ public class Frame
Instruction i = ins.findInstruction(pc);
if (i == null)
{
System.err.println("Cant find ins at pc " + pc + " in method " + method.getName() + " in " + method.getCode().getAttributes().getClassFile().getName());
System.exit(-1);
}
try
{
i.execute(this);
@@ -74,7 +86,7 @@ public class Frame
}
catch (Throwable ex)
{
System.err.println("Error executing instruction " + i.getDesc(this) + " in " + method.getName() + " " + method.getDescriptor() + " in class " + method.getMethods().getClassFile().getName() + " at pc " + pc);
System.err.println("Error executing instruction " + i.getDesc(this));
System.err.println("Frame stack (grows downward):");
while (stack.getSize() > 0)
{
@@ -87,8 +99,8 @@ public class Frame
}
System.err.println("end of stack");
ex.printStackTrace();
System.exit(-1);
//throw ex;
//System.exit(-1);
throw ex;
}
if (oldPc == pc)
@@ -102,15 +114,39 @@ public class Frame
}
}
public void resume()
{
execute();
}
public void skip()
{
/* for resume, skip current ins? */
Instructions ins = method.getCode().getInstructions();
Instruction i = ins.findInstruction(pc);
pc += i.getLength();
}
private void checkLoop()
{
if (!this.getPath().getExecution().visit(method, pc))
{
System.out.println("Ending frame " + this);
executing = false;
}
}
public void jump(int offset)
{
assert offset != 0;
pc += offset;
checkLoop();
}
public void jumpAbsolute(int pc)
{
this.pc = pc;
checkLoop();
}
public Collection<Exception> getExceptionHandlers()

View File

@@ -27,7 +27,7 @@ public class ObjectInstance extends ObjectInstanceBase
Attributes attributes = field.getAttributes();
ConstantValue cv = (ConstantValue) attributes.findType(AttributeType.CONSTANT_VALUE);
FieldInstance fi = new FieldInstance(this, field, cv.getValue().getObject());
FieldInstance fi = new FieldInstance(this, field, cv != null ? cv.getValue().getObject() : null);
this.fields.add(fi);
}
}

View File

@@ -90,20 +90,42 @@ public class Path
return other;
}
public void resume()
{
for (Frame f : frames)
{
/* top most is at the correct pc */
if (f == frames.peek())
break;
/* move pc past invoke function */
f.skip();
}
/* resume execution */
while (!frames.isEmpty())
{
Frame top = frames.peek();
top.resume();
if (!frames.isEmpty() && frames.peek() == top)
frames.pop(); // XXX throwing doesnt remove
}
}
public void invoke(Method method, Object... args)
{
if (!this.getExecution().visit(method))
return;
Frame f = new Frame(this, method);
Variables vars = f.getVariables();
for (int i = 0; i < args.length; ++i)
vars.set(i, args[i]);
frames.push(f);
while (!frames.isEmpty())
{
f = frames.peek();
f.execute();
frames.pop();
}
System.out.println("Executing frame " + method.getName() + " " + method.getDescriptor());
f.execute();
if (frames.isEmpty() == false && frames.peek() == f)
System.err.println("Unpopped frame post execute");
}
public void returnFrame(Instruction i, Object value)
@@ -144,5 +166,9 @@ public class Path
/* handler pc is absolute from the beginning instruction */
other.getCurrentFrame().jumpAbsolute(handler.getHandlerPc());
}
/* this path stops executing */
for (Frame f : frames)
f.executing = false;
}
}