Some branching/jumping

This commit is contained in:
Adam
2014-12-05 16:26:07 -05:00
parent ea556bef32
commit ea366191ea
44 changed files with 571 additions and 124 deletions

View File

@@ -117,4 +117,9 @@ public class ClassFile
{
methods.buildInstructionGraph();
}
public boolean instanceOf(ClassFile other)
{
return this == other || interfaces.instanceOf(other) || (getParent() != null && getParent().instanceOf(other));
}
}

View File

@@ -1,5 +1,7 @@
package info.sigterm.deob;
import info.sigterm.deob.pool.Class;
import java.io.DataInputStream;
import java.io.IOException;
@@ -22,4 +24,16 @@ public class Interfaces
for (int i = 0; i < count; ++i)
interfaces[i] = is.readUnsignedShort();
}
public boolean instanceOf(ClassFile cf)
{
for (int i : interfaces)
{
Class clazz = (Class) classFile.getPool().getEntry(i);
ClassFile iface = classFile.getGroup().findClass(clazz.getName());
if (iface.instanceOf(cf))
return true;
}
return false;
}
}

View File

@@ -1,9 +1,7 @@
package info.sigterm.deob.attributes;
import info.sigterm.deob.attributes.code.Exceptions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
@@ -40,15 +38,30 @@ public class Code extends Attribute
{
return maxLocals;
}
public Instructions getInstructions()
{
return instructions;
}
public void buildInstructionGraph()
{
instructions.buildInstructionGraph();
}
/*
public void execute(Frame frame)
{
Instruction i = instructions.getFirstInstruction();
i.execute(frame);
int pc = 0;
while (exeuting)
{
Instruction i = instructions.findInstruction(pc);
i.execute(frame);
}
}
public void jump(int offset)
{
}*/
}

View File

@@ -55,6 +55,5 @@ public abstract class Instruction
{
}
//public abstract void execute(Frame e);
public void execute(Frame e) { }
public abstract void execute(Frame e);
}

View File

@@ -157,23 +157,21 @@ public enum InstructionType
FCMPG(0x96, "fcmpg", FCmpG.class),
DCMPL(0x97, "dcmpl", DCmpL.class),
DCMPG(0x98, "dcmpg", DCmpG.class),
IFEQ(0x99, "ifeq", Branch.class),
IFNE(0x9a, "ifne", Branch.class),
IFLT(0x9b, "iflt", Branch.class),
IFGE(0x9c, "ifge", Branch.class),
IFGT(0x9d, "ifgt", Branch.class),
IFLE(0x9e, "ifle", Branch.class),
IF_ICMPEQ(0x9f, "if_icmpeq", Branch.class),
IF_ICMPNE(0xa0, "if_icmpne", Branch.class),
IF_ICMPLT(0xa1, "if_cmplt", Branch.class),
IF_CMPGE(0xa2, "if_cmpge", Branch.class),
IF_CMPGT(0xa3, "if_cmpgt", Branch.class),
IF_CMPLE(0xa4, "if_cmple", Branch.class),
IF_ACMPEQ(0xa5, "if_acmpeq", Branch.class),
IF_ACMPNE(0xa6, "if_acmpne", Branch.class),
GOTO(0xa7, "goto", Branch.class),
JSR(0xa8, "jsr", Branch.class),
RET(0xa9, "ret", Ret.class),
IFEQ(0x99, "ifeq", If0.class),
IFNE(0x9a, "ifne", If0.class),
IFLT(0x9b, "iflt", If0.class),
IFGE(0x9c, "ifge", If0.class),
IFGT(0x9d, "ifgt", If0.class),
IFLE(0x9e, "ifle", If0.class),
IF_ICMPEQ(0x9f, "if_icmpeq", If.class),
IF_ICMPNE(0xa0, "if_icmpne", If.class),
IF_ICMPLT(0xa1, "if_cmplt", If.class),
IF_CMPGE(0xa2, "if_cmpge", If.class),
IF_CMPGT(0xa3, "if_cmpgt", If.class),
IF_CMPLE(0xa4, "if_cmple", If.class),
IF_ACMPEQ(0xa5, "if_acmpeq", If.class),
IF_ACMPNE(0xa6, "if_acmpne", If.class),
GOTO(0xa7, "goto", Goto.class),
TABLESWITCH(0xaa, "tableswitch", TableSwitch.class),
LOOKUPSWITCH(0xab, "lookupswitch", LookupSwitch.class),
IRETURN(0xac, "ireturn", Instruction.class),
@@ -198,14 +196,13 @@ public enum InstructionType
ATHROW(0xbf, "athrow", Instruction.class),
CHECKCAST(0xc0, "checkcast", CheckCast.class),
INSTANCEOf(0xc1, "instanceof", InstanceOf.class),
MONITORENTER(0xc2, "monitorenter", Instruction.class),
MONITOREXIT(0xc3, "monitorexit", Instruction.class),
MONITORENTER(0xc2, "monitorenter", MonitorEnter.class),
MONITOREXIT(0xc3, "monitorexit", MonitorExit.class),
WIDE(0xc4, "wide", Wide.class),
MULTIANEWARRAY(0xc5, "multianewarray", MultiANewArray.class),
IFNULL(0xc6, "ifnull", IfNull.class),
IFNONNULL(0xc7, "ifnonnull", IfNonNull.class),
GOTO_W(0xc8, "goto_w", GotoW.class),
JSR_W(0xc9, "jsr_w", JSR_W.class);
IFNULL(0xc6, "ifnull", If0.class),
IFNONNULL(0xc7, "ifnonnull", If0.class),
GOTO_W(0xc8, "goto_w", GotoW.class);
private byte code;
private String name;

View File

@@ -63,12 +63,7 @@ public class Instructions
{
return code;
}
public Instruction getFirstInstruction()
{
return instructions.get(0);
}
public Instruction findInstruction(int pc)
{
for (Instruction i : instructions)

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.ArrayInstance;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.Stack;
@@ -19,8 +20,8 @@ public class AALoad extends Instruction
Stack stack = frame.getStack();
int index = (int) stack.pop();
Object[] array = (Object[]) stack.pop();
ArrayInstance array = (ArrayInstance) stack.pop();
stack.push(array[index]);
stack.push(array.get(index));
}
}

View File

@@ -3,7 +3,9 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.ArrayInstance;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.ObjectInstance;
import info.sigterm.deob.execution.Stack;
public class AAStore extends Instruction
@@ -18,10 +20,10 @@ public class AAStore extends Instruction
{
Stack stack = frame.getStack();
Object value = stack.pop();
ObjectInstance value = (ObjectInstance) stack.pop();
int index = (int) stack.pop();
Object[] array = (Object[]) stack.pop();
ArrayInstance array = (ArrayInstance) stack.pop();
array[index] = value;
array.put(value, index);
}
}

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +21,10 @@ public class ALoad extends Instruction
length += 1;
}
@Override
public void execute(Frame frame)
{
Object obj = frame.getVariables().get(index);
frame.getStack().push(obj);
}
}

View File

@@ -1,8 +1,13 @@
package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.ClassFile;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.ArrayInstance;
import info.sigterm.deob.execution.ClassInstance;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.pool.Class;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +25,24 @@ public class ANewArray extends Instruction
length += 2;
}
@Override
public void execute(Frame frame)
{
ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile();
Class clazz = (Class) thisClass.getPool().getEntry(index);
int count = (int) frame.getStack().pop();
ClassFile cf = thisClass.getGroup().findClass(clazz.getName());
if (cf == null)
{
frame.getStack().push(null);
return;
}
ClassInstance type = frame.getPath().getClassInstance(cf);
ArrayInstance array = frame.getPath().createArray(type, count);
frame.getStack().push(array);
}
}

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +21,9 @@ public class BiPush extends Instruction
length += 1;
}
@Override
public void execute(Frame frame)
{
frame.getStack().push((int) b);
}
}

View File

@@ -1,8 +1,13 @@
package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.ClassFile;
import info.sigterm.deob.ConstantPool;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.ObjectInstance;
import info.sigterm.deob.pool.Class;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +25,30 @@ public class CheckCast extends Instruction
length += 2;
}
@Override
public void execute(Frame e)
{
ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile();
ConstantPool pool = thisClass.getPool();
Class clazz = (Class) pool.getEntry(index);
ObjectInstance obj = (ObjectInstance) e.getStack().pop();
if (obj == null)
{
e.getStack().push(null);
return;
}
ClassFile otherClass = thisClass.getGroup().findClass(clazz.getName());
boolean instanceOf = obj.getType().getClassFile().instanceOf(otherClass);
if (!instanceOf)
{
// XXX throw
}
e.getStack().push(obj);
}
}

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +21,10 @@ public class DLoad extends Instruction
length += 1;
}
@Override
public void execute(Frame frame)
{
double d = (double) frame.getVariables().get(index);
frame.getStack().push(d);
}
}

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +21,10 @@ public class DStore extends Instruction
length += 1;
}
@Override
public void execute(Frame frame)
{
double d = (double) frame.getStack().pop();
frame.getVariables().set(index, d);
}
}

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +21,10 @@ public class FLoad extends Instruction
length += 1;
}
@Override
public void execute(Frame frame)
{
float f = (float) frame.getVariables().get(index);
frame.getStack().push(f);
}
}

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +21,10 @@ public class FStore extends Instruction
length += 1;
}
@Override
public void execute(Frame frame)
{
float f = (float) frame.getStack().pop();
frame.getVariables().set(index, f);
}
}

View File

@@ -1,8 +1,15 @@
package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.ClassFile;
import info.sigterm.deob.ConstantPool;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.FieldInstance;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.ObjectInstance;
import info.sigterm.deob.pool.Field;
import info.sigterm.deob.pool.NameAndType;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +27,19 @@ public class GetField extends Instruction
length += 2;
}
@Override
public void execute(Frame frame)
{
ObjectInstance object = (ObjectInstance) frame.getStack().pop();
ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile();
ConstantPool pool = thisClass.getPool();
Field entry = (Field) pool.getEntry(index);
NameAndType nat = entry.getNameAndType();
FieldInstance field = object.getField(nat);
frame.getStack().push(field.getValue());
}
}

View File

@@ -3,15 +3,16 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
public class Branch extends Instruction
public class Goto extends Instruction
{
private short offset;
public Branch(Instructions instructions, InstructionType type, int pc) throws IOException
public Goto(Instructions instructions, InstructionType type, int pc) throws IOException
{
super(instructions, type, pc);
@@ -25,4 +26,10 @@ public class Branch extends Instruction
{
this.addJump(offset);
}
@Override
public void execute(Frame e)
{
e.jump(offset);
}
}

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
@@ -25,4 +26,10 @@ public class GotoW extends Instruction
{
this.addJump(offset);
}
@Override
public void execute(Frame e)
{
e.jump(offset);
}
}

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
@@ -22,4 +23,11 @@ public class IInc extends Instruction
length += 2;
}
@Override
public void execute(Frame frame)
{
int i = (int) frame.getVariables().get(index);
i += inc;
frame.getVariables().set(index, i);
}
}

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +21,10 @@ public class ILoad extends Instruction
length += 1;
}
@Override
public void execute(Frame frame)
{
int i = (int) frame.getVariables().get(index);
frame.getStack().push(i);
}
}

View File

@@ -0,0 +1,41 @@
package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.Path;
import java.io.DataInputStream;
import java.io.IOException;
public class If extends Instruction
{
private short offset;
public If(Instructions instructions, InstructionType type, int pc) throws IOException
{
super(instructions, type, pc);
DataInputStream is = instructions.getCode().getAttributes().getStream();
offset = is.readShort();
length += 2;
}
@Override
public void buildJumpGraph()
{
this.addJump(offset);
}
@Override
public void execute(Frame e)
{
e.getStack().pop();
e.getStack().pop();
Path other = e.getPath().dup();
Frame frame = other.getCurrentFrame();
frame.jump(offset);
}
}

View File

@@ -3,21 +3,23 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.Path;
import java.io.DataInputStream;
import java.io.IOException;
public class JSR_W extends Instruction
public class If0 extends Instruction
{
private int offset;
private short offset;
public JSR_W(Instructions instructions, InstructionType type, int pc) throws IOException
public If0(Instructions instructions, InstructionType type, int pc) throws IOException
{
super(instructions, type, pc);
DataInputStream is = instructions.getCode().getAttributes().getStream();
offset = is.readInt();
length += 4;
offset = is.readShort();
length += 2;
}
@Override
@@ -25,4 +27,14 @@ public class JSR_W extends Instruction
{
this.addJump(offset);
}
@Override
public void execute(Frame e)
{
e.getStack().pop();
Path other = e.getPath().dup();
Frame frame = other.getCurrentFrame();
frame.jump(offset);
}
}

View File

@@ -1,23 +0,0 @@
package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import java.io.DataInputStream;
import java.io.IOException;
public class IfNonNull extends Instruction
{
private int index;
public IfNonNull(Instructions instructions, InstructionType type, int pc) throws IOException
{
super(instructions, type, pc);
DataInputStream is = instructions.getCode().getAttributes().getStream();
index = is.readUnsignedShort();
length += 2;
}
}

View File

@@ -1,23 +0,0 @@
package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import java.io.DataInputStream;
import java.io.IOException;
public class IfNull extends Instruction
{
private int index;
public IfNull(Instructions instructions, InstructionType type, int pc) throws IOException
{
super(instructions, type, pc);
DataInputStream is = instructions.getCode().getAttributes().getStream();
index = is.readUnsignedShort();
length += 2;
}
}

View File

@@ -1,8 +1,13 @@
package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.ClassFile;
import info.sigterm.deob.ConstantPool;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.ObjectInstanceBase;
import info.sigterm.deob.pool.Class;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +25,24 @@ public class InstanceOf extends Instruction
length += 2;
}
@Override
public void execute(Frame e)
{
ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile();
ConstantPool pool = thisClass.getPool();
Class clazz = (Class) pool.getEntry(index);
ObjectInstanceBase obj = (ObjectInstanceBase) e.getStack().pop();
if (obj == null)
{
e.getStack().push(0);
return;
}
ClassFile otherClass = thisClass.getGroup().findClass(clazz.getName());
boolean instanceOf = obj.getType().getClassFile().instanceOf(otherClass);
e.getStack().push(instanceOf ? 1 : 0);
}
}

View File

@@ -1,8 +1,11 @@
package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.ClassFile;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.pool.PoolEntry;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +23,11 @@ public class LDC extends Instruction
length += 1;
}
@Override
public void execute(Frame frame)
{
ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile();
PoolEntry entry = thisClass.getPool().getEntry(index);
frame.getStack().push(entry.getObject());
}
}

View File

@@ -1,8 +1,11 @@
package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.ClassFile;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.pool.PoolEntry;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +23,11 @@ public class LDC2_W extends Instruction
length += 2;
}
@Override
public void execute(Frame frame)
{
ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile();
PoolEntry entry = thisClass.getPool().getEntry(index);
frame.getStack().push(entry.getObject());
}
}

View File

@@ -1,8 +1,11 @@
package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.ClassFile;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.pool.PoolEntry;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +23,11 @@ public class LDC_W extends Instruction
length += 2;
}
@Override
public void execute(Frame frame)
{
ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile();
PoolEntry entry = thisClass.getPool().getEntry(index);
frame.getStack().push(entry.getObject());
}
}

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +21,10 @@ public class LLoad extends Instruction
length += 1;
}
@Override
public void execute(Frame frame)
{
long l = (long) frame.getVariables().get(index);
frame.getStack().push(l);
}
}

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +21,10 @@ public class LStore extends Instruction
length += 1;
}
@Override
public void execute(Frame frame)
{
long l = (long) frame.getStack().pop();
frame.getVariables().set(index, l);
}
}

View File

@@ -0,0 +1,19 @@
package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
public class MonitorEnter extends Instruction
{
public MonitorEnter(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
@Override
public void execute(Frame frame)
{
}
}

View File

@@ -0,0 +1,19 @@
package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
public class MonitorExit extends Instruction
{
public MonitorExit(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
@Override
public void execute(Frame frame)
{
}
}

View File

@@ -1,23 +0,0 @@
package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import java.io.DataInputStream;
import java.io.IOException;
public class Ret extends Instruction
{
private int index;
public Ret(Instructions instructions, InstructionType type, int pc) throws IOException
{
super(instructions, type, pc);
DataInputStream is = instructions.getCode().getAttributes().getStream();
index = is.readByte();
length += 1;
}
}

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream;
import java.io.IOException;
@@ -20,4 +21,9 @@ public class SiPush extends Instruction
length += 2;
}
@Override
public void execute(Frame frame)
{
frame.getStack().push(s);
}
}

View File

@@ -0,0 +1,23 @@
package info.sigterm.deob.execution;
public class ArrayInstance extends ObjectInstanceBase
{
private ObjectInstance[] array;
public ArrayInstance(Path path, ClassInstance type, int len)
{
super(path, type);
this.array = new ObjectInstance[len];
}
public void put(ObjectInstance obj, int idx)
{
array[idx] = obj;
}
public ObjectInstance get(int idx)
{
return array[idx];
}
}

View File

@@ -29,7 +29,7 @@ public class ClassInstance
Attributes attributes = field.getAttributes();
ConstantValue cv = (ConstantValue) attributes.findType(AttributeType.CONSTANT_VALUE);
StaticFieldInstance fi = new StaticFieldInstance(field, cv);
StaticFieldInstance fi = new StaticFieldInstance(this, field, cv);
this.fields.add(fi);
}
}

View File

@@ -20,4 +20,9 @@ public class Execution
Path p = new Path(this);
p.init(method, args);
}
public void addPath(Path p)
{
paths.add(p);
}
}

View File

@@ -0,0 +1,27 @@
package info.sigterm.deob.execution;
import info.sigterm.deob.Field;
public class FieldInstance
{
private ObjectInstance object;
private Field field;
private Object value;
public FieldInstance(ObjectInstance object, Field field, Object value)
{
this.object = object;
this.field = field;
this.value = value;
}
public Field getField()
{
return field;
}
public Object getValue()
{
return value;
}
}

View File

@@ -2,11 +2,15 @@ package info.sigterm.deob.execution;
import info.sigterm.deob.Method;
import info.sigterm.deob.attributes.Code;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.Instructions;
public class Frame
{
private Path path;
private Method method;
private boolean executing = true;
private int pc;
private Stack stack;
private Variables variables;
@@ -36,12 +40,38 @@ public class Frame
return variables;
}
public void init(Method method, Object[] args)
public void init(Object[] args)
{
for (Object o : args)
stack.push(o);
Code code = method.getCode();
code.execute(this);
execute();
}
public void execute()
{
Instructions ins = method.getCode().getInstructions();
while (executing)
{
int oldPc = pc;
Instruction i = ins.findInstruction(pc);
i.execute(this);
if (oldPc == pc)
{
pc += i.getLength();
}
else
{
/* jump */
}
}
}
public void jump(int offset)
{
assert offset != 0;
pc += offset;
}
}

View File

@@ -1,6 +1,42 @@
package info.sigterm.deob.execution;
public class ObjectInstance
import info.sigterm.deob.Field;
import info.sigterm.deob.Fields;
import info.sigterm.deob.attributes.AttributeType;
import info.sigterm.deob.attributes.Attributes;
import info.sigterm.deob.attributes.ConstantValue;
import info.sigterm.deob.pool.NameAndType;
import java.util.ArrayList;
public class ObjectInstance extends ObjectInstanceBase
{
private ClassInstance type;
private ArrayList<FieldInstance> fields = new ArrayList<FieldInstance>();
public ObjectInstance(Path path, ClassInstance type)
{
super(path, type);
/* create fields */
Fields fields = type.getClassFile().getFields();
for (Field field : fields.getFields())
{
if ((field.getAccessFlags() & Field.ACC_STATIC) != 0)
continue;
Attributes attributes = field.getAttributes();
ConstantValue cv = (ConstantValue) attributes.findType(AttributeType.CONSTANT_VALUE);
FieldInstance fi = new FieldInstance(this, field, cv.getValue().getObject());
this.fields.add(fi);
}
}
public FieldInstance getField(NameAndType nat)
{
for (FieldInstance f : fields)
if (f.getField().getName().equals(nat.getName()) && f.getField().getDescriptor().equals(nat.getDescriptor()))
return f;
return null;
}
}

View File

@@ -0,0 +1,19 @@
package info.sigterm.deob.execution;
public abstract class ObjectInstanceBase
{
private Path path;
private ClassInstance type;
public ObjectInstanceBase(Path path, ClassInstance type)
{
this.path = path;
this.type = type;
}
public ClassInstance getType()
{
return type;
}
}

View File

@@ -9,12 +9,22 @@ public class Path
{
private Execution execution;
private ArrayList<ClassInstance> classes = new ArrayList<ClassInstance>();
private ArrayList<ObjectInstance> objects = new ArrayList<ObjectInstance>();
private java.util.Stack<Frame> frames = new java.util.Stack<Frame>(); // current execution frames
public Path(Execution execution)
{
this.execution = execution;
}
private Path(Path other)
{
this.execution = other.execution;
this.classes = new ArrayList<ClassInstance>(other.classes);
this.objects = new ArrayList<ObjectInstance>(other.objects);
this.frames = new java.util.Stack<Frame>();
this.frames.addAll(other.frames);
}
public Execution getExecution()
{
@@ -37,11 +47,35 @@ public class Path
return cl;
}
public ObjectInstance createObject(ClassInstance type)
{
ObjectInstance obj = new ObjectInstance(this, type);
objects.add(obj);
return obj;
}
public ArrayInstance createArray(ClassInstance type, int len)
{
return new ArrayInstance(this, type, len);
}
public Frame getCurrentFrame()
{
return frames.peek();
}
public void init(Method method, Object[] args)
{
Frame f = new Frame(this, method);
frames.push(f);
f.init(method, args);
f.init(args);
}
public Path dup()
{
Path other = new Path(this);
execution.addPath(other);
return other;
}
}

View File

@@ -5,11 +5,13 @@ import info.sigterm.deob.attributes.ConstantValue;
public class StaticFieldInstance
{
private ClassInstance clazz;
private Field field;
private ConstantValue value;
public StaticFieldInstance(Field field, ConstantValue value)
public StaticFieldInstance(ClassInstance clazz, Field field, ConstantValue value)
{
this.clazz = clazz;
this.field = field;
this.value = value;
}