Invokeinterface, among others

This commit is contained in:
Adam
2014-12-09 02:00:19 -05:00
parent 463b6df138
commit a998491133
17 changed files with 186 additions and 50 deletions
+1
View File
@@ -0,0 +1 @@
/target/
@@ -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()
{ {
@@ -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()
{ {
@@ -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()
{ {
@@ -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),
@@ -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);
} }
@@ -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;
}
}
@@ -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);
}
} }
@@ -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;
}
}
} }
@@ -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);
}
} }
@@ -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);
}
} }
@@ -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)
@@ -24,4 +24,9 @@ public class FieldInstance
{ {
return value; return value;
} }
public void setValue(Object obj)
{
value = obj;
}
} }
@@ -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()
{ {
@@ -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();
}
} }
@@ -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;
}
} }
@@ -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);
}
} }