Import runeloader inject system

This commit is contained in:
Adam
2015-11-22 09:04:10 -06:00
parent 792446c8fb
commit 98a24c954b
11 changed files with 558 additions and 10 deletions

15
pom.xml
View File

@@ -24,21 +24,16 @@
<artifactId>commons-compress</artifactId>
<version>1.10</version>
</dependency>
<!-- <dependency>
<groupId>edu.ucla.sspace</groupId>
<artifactId>sspace</artifactId>
<version>2.0.4</version>
</dependency>-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.4</version>
</dependency>
<!-- <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>-->
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-all</artifactId>
<version>5.0.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>

View File

@@ -0,0 +1,7 @@
package net.runelite.deob.inject;
public class AddFieldInstruction {
public static String owner;
public static String name;
public static String desc;
}

View File

@@ -0,0 +1,29 @@
package net.runelite.deob.inject;
import org.objectweb.asm.tree.ClassNode;
public class AddInterfaceInstruction {
private final String clientClass;
private final String interfaceClass;
public AddInterfaceInstruction(String var1, String var2) {
this.clientClass = var1;
this.interfaceClass = var2;
}
public String getClientClass() {
return this.clientClass;
}
public String getInterfaceClass() {
return this.interfaceClass;
}
public boolean valid(ClassNode var1) {
return var1.name.equalsIgnoreCase(this.clientClass);
}
public void inject(ClassNode var1) {
var1.interfaces.add(this.interfaceClass);
}
}

View File

@@ -0,0 +1,37 @@
package net.runelite.deob.inject;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
public class AddMethodInstruction {
private final String clientClass;
private final String methodName;
private final String methodDesc;
private final AbstractInsnNode[] instructions;
public AddMethodInstruction(String var1, String var2, String var3, AbstractInsnNode[] var4) {
this.clientClass = var1;
this.methodName = var2;
this.methodDesc = var3;
this.instructions = var4;
}
public boolean valid(ClassNode var1) {
return var1.name.equalsIgnoreCase(this.clientClass);
}
public void inject(ClassNode var1) {
MethodNode var2 = new MethodNode(1, this.methodName, this.methodDesc, (String)null, (String[])null);
AbstractInsnNode[] var6 = this.instructions;
int var5 = this.instructions.length;
for(int var4 = 0; var4 < var5; ++var4) {
AbstractInsnNode var3 = var6[var4];
var2.instructions.add(var3);
}
var2.visitMaxs(0, 0);
var1.methods.add(var2);
}
}

View File

@@ -0,0 +1,149 @@
package net.runelite.deob.inject;
import java.util.Iterator;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
public class GetterInjectInstruction {
private final String className;
private final String getterMethodDesc;
private final String getterName;
private final String getterClassName;
private final String getterFieldName;
private final Integer multiplier;
private final boolean staticField;
public GetterInjectInstruction(String var1, String var2, String var3, String var4, String var5, Integer var6, boolean var7) {
this.className = var1;
this.getterMethodDesc = "()" + var3;
this.getterName = var2;
this.getterClassName = var4;
this.getterFieldName = var5;
this.multiplier = var6;
this.staticField = var7;
}
public String getClassName() {
return this.className;
}
public String getGetterMethodDesc() {
return this.getterMethodDesc;
}
public String getGetterName() {
return this.getterName;
}
public String getGetterClassName() {
return this.getterClassName;
}
public String getGetterFieldName() {
return this.getterFieldName;
}
public Integer getMultiplier() {
return this.multiplier;
}
public boolean isStaticField() {
return this.staticField;
}
//
// public boolean valid(ClassNode var1) {
// return var1.name.equalsIgnoreCase(this.className);
// }
//
// private FieldNode get(qelKbskphK[] var1) {
// qelKbskphK[] var5 = var1;
// int var4 = var1.length;
//
// for(int var3 = 0; var3 < var4; ++var3) {
// qelKbskphK var2 = var5[var3];
// ClassNode var6 = var2.KxdZMCzVTn();
// if(var6.name.equalsIgnoreCase(this.getterClassName)) {
// Iterator var8 = var6.fields.iterator();
//
// while(var8.hasNext()) {
// FieldNode var7 = (FieldNode)var8.next();
// if(var7.name.equalsIgnoreCase(this.getterFieldName)) {
// return var7;
// }
// }
// }
// }
//
// return null;
// }
//
// public void inject(ClassNode var1, qelKbskphK[] var2) {
// String var3 = this.getGetterMethodDesc().substring(2);
// MethodNode var4 = new MethodNode(1, this.getGetterName(), this.getGetterMethodDesc(), (String)null, (String[])null);
// if(!this.isStaticField()) {
// var4.instructions.add(new VarInsnNode(25, 0));
// }
//
// int var5 = this.isStaticField()?178:180;
// var4.instructions.add(new FieldInsnNode(var5, this.getterClassName, this.getterFieldName, this.get(var2).desc));
// if(this.getMultiplier() != null) {
// var4.instructions.add(new LdcInsnNode(this.getMultiplier()));
// var4.instructions.add(new InsnNode(104));
// }
//
// var4.instructions.add(new InsnNode(getReturn(Type.getReturnType(var3).getSort())));
// var1.methods.add(var4);
// }
//
// public static int getReturn(int var0) {
// return var0 == 0?177:(var0 >= 1 && var0 <= 5?172:(var0 == 6?174:(var0 == 7?173:(var0 == 8?175:176))));
// }
//
// private int getReturnOpcode(String var1) {
// var1 = var1.substring(var1.indexOf(")") + 1);
// if(var1.length() > 1) {
// return 176;
// } else {
// char var2 = var1.charAt(0);
// switch(var2) {
// case 'B':
// case 'C':
// case 'I':
// case 'S':
// case 'Z':
// return 172;
// case 'D':
// return 175;
// case 'E':
// case 'G':
// case 'H':
// case 'K':
// case 'L':
// case 'M':
// case 'N':
// case 'O':
// case 'P':
// case 'Q':
// case 'R':
// case 'T':
// case 'U':
// case 'V':
// case 'W':
// case 'X':
// case 'Y':
// default:
// throw new RuntimeException("bad_return");
// case 'F':
// return 174;
// case 'J':
// return 173;
// }
// }
// }
}

View File

@@ -0,0 +1,60 @@
package net.runelite.deob.inject;
import com.google.common.io.Files;
import com.google.gson.GsonBuilder;
import com.runeloader.RuneLoader;
import com.runeloader.api.inject.InstructionDeserializer;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import org.objectweb.asm.tree.AbstractInsnNode;
public class InjectionModscript {
private List getterInjects = new LinkedList();
private List superChangeInjects = new LinkedList();
private List addInterfaceInjects = new LinkedList();
private List methodMods = new LinkedList();
private List addMethods = new LinkedList();
private List newMethodMods = new LinkedList();
public void save() {
byte[] var1 = (new GsonBuilder()).setPrettyPrinting().create().toJson(this).getBytes();
try {
Files.write(var1, new File("injection.json"));
} catch (IOException var3) {
var3.printStackTrace();
}
}
public static InjectionModscript load(File var0) throws IOException {
byte[] var1 = Files.toByteArray(var0);
return (InjectionModscript)(new GsonBuilder()).registerTypeAdapter(AbstractInsnNode.class, new InstructionDeserializer()).create().fromJson((new String(var1)).replaceAll("runecore", "runeloader"), InjectionModscript.class);
}
public List getGetterInjects() {
return this.getterInjects;
}
public List getSuperChangeInjects() {
return this.superChangeInjects;
}
public List getAddInterfaceInjects() {
return this.addInterfaceInjects;
}
public List getMethodMods() {
return this.methodMods;
}
public List getAddMethods() {
return this.addMethods;
}
public List getNewMethodMods() {
return this.newMethodMods;
}
}

View File

@@ -0,0 +1,57 @@
package net.runelite.deob.inject;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.lang.reflect.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
public class InstructionDeserializer implements JsonDeserializer {
public AbstractInsnNode deserialize(JsonElement var1, Type var2, JsonDeserializationContext var3) {
JsonObject var4 = (JsonObject)var1;
int var5 = var4.get("opcode").getAsInt();
if(var5 != 21 && var5 != 25 && var5 != 58 && var5 != 54 && var5 != 22) {
String var7;
String var8;
String var10;
if(var5 != 184 && var5 != 182 && var5 != 183) {
if(var5 == 18) {
try {
return new LdcInsnNode(Integer.valueOf(var4.get("cst").getAsInt()));
} catch (Exception var9) {
return new LdcInsnNode(var4.get("cst").getAsString());
}
} else if(var5 == 187) {
return new TypeInsnNode(var5, var4.get("desc").getAsString());
} else if(var5 != 16 && var5 != 17) {
if(var5 != 179 && var5 != 178 && var5 != 180 && var5 != 181) {
return new InsnNode(var5);
} else {
var10 = var4.get("owner").getAsString();
var7 = var4.get("name").getAsString();
var8 = var4.get("desc").getAsString();
return new FieldInsnNode(var5, var10, var7, var8);
}
} else {
return new IntInsnNode(var5, var4.get("operand").getAsInt());
}
} else {
var10 = var4.get("owner").getAsString();
var7 = var4.get("name").getAsString();
var8 = var4.get("desc").getAsString();
return new MethodInsnNode(var5, var10, var7, var8);
}
} else {
int var6 = var4.get("var").getAsInt();
return new VarInsnNode(var5, var6);
}
}
}

View File

@@ -0,0 +1,64 @@
package net.runelite.deob.inject;
import java.util.Iterator;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.MethodNode;
public class MethodModInstruction {
private final int startIndex;
private final AbstractInsnNode[] nodes;
public final String owner;
public final String method;
public final String desc;
public MethodModInstruction(int var1, AbstractInsnNode[] var2, String var3, String var4, String var5) {
this.startIndex = var1;
this.nodes = var2;
this.owner = var3;
this.method = var4;
this.desc = var5;
}
public boolean valid(ClassNode var1) {
return var1.name.equalsIgnoreCase(this.owner);
}
public void inject(ClassNode var1) {
Iterator var3 = var1.methods.iterator();
while(true) {
MethodNode var2;
do {
do {
if(!var3.hasNext()) {
return;
}
var2 = (MethodNode)var3.next();
} while(!var2.name.equalsIgnoreCase(this.method));
} while(!var2.desc.equalsIgnoreCase(this.desc));
InsnList var4 = var2.instructions;
try {
AbstractInsnNode var5 = var4.get(this.startIndex);
AbstractInsnNode var6 = null;
for(int var7 = 0; var7 < this.nodes.length; ++var7) {
if(var6 == null) {
var4.insertBefore(var5, this.nodes[var7]);
} else {
var4.insert(var6, this.nodes[var7]);
}
var6 = this.nodes[var7];
}
} catch (Exception var8) {
System.err.println("Failed on " + this.startIndex + " @ " + this.owner + "." + this.method + " " + this.desc);
var8.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,29 @@
package net.runelite.deob.inject;
import org.objectweb.asm.tree.ClassNode;
public class SuperChangeInstruction {
private final String clientName;
private final String superName;
public SuperChangeInstruction(String var1, String var2) {
this.clientName = var1;
this.superName = var2;
}
public String getClientName() {
return this.clientName;
}
public String getSuperName() {
return this.superName;
}
public boolean valid(ClassNode var1) {
return var1.name.equalsIgnoreCase(this.clientName);
}
public void inject(ClassNode var1) {
var1.superName = this.superName;
}
}

View File

@@ -0,0 +1,16 @@
package net.runelite.deob.inject;
import org.objectweb.asm.Label;
public class TableJumpInstruction$TableJump {
public Label label;
public final int instructionIndex;
public final int labelArrayIndex;
public final int opcode;
public TableJumpInstruction$TableJump(int var1, int var2, int var3) {
this.instructionIndex = var1;
this.opcode = var3;
this.labelArrayIndex = var2;
}
}

View File

@@ -0,0 +1,105 @@
package net.runelite.deob.inject;
import java.util.Iterator;
import org.objectweb.asm.Label;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.MethodNode;
public class TableJumpInstruction {
private final TableJumpInstruction$TableJump[] tableJumps;
private final int[] labels;
private final int start;
private final AbstractInsnNode[] instructions;
private final String owner;
private final String name;
private final String desc;
public TableJumpInstruction(TableJumpInstruction$TableJump[] var1, AbstractInsnNode[] var2, int[] var3, int var4, String var5, String var6, String var7) {
this.tableJumps = var1;
this.instructions = var2;
this.labels = var3;
this.owner = var5;
this.name = var6;
this.desc = var7;
this.start = var4;
}
public boolean valid(ClassNode var1) {
return var1.name.equalsIgnoreCase(this.owner);
}
public void inject(ClassNode var1) {
Iterator var3 = var1.methods.iterator();
MethodNode var2;
do {
if(!var3.hasNext()) {
return;
}
var2 = (MethodNode)var3.next();
} while(!var2.name.equalsIgnoreCase(this.name) || !var2.desc.equalsIgnoreCase(this.desc));
this.insert(var2);
}
private void insert(MethodNode var1) {
AbstractInsnNode[] var2 = new AbstractInsnNode[this.instructions.length];
Label[] var3 = new Label[this.labels.length];
InsnList var4 = var1.instructions;
int var5;
for(var5 = 0; var5 < this.labels.length; ++var5) {
int var6 = this.labels[var5];
if(var6 == -1) {
var3[var5] = new Label();
} else {
JumpInsnNode var7 = (JumpInsnNode)var4.get(var6);
var3[var5] = var7.label.getLabel();
}
}
for(var5 = 0; var5 < this.instructions.length; ++var5) {
Object var11 = this.instructions[var5];
if(var11 == null) {
TableJumpInstruction$TableJump var12 = this.getJump(var5);
LabelNode var8 = new LabelNode(var3[var12.labelArrayIndex]);
if(var12.opcode != 9000) {
var11 = new JumpInsnNode(var12.opcode, var8);
} else {
var11 = var8;
}
}
var2[var5] = (AbstractInsnNode)var11;
}
AbstractInsnNode var10 = var4.get(this.start);
AbstractInsnNode[] var9 = var2;
int var15 = var2.length;
for(int var13 = 0; var13 < var15; ++var13) {
AbstractInsnNode var14 = var9[var13];
var4.insertBefore(var10, var14);
}
}
private TableJumpInstruction$TableJump getJump(int var1) {
TableJumpInstruction$TableJump[] var5 = this.tableJumps;
int var4 = this.tableJumps.length;
for(int var3 = 0; var3 < var4; ++var3) {
TableJumpInstruction$TableJump var2 = var5[var3];
if(var2.instructionIndex == var1) {
return var2;
}
}
return null;
}
}