Import runeloader inject system
This commit is contained in:
15
pom.xml
15
pom.xml
@@ -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>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package net.runelite.deob.inject;
|
||||
|
||||
public class AddFieldInstruction {
|
||||
public static String owner;
|
||||
public static String name;
|
||||
public static String desc;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
105
src/main/java/net/runelite/deob/inject/TableJumpInstruction.java
Normal file
105
src/main/java/net/runelite/deob/inject/TableJumpInstruction.java
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user