Some branching/jumping
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
23
src/main/java/info/sigterm/deob/execution/ArrayInstance.java
Normal file
23
src/main/java/info/sigterm/deob/execution/ArrayInstance.java
Normal 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];
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,4 +20,9 @@ public class Execution
|
||||
Path p = new Path(this);
|
||||
p.init(method, args);
|
||||
}
|
||||
|
||||
public void addPath(Path p)
|
||||
{
|
||||
paths.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
27
src/main/java/info/sigterm/deob/execution/FieldInstance.java
Normal file
27
src/main/java/info/sigterm/deob/execution/FieldInstance.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user