Invokeinterface, among others

This commit is contained in:
Adam
2014-12-09 02:00:10 -05:00
parent 463b6df138
commit a998491133
17 changed files with 186 additions and 50 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target/

View File

@@ -102,6 +102,19 @@ public class ClassFile
return null; return null;
} }
public Method findMethod(NameAndType nat)
{
Method m = methods.findMethod(nat);
if (m != null)
return m;
ClassFile parent = getParent();
if (parent != null)
return parent.findMethod(nat);
return null;
}
public void buildClassGraph() public void buildClassGraph()
{ {

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob;
import info.sigterm.deob.attributes.AttributeType; import info.sigterm.deob.attributes.AttributeType;
import info.sigterm.deob.attributes.Attributes; import info.sigterm.deob.attributes.Attributes;
import info.sigterm.deob.attributes.Code; import info.sigterm.deob.attributes.Code;
import info.sigterm.deob.pool.UTF8;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
@@ -32,6 +33,18 @@ public class Method
{ {
return methods; return methods;
} }
public String getName()
{
UTF8 u = (UTF8) methods.getClassFile().getPool().getEntry(nameIndex);
return u.getValue();
}
public String getDescriptor()
{
UTF8 u = (UTF8) methods.getClassFile().getPool().getEntry(descriptorIndex);
return u.getValue();
}
public Code getCode() public Code getCode()
{ {

View File

@@ -1,5 +1,7 @@
package info.sigterm.deob; package info.sigterm.deob;
import info.sigterm.deob.pool.NameAndType;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
@@ -27,6 +29,14 @@ public class Methods
{ {
return classFile; return classFile;
} }
public Method findMethod(NameAndType nat)
{
for (Method m : methods)
if (m.getName().equals(nat.getName()) && m.getDescriptor().equals(nat.getDescriptor()))
return m;
return null;
}
public void buildInstructionGraph() public void buildInstructionGraph()
{ {

View File

@@ -188,7 +188,6 @@ public enum InstructionType
INVOKESPECIAL(0xb7, "invokespecial", InvokeSpecial.class), INVOKESPECIAL(0xb7, "invokespecial", InvokeSpecial.class),
INVOKESTATIC(0xb8, "invokestatic", InvokeStatic.class), INVOKESTATIC(0xb8, "invokestatic", InvokeStatic.class),
INVOKEINTERFACE(0xb9, "invokeinterface", InvokeInterface.class), INVOKEINTERFACE(0xb9, "invokeinterface", InvokeInterface.class),
INVOKEDYNAMIC(0xba, "invokedynamic", InvokeDynamic.class),
NEW(0xbb, "new", New.class), NEW(0xbb, "new", New.class),
NEWARRAY(0xbc, "newarray", NewArray.class), NEWARRAY(0xbc, "newarray", NewArray.class),
ANEWARRAY(0xbd, "anewarray", ANewArray.class), ANEWARRAY(0xbd, "anewarray", ANewArray.class),

View File

@@ -2,7 +2,6 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.ClassFile; import info.sigterm.deob.ClassFile;
import info.sigterm.deob.ConstantPool; import info.sigterm.deob.ConstantPool;
import info.sigterm.deob.attributes.ConstantValue;
import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.Instructions;
@@ -12,7 +11,6 @@ import info.sigterm.deob.execution.StaticFieldInstance;
import info.sigterm.deob.pool.Class; import info.sigterm.deob.pool.Class;
import info.sigterm.deob.pool.Field; import info.sigterm.deob.pool.Field;
import info.sigterm.deob.pool.NameAndType; import info.sigterm.deob.pool.NameAndType;
import info.sigterm.deob.pool.PoolEntry;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
@@ -51,10 +49,7 @@ public class GetStatic extends Instruction
ClassInstance ci = frame.getPath().getClassInstance(cf); ClassInstance ci = frame.getPath().getClassInstance(cf);
StaticFieldInstance fi = ci.findStaticField(nat); StaticFieldInstance fi = ci.findStaticField(nat);
ConstantValue value = fi.getValue(); Object ovalue = fi.getValue();
PoolEntry pe = value.getValue();
Object ovalue = pe.getObject();
frame.getStack().push(ovalue); frame.getStack().push(ovalue);
} }

View File

@@ -1,24 +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 InvokeDynamic extends Instruction
{
private int index;
public InvokeDynamic(Instructions instructions, InstructionType type, int pc) throws IOException
{
super(instructions, type, pc);
DataInputStream is = instructions.getCode().getAttributes().getStream();
index = is.readUnsignedShort();
is.skip(2);
length += 4;
}
}

View File

@@ -1,8 +1,15 @@
package info.sigterm.deob.attributes.code.instructions; package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.ClassFile;
import info.sigterm.deob.ConstantPool;
import info.sigterm.deob.Method;
import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.ClassInstance;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.ObjectInstance;
import info.sigterm.deob.pool.InterfaceMethod;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
@@ -23,4 +30,24 @@ public class InvokeInterface extends Instruction
length += 4; length += 4;
} }
@Override
public void execute(Frame e)
{
ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile();
ConstantPool pool = thisClass.getPool();
InterfaceMethod method = (InterfaceMethod) pool.getEntry(index);
ObjectInstance object = (ObjectInstance) e.getStack().pop();
ClassInstance objectType = object.getType();
Object[] args = new Object[count + 1];
args[0] = object;
for (int i = 1; i < count + 1; ++i)
args[i] = e.getStack().pop();
Method meth = objectType.getClassFile().findMethod(method.getNameAndType());
e.getPath().invoke(meth, args);
}
} }

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.Instruction;
import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.Frame;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
@@ -20,4 +21,38 @@ public class NewArray extends Instruction
length += 1; length += 1;
} }
@Override
public void execute(Frame e)
{
int count = (int) e.getStack().pop();
switch (type)
{
case 4:
e.getStack().push(new boolean[count]);
break;
case 5:
e.getStack().push(new char[count]);
break;
case 6:
e.getStack().push(new float[count]);
break;
case 7:
e.getStack().push(new double[count]);
break;
case 8:
e.getStack().push(new byte[count]);
break;
case 9:
e.getStack().push(new short[count]);
break;
case 10:
e.getStack().push(new int[count]);
break;
case 11:
e.getStack().push(new long[count]);
break;
}
}
} }

View File

@@ -1,8 +1,15 @@
package info.sigterm.deob.attributes.code.instructions; 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.Instruction;
import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions; 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.DataInputStream;
import java.io.IOException; import java.io.IOException;
@@ -20,4 +27,20 @@ public class PutField extends Instruction
length += 2; length += 2;
} }
@Override
public void execute(Frame e)
{
ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile();
ConstantPool pool = thisClass.getPool();
Field entry = (Field) pool.getEntry(index);
NameAndType nat = entry.getNameAndType();
ObjectInstance object = (ObjectInstance) e.getStack().pop();
Object value = e.getStack().pop();
FieldInstance field = object.getField(nat);
field.setValue(value);
}
} }

View File

@@ -1,8 +1,16 @@
package info.sigterm.deob.attributes.code.instructions; 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.Instruction;
import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.execution.ClassInstance;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.StaticFieldInstance;
import info.sigterm.deob.pool.Class;
import info.sigterm.deob.pool.Field;
import info.sigterm.deob.pool.NameAndType;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
@@ -20,4 +28,25 @@ public class PutStatic extends Instruction
length += 2; length += 2;
} }
@Override
public void execute(Frame e)
{
ClassFile thisClass = this.getInstructions().getCode().getAttributes().getClassFile();
ConstantPool pool = thisClass.getPool();
Field entry = (Field) pool.getEntry(index);
Class clazz = entry.getClassEntry();
NameAndType nat = entry.getNameAndType();
Object value = e.getStack().pop();
ClassFile cf = thisClass.getGroup().findClass(clazz.getName());
if (cf == null)
return;
ClassInstance ci = e.getPath().getClassInstance(cf);
StaticFieldInstance fi = ci.findStaticField(nat);
fi.setField(value);
}
} }

View File

@@ -18,7 +18,7 @@ public class Execution
public void run(Method method, Object... args) public void run(Method method, Object... args)
{ {
Path p = new Path(this); Path p = new Path(this);
p.init(method, args); p.invoke(method, args);
} }
public void addPath(Path p) public void addPath(Path p)

View File

@@ -24,4 +24,9 @@ public class FieldInstance
{ {
return value; return value;
} }
public void setValue(Object obj)
{
value = obj;
}
} }

View File

@@ -39,14 +39,6 @@ public class Frame
{ {
return variables; return variables;
} }
public void init(Object[] args)
{
for (Object o : args)
stack.push(o);
execute();
}
public void execute() public void execute()
{ {

View File

@@ -64,13 +64,6 @@ public class Path
{ {
return frames.peek(); return frames.peek();
} }
public void init(Method method, Object[] args)
{
Frame f = new Frame(this, method);
frames.push(f);
f.init(args);
}
public Path dup() public Path dup()
{ {
@@ -78,4 +71,14 @@ public class Path
execution.addPath(other); execution.addPath(other);
return other; return other;
} }
public void invoke(Method method, Object[] args)
{
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);
f.execute();
}
} }

View File

@@ -7,13 +7,13 @@ public class StaticFieldInstance
{ {
private ClassInstance clazz; private ClassInstance clazz;
private Field field; private Field field;
private ConstantValue value; private Object value;
public StaticFieldInstance(ClassInstance clazz, Field field, ConstantValue value) public StaticFieldInstance(ClassInstance clazz, Field field, ConstantValue value)
{ {
this.clazz = clazz; this.clazz = clazz;
this.field = field; this.field = field;
this.value = value; this.value = value.getValue().getObject();
} }
public Field getField() public Field getField()
@@ -21,8 +21,13 @@ public class StaticFieldInstance
return field; return field;
} }
public ConstantValue getValue() public Object getValue()
{ {
return value; return value;
} }
public void setField(Object obj)
{
value = obj;
}
} }

View File

@@ -19,4 +19,14 @@ public class InterfaceMethod extends PoolEntry
classIndex = is.readUnsignedShort(); classIndex = is.readUnsignedShort();
nameAndTypeIndex = is.readUnsignedShort(); nameAndTypeIndex = is.readUnsignedShort();
} }
public Class getClassEntry()
{
return (Class) this.getPool().getEntry(classIndex);
}
public NameAndType getNameAndType()
{
return (NameAndType) this.getPool().getEntry(nameAndTypeIndex);
}
} }