Store stack context with variable context, and pass up stack contexts when invoking methods. I don't think iirc is right?
This commit is contained in:
5
pom.xml
5
pom.xml
@@ -9,6 +9,11 @@
|
|||||||
<artifactId>commons-collections4</artifactId>
|
<artifactId>commons-collections4</artifactId>
|
||||||
<version>4.0</version>
|
<version>4.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>18.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>1.7</maven.compiler.source>
|
<maven.compiler.source>1.7</maven.compiler.source>
|
||||||
|
|||||||
@@ -47,66 +47,66 @@ public class Deob
|
|||||||
// bdur = System.currentTimeMillis() - bstart;
|
// bdur = System.currentTimeMillis() - bstart;
|
||||||
// System.out.println("rename unique took " + bdur/1000L + " seconds");
|
// System.out.println("rename unique took " + bdur/1000L + " seconds");
|
||||||
|
|
||||||
// // remove except RuntimeException
|
// remove except RuntimeException
|
||||||
// bstart = System.currentTimeMillis();
|
bstart = System.currentTimeMillis();
|
||||||
// new RuntimeExceptions().run(group);
|
new RuntimeExceptions().run(group);
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
bdur = System.currentTimeMillis() - bstart;
|
||||||
// System.out.println("runtime exception took " + bdur/1000L + " seconds");
|
System.out.println("runtime exception took " + bdur/1000L + " seconds");
|
||||||
//
|
|
||||||
// // remove unused methods
|
// remove unused methods
|
||||||
// bstart = System.currentTimeMillis();
|
bstart = System.currentTimeMillis();
|
||||||
// new UnusedMethods().run(group);
|
new UnusedMethods().run(group);
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
bdur = System.currentTimeMillis() - bstart;
|
||||||
// System.out.println("unused methods took " + bdur/1000L + " seconds");
|
System.out.println("unused methods took " + bdur/1000L + " seconds");
|
||||||
//
|
|
||||||
// new UnreachedCode().run(group);
|
new UnreachedCode().run(group);
|
||||||
//
|
|
||||||
// // remove illegal state exceptions, frees up some parameters
|
// remove illegal state exceptions, frees up some parameters
|
||||||
// bstart = System.currentTimeMillis();
|
bstart = System.currentTimeMillis();
|
||||||
// new IllegalStateExceptions().run(group);
|
new IllegalStateExceptions().run(group);
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
bdur = System.currentTimeMillis() - bstart;
|
||||||
// System.out.println("illegal state exception took " + bdur/1000L + " seconds");
|
System.out.println("illegal state exception took " + bdur/1000L + " seconds");
|
||||||
//
|
|
||||||
// // remove constant logically dead parameters
|
// remove constant logically dead parameters
|
||||||
// bstart = System.currentTimeMillis();
|
bstart = System.currentTimeMillis();
|
||||||
// new ConstantParameter().run(group);
|
new ConstantParameter().run(group);
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
bdur = System.currentTimeMillis() - bstart;
|
||||||
// System.out.println("constant param took " + bdur/1000L + " seconds");
|
System.out.println("constant param took " + bdur/1000L + " seconds");
|
||||||
//
|
|
||||||
// // remove unhit blocks
|
// remove unhit blocks
|
||||||
// bstart = System.currentTimeMillis();
|
bstart = System.currentTimeMillis();
|
||||||
// new UnreachedCode().run(group);
|
new UnreachedCode().run(group);
|
||||||
// //new UnusedBlocks().run(group);
|
//new UnusedBlocks().run(group);
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
bdur = System.currentTimeMillis() - bstart;
|
||||||
// System.out.println("unused blocks took " + bdur/1000L + " seconds");
|
System.out.println("unused blocks took " + bdur/1000L + " seconds");
|
||||||
//
|
|
||||||
// // remove unused parameters
|
// remove unused parameters
|
||||||
// bstart = System.currentTimeMillis();
|
bstart = System.currentTimeMillis();
|
||||||
// new UnusedParameters().run(group);
|
new UnusedParameters().run(group);
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
bdur = System.currentTimeMillis() - bstart;
|
||||||
// System.out.println("unused params took " + bdur/1000L + " seconds");
|
System.out.println("unused params took " + bdur/1000L + " seconds");
|
||||||
//
|
|
||||||
// // remove jump obfuscation
|
// remove jump obfuscation
|
||||||
// //new Jumps().run(group);
|
//new Jumps().run(group);
|
||||||
//
|
|
||||||
// // remove unused fields
|
// remove unused fields
|
||||||
// bstart = System.currentTimeMillis();
|
bstart = System.currentTimeMillis();
|
||||||
// new UnusedFields().run(group);
|
new UnusedFields().run(group);
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
bdur = System.currentTimeMillis() - bstart;
|
||||||
// System.out.println("unused fields took " + bdur/1000L + " seconds");
|
System.out.println("unused fields took " + bdur/1000L + " seconds");
|
||||||
//
|
|
||||||
// // remove unused methods, again?
|
// remove unused methods, again?
|
||||||
// bstart = System.currentTimeMillis();
|
bstart = System.currentTimeMillis();
|
||||||
// new UnusedMethods().run(group);
|
new UnusedMethods().run(group);
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
bdur = System.currentTimeMillis() - bstart;
|
||||||
// System.out.println("unused methods took " + bdur/1000L + " seconds");
|
System.out.println("unused methods took " + bdur/1000L + " seconds");
|
||||||
//
|
|
||||||
//
|
|
||||||
// new MethodInliner().run(group);
|
new MethodInliner().run(group);
|
||||||
//
|
|
||||||
// new MethodMover().run(group);
|
new MethodMover().run(group);
|
||||||
//
|
|
||||||
// new FieldInliner().run(group);
|
new FieldInliner().run(group);
|
||||||
|
|
||||||
// XXX this is broken because when moving clinit around, some fields can depend on other fields
|
// XXX this is broken because when moving clinit around, some fields can depend on other fields
|
||||||
// (like multianewarray)
|
// (like multianewarray)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package net.runelite.deob.attributes.code.instructions;
|
package net.runelite.deob.attributes.code.instructions;
|
||||||
|
|
||||||
import net.runelite.deob.ClassFile;
|
|
||||||
import net.runelite.deob.attributes.code.Instruction;
|
import net.runelite.deob.attributes.code.Instruction;
|
||||||
import net.runelite.deob.attributes.code.InstructionType;
|
import net.runelite.deob.attributes.code.InstructionType;
|
||||||
import net.runelite.deob.attributes.code.Instructions;
|
import net.runelite.deob.attributes.code.Instructions;
|
||||||
@@ -12,7 +11,6 @@ import net.runelite.deob.execution.Stack;
|
|||||||
import net.runelite.deob.execution.StackContext;
|
import net.runelite.deob.execution.StackContext;
|
||||||
import net.runelite.deob.execution.VariableContext;
|
import net.runelite.deob.execution.VariableContext;
|
||||||
import net.runelite.deob.execution.Variables;
|
import net.runelite.deob.execution.Variables;
|
||||||
import net.runelite.deob.pool.Class;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
@@ -55,7 +53,7 @@ public class AStore extends Instruction implements LVTInstruction, WideInstructi
|
|||||||
StackContext object = stack.pop();
|
StackContext object = stack.pop();
|
||||||
ins.pop(object);
|
ins.pop(object);
|
||||||
|
|
||||||
variables.set(index, new VariableContext(ins, object.getType()));
|
variables.set(index, new VariableContext(ins, object));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class AStore_0 extends Instruction implements LVTInstruction
|
|||||||
StackContext object = stack.pop();
|
StackContext object = stack.pop();
|
||||||
ins.pop(object);
|
ins.pop(object);
|
||||||
|
|
||||||
variables.set(0, new VariableContext(ins, object.getType()));
|
variables.set(0, new VariableContext(ins, object));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class AStore_1 extends Instruction implements LVTInstruction
|
|||||||
StackContext object = stack.pop();
|
StackContext object = stack.pop();
|
||||||
ins.pop(object);
|
ins.pop(object);
|
||||||
|
|
||||||
variables.set(1, new VariableContext(ins, object.getType()));
|
variables.set(1, new VariableContext(ins, object));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class AStore_2 extends Instruction implements LVTInstruction
|
|||||||
StackContext object = stack.pop();
|
StackContext object = stack.pop();
|
||||||
ins.pop(object);
|
ins.pop(object);
|
||||||
|
|
||||||
variables.set(2, new VariableContext(ins, object.getType()));
|
variables.set(2, new VariableContext(ins, object));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class AStore_3 extends Instruction implements LVTInstruction
|
|||||||
StackContext object = stack.pop();
|
StackContext object = stack.pop();
|
||||||
ins.pop(object);
|
ins.pop(object);
|
||||||
|
|
||||||
variables.set(3, new VariableContext(ins, object.getType()));
|
variables.set(3, new VariableContext(ins, object));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class DStore extends Instruction implements LVTInstruction, WideInstructi
|
|||||||
StackContext value = stack.pop();
|
StackContext value = stack.pop();
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(index, new VariableContext(ins, value.getType()));
|
variables.set(index, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class DStore_0 extends Instruction implements LVTInstruction
|
|||||||
StackContext value = stack.pop();
|
StackContext value = stack.pop();
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(0, new VariableContext(ins, value.getType()));
|
variables.set(0, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class DStore_1 extends Instruction implements LVTInstruction
|
|||||||
StackContext value = stack.pop();
|
StackContext value = stack.pop();
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(1, new VariableContext(ins, value.getType()));
|
variables.set(1, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class DStore_2 extends Instruction implements LVTInstruction
|
|||||||
StackContext value = stack.pop();
|
StackContext value = stack.pop();
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(2, new VariableContext(ins, value.getType()));
|
variables.set(2, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class DStore_3 extends Instruction implements LVTInstruction
|
|||||||
StackContext value = stack.pop();
|
StackContext value = stack.pop();
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(3, new VariableContext(ins, value.getType()));
|
variables.set(3, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class FStore extends Instruction implements LVTInstruction, WideInstructi
|
|||||||
StackContext value = stack.pop();
|
StackContext value = stack.pop();
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(index, new VariableContext(ins, value.getType()));
|
variables.set(index, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class FStore_0 extends Instruction implements LVTInstruction
|
|||||||
StackContext value = stack.pop();
|
StackContext value = stack.pop();
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(0, new VariableContext(ins, value.getType()));
|
variables.set(0, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class FStore_1 extends Instruction implements LVTInstruction
|
|||||||
StackContext value = stack.pop();
|
StackContext value = stack.pop();
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(1, new VariableContext(ins, value.getType()));
|
variables.set(1, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class FStore_2 extends Instruction implements LVTInstruction
|
|||||||
StackContext value = stack.pop();
|
StackContext value = stack.pop();
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(2, new VariableContext(ins, value.getType()));
|
variables.set(2, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class FStore_3 extends Instruction implements LVTInstruction
|
|||||||
StackContext value = stack.pop();
|
StackContext value = stack.pop();
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(3, new VariableContext(ins, value.getType()));
|
variables.set(3, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class IInc extends Instruction implements LVTInstruction, WideInstruction
|
|||||||
assert vctx.getType().equals(new Type(int.class.getCanonicalName()));
|
assert vctx.getType().equals(new Type(int.class.getCanonicalName()));
|
||||||
ins.read(vctx);
|
ins.read(vctx);
|
||||||
|
|
||||||
vctx = new VariableContext(ins, vctx.getType());
|
vctx = new VariableContext(ins, vctx.getStackContext()); // XXX this is probably not right.
|
||||||
var.set(index, vctx);
|
var.set(index, vctx);
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class IStore extends Instruction implements LVTInstruction, WideInstructi
|
|||||||
assert value.getType().equals(new Type(int.class.getName()));
|
assert value.getType().equals(new Type(int.class.getName()));
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(index, new VariableContext(ins, value.getType()));
|
variables.set(index, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class IStore_0 extends Instruction implements LVTInstruction
|
|||||||
assert value.getType().equals(new Type(int.class.getName()));
|
assert value.getType().equals(new Type(int.class.getName()));
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(0, new VariableContext(ins, value.getType()));
|
variables.set(0, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class IStore_1 extends Instruction implements LVTInstruction
|
|||||||
assert value.getType().equals(new Type(int.class.getName()));
|
assert value.getType().equals(new Type(int.class.getName()));
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(1, new VariableContext(ins, value.getType()));
|
variables.set(1, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class IStore_2 extends Instruction implements LVTInstruction
|
|||||||
assert value.getType().equals(new Type(int.class.getName()));
|
assert value.getType().equals(new Type(int.class.getName()));
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(2, new VariableContext(ins, value.getType()));
|
variables.set(2, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class IStore_3 extends Instruction implements LVTInstruction
|
|||||||
assert value.getType().equals(new Type(int.class.getName()));
|
assert value.getType().equals(new Type(int.class.getName()));
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(3, new VariableContext(ins, value.getType()));
|
variables.set(3, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import java.io.DataOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import net.runelite.deob.execution.Execution;
|
||||||
|
|
||||||
public class InvokeInterface extends Instruction implements InvokeInstruction
|
public class InvokeInterface extends Instruction implements InvokeInstruction
|
||||||
{
|
{
|
||||||
@@ -102,8 +103,16 @@ public class InvokeInterface extends Instruction implements InvokeInstruction
|
|||||||
for (net.runelite.deob.Method method : getMethods())
|
for (net.runelite.deob.Method method : getMethods())
|
||||||
{
|
{
|
||||||
ins.invoke(method);
|
ins.invoke(method);
|
||||||
|
|
||||||
|
if (method.getCode() == null)
|
||||||
|
{
|
||||||
|
frame.getExecution().methods.add(method);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// add possible method call to execution
|
// add possible method call to execution
|
||||||
frame.getExecution().addMethod(method);
|
Execution execution = frame.getExecution();
|
||||||
|
execution.invoke(ins, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.io.DataOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import net.runelite.deob.execution.Execution;
|
||||||
|
|
||||||
public class InvokeSpecial extends Instruction implements InvokeInstruction
|
public class InvokeSpecial extends Instruction implements InvokeInstruction
|
||||||
{
|
{
|
||||||
@@ -88,8 +89,16 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction
|
|||||||
for (net.runelite.deob.Method method : getMethods())
|
for (net.runelite.deob.Method method : getMethods())
|
||||||
{
|
{
|
||||||
ins.invoke(method);
|
ins.invoke(method);
|
||||||
|
|
||||||
|
if (method.getCode() == null)
|
||||||
|
{
|
||||||
|
frame.getExecution().methods.add(method);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// add possible method call to execution
|
// add possible method call to execution
|
||||||
frame.getExecution().addMethod(method);
|
Execution execution = frame.getExecution();
|
||||||
|
execution.invoke(ins, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.io.DataOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import net.runelite.deob.execution.Execution;
|
||||||
|
|
||||||
public class InvokeStatic extends Instruction implements InvokeInstruction
|
public class InvokeStatic extends Instruction implements InvokeInstruction
|
||||||
{
|
{
|
||||||
@@ -85,8 +86,16 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
|
|||||||
for (net.runelite.deob.Method method : getMethods())
|
for (net.runelite.deob.Method method : getMethods())
|
||||||
{
|
{
|
||||||
ins.invoke(method);
|
ins.invoke(method);
|
||||||
|
|
||||||
|
if (method.getCode() == null)
|
||||||
|
{
|
||||||
|
frame.getExecution().methods.add(method);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// add possible method call to execution
|
// add possible method call to execution
|
||||||
frame.getExecution().addMethod(method);
|
Execution execution = frame.getExecution();
|
||||||
|
execution.invoke(ins, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.io.DataOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import net.runelite.deob.execution.Execution;
|
||||||
|
|
||||||
public class InvokeVirtual extends Instruction implements InvokeInstruction
|
public class InvokeVirtual extends Instruction implements InvokeInstruction
|
||||||
{
|
{
|
||||||
@@ -71,8 +72,16 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction
|
|||||||
for (net.runelite.deob.Method method : getMethods())
|
for (net.runelite.deob.Method method : getMethods())
|
||||||
{
|
{
|
||||||
ins.invoke(method);
|
ins.invoke(method);
|
||||||
|
|
||||||
|
if (method.getCode() == null)
|
||||||
|
{
|
||||||
|
frame.getExecution().methods.add(method);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// add possible method call to execution
|
// add possible method call to execution
|
||||||
frame.getExecution().addMethod(method);
|
Execution execution = frame.getExecution();
|
||||||
|
execution.invoke(ins, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class LStore extends Instruction implements LVTInstruction, WideInstructi
|
|||||||
assert value.getType().equals(new Type(long.class.getName()));
|
assert value.getType().equals(new Type(long.class.getName()));
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(index, new VariableContext(ins, value.getType()));
|
variables.set(index, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class LStore_0 extends Instruction implements LVTInstruction
|
|||||||
assert value.getType().equals(new Type(long.class.getName()));
|
assert value.getType().equals(new Type(long.class.getName()));
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(0, new VariableContext(ins, value.getType()));
|
variables.set(0, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class LStore_1 extends Instruction implements LVTInstruction
|
|||||||
assert value.getType().equals(new Type(long.class.getName()));
|
assert value.getType().equals(new Type(long.class.getName()));
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(1, new VariableContext(ins, value.getType()));
|
variables.set(1, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class LStore_2 extends Instruction implements LVTInstruction
|
|||||||
assert value.getType().equals(new Type(long.class.getName()));
|
assert value.getType().equals(new Type(long.class.getName()));
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(2, new VariableContext(ins, value.getType()));
|
variables.set(2, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class LStore_3 extends Instruction implements LVTInstruction
|
|||||||
assert value.getType().equals(new Type(long.class.getName()));
|
assert value.getType().equals(new Type(long.class.getName()));
|
||||||
ins.pop(value);
|
ins.pop(value);
|
||||||
|
|
||||||
variables.set(3, new VariableContext(ins, value.getType()));
|
variables.set(3, new VariableContext(ins, value));
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,18 +7,20 @@ import net.runelite.deob.Method;
|
|||||||
import net.runelite.deob.attributes.code.Instruction;
|
import net.runelite.deob.attributes.code.Instruction;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import org.apache.commons.collections4.map.MultiValueMap;
|
||||||
|
|
||||||
public class Execution
|
public class Execution
|
||||||
{
|
{
|
||||||
private ClassGroup group;
|
private ClassGroup group;
|
||||||
public List<Frame> frames = new ArrayList<>(),
|
public List<Frame> frames = new ArrayList<>(),
|
||||||
processedFrames = new ArrayList<>();
|
processedFrames = new ArrayList<>();
|
||||||
private List<Method> pendingMethods = new ArrayList<>(); // pending methods
|
|
||||||
public Set<Method> methods = new HashSet<>(); // all methods
|
public Set<Method> methods = new HashSet<>(); // all methods
|
||||||
public Set<Instruction> executed = new HashSet<>(); // executed instructions
|
public Set<Instruction> executed = new HashSet<>(); // executed instructions
|
||||||
|
private MultiValueMap<InstructionContext, Method> invokes = new MultiValueMap<>();
|
||||||
|
|
||||||
public Execution(ClassGroup group)
|
public Execution(ClassGroup group)
|
||||||
{
|
{
|
||||||
@@ -30,58 +32,62 @@ public class Execution
|
|||||||
for (ClassFile cf : group.getClasses())
|
for (ClassFile cf : group.getClasses())
|
||||||
{
|
{
|
||||||
for (Method m : cf.getMethods().getMethods())
|
for (Method m : cf.getMethods().getMethods())
|
||||||
{
|
{
|
||||||
if (!Deob.isObfuscated(m.getName()) && !m.getName().equals("<init>"))
|
if (!Deob.isObfuscated(m.getName()) && !m.getName().equals("<init>"))
|
||||||
{
|
{
|
||||||
addMethod(m); // I guess this method name is overriding a jre interface (init, run, ?).
|
if (m.getCode() == null)
|
||||||
|
{
|
||||||
|
methods.add(m);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Frame frame = new Frame(this, m);
|
||||||
|
frame.initialize();
|
||||||
|
addFrame(frame); // I guess this method name is overriding a jre interface (init, run, ?).
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMethod(Method method)
|
private boolean hasInvoked(InstructionContext from, Method to)
|
||||||
{
|
{
|
||||||
assert method != null;
|
Collection<Method> methods = invokes.getCollection(from);
|
||||||
|
if (methods != null && methods.contains(to))
|
||||||
|
return true;
|
||||||
|
|
||||||
if (methods.contains(method))
|
invokes.put(from, to);
|
||||||
return; // already processed
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFrame(Frame frame)
|
||||||
|
{
|
||||||
|
frames.add(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void invoke(InstructionContext from, Method to)
|
||||||
|
{
|
||||||
|
if (hasInvoked(from, to))
|
||||||
|
return;
|
||||||
|
|
||||||
pendingMethods.add(method);
|
Frame f = new Frame(this, to);
|
||||||
methods.add(method);
|
f.initialize(from);
|
||||||
|
this.addFrame(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run()
|
public void run()
|
||||||
{
|
|
||||||
int count = 0, fcount = 0;
|
|
||||||
while (!pendingMethods.isEmpty())
|
|
||||||
{
|
|
||||||
Method method = pendingMethods.remove(0);
|
|
||||||
|
|
||||||
if (method.getCode() == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Frame f = new Frame(this, method);
|
|
||||||
frames.add(f);
|
|
||||||
|
|
||||||
fcount += this.runFrames();
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Processed " + count + " methods and " + fcount + " paths");
|
|
||||||
}
|
|
||||||
|
|
||||||
private int runFrames()
|
|
||||||
{
|
{
|
||||||
int fcount = 0;
|
int fcount = 0;
|
||||||
|
|
||||||
while (!frames.isEmpty())
|
while (!frames.isEmpty())
|
||||||
{
|
{
|
||||||
Frame frame = frames.remove(0);
|
Frame frame = frames.remove(0);
|
||||||
|
|
||||||
|
methods.add(frame.getMethod());
|
||||||
|
|
||||||
++fcount;
|
++fcount;
|
||||||
frame.execute();
|
frame.execute();
|
||||||
processedFrames.add(frame);
|
processedFrames.add(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fcount;
|
System.out.println("Processed " + fcount + " frames");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.runelite.deob.execution;
|
package net.runelite.deob.execution;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -15,6 +16,7 @@ import net.runelite.deob.attributes.code.instructions.TableSwitch;
|
|||||||
import net.runelite.deob.pool.NameAndType;
|
import net.runelite.deob.pool.NameAndType;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction;
|
||||||
import org.apache.commons.collections4.MultiMap;
|
import org.apache.commons.collections4.MultiMap;
|
||||||
import org.apache.commons.collections4.map.MultiValueMap;
|
import org.apache.commons.collections4.map.MultiValueMap;
|
||||||
|
|
||||||
@@ -38,19 +40,52 @@ public class Frame
|
|||||||
|
|
||||||
stack = new Stack(code.getMaxStack());
|
stack = new Stack(code.getMaxStack());
|
||||||
variables = new Variables(code.getMaxLocals());
|
variables = new Variables(code.getMaxLocals());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize()
|
||||||
|
{
|
||||||
// initialize LVT
|
// initialize LVT
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
if (!method.isStatic())
|
if (!method.isStatic())
|
||||||
variables.set(pos++, new VariableContext(null, new Type(method.getMethods().getClassFile().getName())));
|
variables.set(pos++, new VariableContext(new Type(method.getMethods().getClassFile().getName())));
|
||||||
|
|
||||||
NameAndType nat = method.getNameAndType();
|
NameAndType nat = method.getNameAndType();
|
||||||
for (int i = 0; i < nat.getNumberOfArgs(); ++i)
|
for (int i = 0; i < nat.getNumberOfArgs(); ++i)
|
||||||
{
|
{
|
||||||
variables.set(pos, new VariableContext(null, new Type(nat.getDescriptor().getTypeOfArg(i)).toStackType()));
|
variables.set(pos, new VariableContext(new Type(nat.getDescriptor().getTypeOfArg(i)).toStackType()));
|
||||||
pos += nat.getDescriptor().getTypeOfArg(i).getSlots();
|
pos += nat.getDescriptor().getTypeOfArg(i).getSlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Code code = method.getCode();
|
||||||
|
cur = code.getInstructions().getInstructions().get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize(InstructionContext ctx)
|
||||||
|
{
|
||||||
|
// initialize frame from invoking context
|
||||||
|
assert ctx.getInstruction() instanceof InvokeInstruction;
|
||||||
|
|
||||||
|
// initialize LVT. the last argument is popped first, and is at arguments[0]
|
||||||
|
List<StackContext> pops = ctx.getPops();
|
||||||
|
pops = Lists.reverse(new ArrayList<>(pops)); // reverse the list so first argument is at index 0
|
||||||
|
|
||||||
|
int lvtOffset = 0;
|
||||||
|
if (!method.isStatic())
|
||||||
|
variables.set(lvtOffset++, new VariableContext(ctx, pops.remove(0)));
|
||||||
|
|
||||||
|
NameAndType nat = method.getNameAndType();
|
||||||
|
|
||||||
|
for (int i = 0; i < nat.getNumberOfArgs(); ++i)
|
||||||
|
{
|
||||||
|
StackContext argument = pops.remove(0);
|
||||||
|
|
||||||
|
variables.set(lvtOffset, new VariableContext(ctx, argument));//new Type(nat.getDescriptor().getTypeOfArg(i)).toStackType()));
|
||||||
|
lvtOffset += nat.getDescriptor().getTypeOfArg(i).getSlots();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert pops.isEmpty();
|
||||||
|
|
||||||
|
Code code = method.getCode();
|
||||||
cur = code.getInstructions().getInstructions().get(0);
|
cur = code.getInstructions().getInstructions().get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ public class InstructionContext
|
|||||||
Stack ours = new Stack(this.getStack()), // copy stacks since we destroy them
|
Stack ours = new Stack(this.getStack()), // copy stacks since we destroy them
|
||||||
theirs = new Stack(ic.getStack());
|
theirs = new Stack(ic.getStack());
|
||||||
|
|
||||||
if (ours.getSize() != theirs.getSize())
|
if (ours.getSize() != theirs.getSize()) // is this possible?
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (ours.getSize() > 0)
|
while (ours.getSize() > 0)
|
||||||
|
|||||||
@@ -2,13 +2,25 @@ package net.runelite.deob.execution;
|
|||||||
|
|
||||||
public class VariableContext
|
public class VariableContext
|
||||||
{
|
{
|
||||||
private InstructionContext ic;
|
private StackContext ctx; // the value stored
|
||||||
|
private InstructionContext ic; // the instruction which stored it. also ctx.popped?
|
||||||
private Type type;
|
private Type type;
|
||||||
|
|
||||||
public VariableContext(InstructionContext i, Type t)
|
public VariableContext(InstructionContext i, StackContext ctx)
|
||||||
{
|
{
|
||||||
ic = i;
|
ic = i;
|
||||||
type = t;
|
this.ctx = ctx;
|
||||||
|
type = ctx.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public VariableContext(Type type) // for entrypoints
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StackContext getStackContext()
|
||||||
|
{
|
||||||
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getType()
|
public Type getType()
|
||||||
|
|||||||
Reference in New Issue
Block a user