Merge pull request #543 from Lucwousin/iodsangoisndiognadsoihnioadsfnhoidafsniogndsaiohgnoifdsanhiosnd
Add menu raw injector
This commit is contained in:
@@ -203,9 +203,16 @@ public class Method
|
|||||||
return (accessFlags & ACC_STATIC) != 0;
|
return (accessFlags & ACC_STATIC) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStatic()
|
public void setStatic(boolean s)
|
||||||
{
|
{
|
||||||
accessFlags |= ACC_STATIC;
|
if (s)
|
||||||
|
{
|
||||||
|
accessFlags |= ACC_STATIC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
accessFlags &= ~ACC_STATIC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSynchronized()
|
public boolean isSynchronized()
|
||||||
|
|||||||
@@ -27,14 +27,10 @@ package net.runelite.deob;
|
|||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import net.runelite.asm.ClassFile;
|
|
||||||
import net.runelite.asm.ClassGroup;
|
import net.runelite.asm.ClassGroup;
|
||||||
import net.runelite.asm.Field;
|
|
||||||
import net.runelite.asm.Method;
|
|
||||||
import net.runelite.asm.Type;
|
|
||||||
import net.runelite.asm.attributes.Annotations;
|
|
||||||
import net.runelite.asm.execution.Execution;
|
import net.runelite.asm.execution.Execution;
|
||||||
import net.runelite.deob.deobfuscators.CastNull;
|
import net.runelite.deob.deobfuscators.CastNull;
|
||||||
|
import net.runelite.deob.deobfuscators.StaticShouldBeInstance;
|
||||||
import net.runelite.deob.deobfuscators.constparam.ConstantParameter;
|
import net.runelite.deob.deobfuscators.constparam.ConstantParameter;
|
||||||
import net.runelite.deob.deobfuscators.EnumDeobfuscator;
|
import net.runelite.deob.deobfuscators.EnumDeobfuscator;
|
||||||
import net.runelite.deob.deobfuscators.FieldInliner;
|
import net.runelite.deob.deobfuscators.FieldInliner;
|
||||||
@@ -85,85 +81,70 @@ public class Deob
|
|||||||
|
|
||||||
ClassGroup group = JarUtil.loadJar(new File(args[0]));
|
ClassGroup group = JarUtil.loadJar(new File(args[0]));
|
||||||
|
|
||||||
for (ClassFile f : group.getClasses())
|
if (args.length > 2 && args[2].equals("rl"))
|
||||||
{
|
{
|
||||||
f.getAnnotations().clearAnnotations();
|
run(group, new StaticShouldBeInstance());
|
||||||
for (Method m : f.getMethods())
|
|
||||||
{
|
|
||||||
Annotations an = m.getAnnotations();
|
|
||||||
an.clearAnnotations();
|
|
||||||
}
|
|
||||||
for (Field fi : f.getFields())
|
|
||||||
{
|
|
||||||
Annotations an = fi.getAnnotations();
|
|
||||||
if (an.find(new Type("Ljavax/inject/Inject;")) == null)
|
|
||||||
{
|
|
||||||
an.clearAnnotations();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.info("Class {}, field {} has inject", f.getClassName(), fi.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// remove except RuntimeException
|
||||||
|
run(group, new RuntimeExceptions());
|
||||||
|
|
||||||
// remove except RuntimeException
|
run(group, new ControlFlowDeobfuscator());
|
||||||
run(group, new RuntimeExceptions());
|
|
||||||
|
|
||||||
run(group, new ControlFlowDeobfuscator());
|
run(group, new RenameUnique());
|
||||||
|
|
||||||
run(group, new RenameUnique());
|
// remove unused methods - this leaves Code with no instructions,
|
||||||
|
// which is not valid, so unused methods is run after
|
||||||
|
run(group, new UnreachedCode());
|
||||||
|
run(group, new UnusedMethods());
|
||||||
|
|
||||||
// remove unused methods - this leaves Code with no instructions,
|
// remove illegal state exceptions, frees up some parameters
|
||||||
// which is not valid, so unused methods is run after
|
run(group, new IllegalStateExceptions());
|
||||||
run(group, new UnreachedCode());
|
|
||||||
run(group, new UnusedMethods());
|
|
||||||
|
|
||||||
// remove illegal state exceptions, frees up some parameters
|
// remove constant logically dead parameters
|
||||||
run(group, new IllegalStateExceptions());
|
run(group, new ConstantParameter());
|
||||||
|
|
||||||
// remove constant logically dead parameters
|
// remove unhit blocks
|
||||||
run(group, new ConstantParameter());
|
run(group, new UnreachedCode());
|
||||||
|
run(group, new UnusedMethods());
|
||||||
|
|
||||||
// remove unhit blocks
|
// remove unused parameters
|
||||||
run(group, new UnreachedCode());
|
run(group, new UnusedParameters());
|
||||||
run(group, new UnusedMethods());
|
|
||||||
|
|
||||||
// remove unused parameters
|
// remove unused fields
|
||||||
run(group, new UnusedParameters());
|
run(group, new UnusedFields());
|
||||||
|
|
||||||
// remove unused fields
|
run(group, new FieldInliner());
|
||||||
run(group, new UnusedFields());
|
|
||||||
|
|
||||||
run(group, new FieldInliner());
|
// order uses class name order for sorting fields/methods,
|
||||||
|
// so run it before removing classes below
|
||||||
|
run(group, new Order());
|
||||||
|
|
||||||
// order uses class name order for sorting fields/methods,
|
run(group, new UnusedClass());
|
||||||
// so run it before removing classes below
|
|
||||||
run(group, new Order());
|
|
||||||
|
|
||||||
run(group, new UnusedClass());
|
runMath(group);
|
||||||
|
|
||||||
runMath(group);
|
run(group, new ExprArgOrder());
|
||||||
|
|
||||||
run(group, new ExprArgOrder());
|
run(group, new Lvt());
|
||||||
|
|
||||||
run(group, new Lvt());
|
run(group, new CastNull());
|
||||||
|
|
||||||
run(group, new CastNull());
|
run(group, new EnumDeobfuscator());
|
||||||
|
|
||||||
run(group, new EnumDeobfuscator());
|
new OpcodesTransformer().transform(group);
|
||||||
|
//run(group, new PacketHandlerOrder());
|
||||||
|
//run(group, new PacketWriteDeobfuscator());
|
||||||
|
|
||||||
new OpcodesTransformer().transform(group);
|
run(group, new MenuActionDeobfuscator());
|
||||||
//run(group, new PacketHandlerOrder());
|
|
||||||
//run(group, new PacketWriteDeobfuscator());
|
|
||||||
|
|
||||||
run(group, new MenuActionDeobfuscator());
|
new GetPathTransformer().transform(group);
|
||||||
|
new ClientErrorTransformer().transform(group);
|
||||||
new GetPathTransformer().transform(group);
|
new ReflectionTransformer().transform(group);
|
||||||
new ClientErrorTransformer().transform(group);
|
new MaxMemoryTransformer().transform(group);
|
||||||
new ReflectionTransformer().transform(group);
|
//new RuneliteBufferTransformer().transform(group);
|
||||||
new MaxMemoryTransformer().transform(group);
|
}
|
||||||
//new RuneliteBufferTransformer().transform(group);
|
|
||||||
|
|
||||||
JarUtil.saveJar(group, new File(args[1]));
|
JarUtil.saveJar(group, new File(args[1]));
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
package net.runelite.deob.deobfuscators;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.runelite.asm.ClassFile;
|
||||||
|
import net.runelite.asm.ClassGroup;
|
||||||
|
import net.runelite.asm.Field;
|
||||||
|
import net.runelite.asm.Type;
|
||||||
|
import net.runelite.asm.attributes.Annotations;
|
||||||
|
import net.runelite.asm.attributes.Code;
|
||||||
|
import net.runelite.asm.attributes.code.Instruction;
|
||||||
|
import net.runelite.asm.attributes.code.Instructions;
|
||||||
|
import net.runelite.asm.attributes.code.instruction.types.ReturnInstruction;
|
||||||
|
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
||||||
|
import net.runelite.asm.attributes.code.instructions.InvokeVirtual;
|
||||||
|
import net.runelite.asm.pool.Method;
|
||||||
|
import net.runelite.asm.signature.Signature;
|
||||||
|
import net.runelite.deob.Deobfuscator;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class StaticShouldBeInstance implements Deobfuscator
|
||||||
|
{
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(StaticShouldBeInstance.class);
|
||||||
|
private static Map<Method, Method> methods = new HashMap<>();
|
||||||
|
|
||||||
|
public void run(ClassGroup group)
|
||||||
|
{
|
||||||
|
int replacedCalls = 0;
|
||||||
|
int removedInstructions = 0;
|
||||||
|
int removedMethods = 0;
|
||||||
|
int removedAnnotations = 0;
|
||||||
|
List<net.runelite.asm.Method> obfuscatedMethods = new ArrayList<>();
|
||||||
|
|
||||||
|
for (ClassFile cf : group.getClasses())
|
||||||
|
{
|
||||||
|
// Remove unused annotations
|
||||||
|
Annotations a = cf.getAnnotations();
|
||||||
|
removedAnnotations += a.getAnnotations().size();
|
||||||
|
a.clearAnnotations();
|
||||||
|
|
||||||
|
Type type = new Type('L' + cf.getClassName() + ';');
|
||||||
|
obfuscatedMethods.clear();
|
||||||
|
|
||||||
|
for (net.runelite.asm.Method m : cf.getMethods())
|
||||||
|
{
|
||||||
|
// Remove unused annotations
|
||||||
|
a = m.getAnnotations();
|
||||||
|
removedAnnotations += a.size();
|
||||||
|
a.clearAnnotations();
|
||||||
|
|
||||||
|
if (m.isStatic() && m.getCode() != null)
|
||||||
|
{
|
||||||
|
if (checkIfObf(m, type, cf))
|
||||||
|
{
|
||||||
|
removedMethods++;
|
||||||
|
obfuscatedMethods.add(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (net.runelite.asm.Method m : obfuscatedMethods)
|
||||||
|
{
|
||||||
|
Signature sig = m.getDescriptor();
|
||||||
|
Signature.Builder builder = new Signature.Builder();
|
||||||
|
builder.setReturnType(sig.getReturnValue());
|
||||||
|
if (sig.getArguments().size() > 1)
|
||||||
|
{
|
||||||
|
builder.addArguments(sig.getArguments().subList(1, sig.getArguments().size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Signature toFind = builder.build();
|
||||||
|
|
||||||
|
net.runelite.asm.Method notStatic = cf.findMethod(m.getName(), toFind);
|
||||||
|
net.runelite.asm.pool.Method oldPool = m.getPoolMethod();
|
||||||
|
cf.removeMethod(notStatic);
|
||||||
|
|
||||||
|
m.setDescriptor(toFind);
|
||||||
|
m.setStatic(false);
|
||||||
|
Code c = m.getCode();
|
||||||
|
Instructions ins = c.getInstructions();
|
||||||
|
int startLength = ins.getInstructions().size();
|
||||||
|
ListIterator<Instruction> it = ins.getInstructions().listIterator();
|
||||||
|
assert it.hasNext();
|
||||||
|
Instruction i = it.next();
|
||||||
|
while (!(i instanceof ReturnInstruction))
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
i = it.next();
|
||||||
|
}
|
||||||
|
it.remove();
|
||||||
|
net.runelite.asm.pool.Method newPool = m.getPoolMethod();
|
||||||
|
|
||||||
|
methods.put(oldPool, newPool);
|
||||||
|
|
||||||
|
removedInstructions += startLength - ins.getInstructions().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Field fi : cf.getFields())
|
||||||
|
{
|
||||||
|
a = fi.getAnnotations();
|
||||||
|
if (a.find(new Type("Ljavax/inject/Inject;")) == null)
|
||||||
|
{
|
||||||
|
removedAnnotations += a.size();
|
||||||
|
a.clearAnnotations();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.info("Class {}, field {} has inject", cf.getClassName(), fi.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ClassFile cf : group.getClasses())
|
||||||
|
{
|
||||||
|
for (net.runelite.asm.Method m : cf.getMethods())
|
||||||
|
{
|
||||||
|
if (m.getCode() == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Instructions ins = m.getCode().getInstructions();
|
||||||
|
List<Instruction> instructions = ins.getInstructions();
|
||||||
|
for (int i1 = 0, instructionsSize = instructions.size(); i1 < instructionsSize; i1++)
|
||||||
|
{
|
||||||
|
Instruction i = instructions.get(i1);
|
||||||
|
if (!(i instanceof InvokeStatic))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (methods.containsKey(((InvokeStatic) i).getMethod()))
|
||||||
|
{
|
||||||
|
InvokeVirtual invoke = new InvokeVirtual(ins, methods.get(((InvokeStatic) i).getMethod()));
|
||||||
|
ins.replace(i, invoke);
|
||||||
|
replacedCalls++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Made {} methods not static, removed {} instructions, replaced {} invokes, and removed {} annotations", removedMethods, removedInstructions, replacedCalls, removedAnnotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkIfObf(net.runelite.asm.Method m, Type type, ClassFile cf)
|
||||||
|
{
|
||||||
|
Signature sig = m.getDescriptor();
|
||||||
|
if (sig.getArguments().size() < 1 || !sig.getTypeOfArg(0).equals(type))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Signature.Builder builder = new Signature.Builder();
|
||||||
|
builder.setReturnType(sig.getReturnValue());
|
||||||
|
if (sig.getArguments().size() > 1)
|
||||||
|
{
|
||||||
|
builder.addArguments(sig.getArguments().subList(1, sig.getArguments().size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Signature toFind = builder.build();
|
||||||
|
|
||||||
|
net.runelite.asm.Method notStatic = cf.findMethod(m.getName(), toFind);
|
||||||
|
|
||||||
|
return notStatic != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -60,7 +60,7 @@ public class OpcodesTransformer implements Transformer
|
|||||||
if (clinit == null)
|
if (clinit == null)
|
||||||
{
|
{
|
||||||
clinit = new Method(runeliteOpcodes, "<clinit>", new Signature("()V"));
|
clinit = new Method(runeliteOpcodes, "<clinit>", new Signature("()V"));
|
||||||
clinit.setStatic();
|
clinit.setStatic(true);
|
||||||
Code code = new Code(clinit);
|
Code code = new Code(clinit);
|
||||||
code.setMaxStack(1);
|
code.setMaxStack(1);
|
||||||
clinit.setCode(code);
|
clinit.setCode(code);
|
||||||
|
|||||||
@@ -26,19 +26,24 @@ package net.runelite.deob.updater;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
import net.runelite.asm.ClassGroup;
|
import net.runelite.asm.ClassGroup;
|
||||||
|
import net.runelite.asm.Field;
|
||||||
|
import net.runelite.asm.Method;
|
||||||
|
import net.runelite.deob.deobfuscators.Renamer;
|
||||||
import net.runelite.deob.deobfuscators.mapping.AnnotationIntegrityChecker;
|
import net.runelite.deob.deobfuscators.mapping.AnnotationIntegrityChecker;
|
||||||
import net.runelite.deob.deobfuscators.mapping.AnnotationMapper;
|
import net.runelite.deob.deobfuscators.mapping.AnnotationMapper;
|
||||||
import net.runelite.deob.deobfuscators.mapping.Mapper;
|
import net.runelite.deob.deobfuscators.mapping.Mapper;
|
||||||
import net.runelite.deob.deobfuscators.mapping.ParallelExecutorMapping;
|
import net.runelite.deob.deobfuscators.mapping.ParallelExecutorMapping;
|
||||||
import net.runelite.deob.util.JarUtil;
|
import net.runelite.deob.util.JarUtil;
|
||||||
|
import net.runelite.deob.util.NameMappings;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class UpdateMappings
|
public class UpdateMappings
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(UpdateMappings.class);
|
private static final Logger logger = LoggerFactory.getLogger(UpdateMappings.class);
|
||||||
|
private static boolean renameRL = true;
|
||||||
private final ClassGroup group1, group2;
|
private final ClassGroup group1, group2;
|
||||||
|
|
||||||
public UpdateMappings(ClassGroup group1, ClassGroup group2)
|
public UpdateMappings(ClassGroup group1, ClassGroup group2)
|
||||||
@@ -74,6 +79,32 @@ public class UpdateMappings
|
|||||||
pr.run();
|
pr.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateRL()
|
||||||
|
{
|
||||||
|
Mapper mapper = new Mapper(group1, group2);
|
||||||
|
mapper.run();
|
||||||
|
ParallelExecutorMapping mapping = mapper.getMapping();
|
||||||
|
NameMappings names = new NameMappings();
|
||||||
|
|
||||||
|
for (Map.Entry<Object, Object> e : mapping.getMap().entrySet())
|
||||||
|
{
|
||||||
|
Object k = e.getKey();
|
||||||
|
Object v = e.getValue();
|
||||||
|
|
||||||
|
if (k instanceof Field)
|
||||||
|
{
|
||||||
|
names.map(((Field) v).getPoolField(), ((Field) k).getName());
|
||||||
|
}
|
||||||
|
else if (k instanceof Method)
|
||||||
|
{
|
||||||
|
names.map(((Method) v).getPoolMethod(), ((Method) k).getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Renamer renamer = new Renamer(names);
|
||||||
|
renamer.run(group2);
|
||||||
|
}
|
||||||
|
|
||||||
public void save(File out) throws IOException
|
public void save(File out) throws IOException
|
||||||
{
|
{
|
||||||
JarUtil.saveJar(group2, out);
|
JarUtil.saveJar(group2, out);
|
||||||
@@ -90,7 +121,14 @@ public class UpdateMappings
|
|||||||
JarUtil.loadJar(new File(args[0])),
|
JarUtil.loadJar(new File(args[0])),
|
||||||
JarUtil.loadJar(new File(args[1]))
|
JarUtil.loadJar(new File(args[1]))
|
||||||
);
|
);
|
||||||
u.update();
|
if (renameRL)
|
||||||
|
{
|
||||||
|
u.updateRL();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u.update();
|
||||||
|
}
|
||||||
u.save(new File(args[2]));
|
u.save(new File(args[2]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class ClassGroupFactory
|
|||||||
private static void addVoidMethod(ClassFile cf, String name)
|
private static void addVoidMethod(ClassFile cf, String name)
|
||||||
{
|
{
|
||||||
Method method = new Method(cf, name, new Signature("()V"));
|
Method method = new Method(cf, name, new Signature("()V"));
|
||||||
method.setStatic();
|
method.setStatic(true);
|
||||||
cf.addMethod(method);
|
cf.addMethod(method);
|
||||||
|
|
||||||
Code code = new Code(method);
|
Code code = new Code(method);
|
||||||
@@ -63,7 +63,7 @@ public class ClassGroupFactory
|
|||||||
cf.addField(field);
|
cf.addField(field);
|
||||||
|
|
||||||
Method method = new Method(cf, "func", new Signature("()V"));
|
Method method = new Method(cf, "func", new Signature("()V"));
|
||||||
method.setStatic();
|
method.setStatic(true);
|
||||||
cf.addMethod(method);
|
cf.addMethod(method);
|
||||||
|
|
||||||
Code code = new Code(method);
|
Code code = new Code(method);
|
||||||
@@ -71,7 +71,7 @@ public class ClassGroupFactory
|
|||||||
|
|
||||||
{
|
{
|
||||||
method = new Method(cf, "func2", new Signature("(III)V"));
|
method = new Method(cf, "func2", new Signature("(III)V"));
|
||||||
method.setStatic();
|
method.setStatic(true);
|
||||||
cf.addMethod(method);
|
cf.addMethod(method);
|
||||||
|
|
||||||
code = new Code(method);
|
code = new Code(method);
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import net.runelite.deob.DeobAnnotations;
|
|||||||
import net.runelite.deob.deobfuscators.arithmetic.DMath;
|
import net.runelite.deob.deobfuscators.arithmetic.DMath;
|
||||||
import net.runelite.injector.raw.ClearColorBuffer;
|
import net.runelite.injector.raw.ClearColorBuffer;
|
||||||
import net.runelite.injector.raw.DrawAfterWidgets;
|
import net.runelite.injector.raw.DrawAfterWidgets;
|
||||||
|
import net.runelite.injector.raw.DrawMenu;
|
||||||
import net.runelite.injector.raw.RasterizerHook;
|
import net.runelite.injector.raw.RasterizerHook;
|
||||||
import net.runelite.injector.raw.RenderDraw;
|
import net.runelite.injector.raw.RenderDraw;
|
||||||
import net.runelite.injector.raw.ScriptVM;
|
import net.runelite.injector.raw.ScriptVM;
|
||||||
@@ -68,6 +69,7 @@ public class Inject
|
|||||||
private final InjectInvoker invokes = new InjectInvoker(this);
|
private final InjectInvoker invokes = new InjectInvoker(this);
|
||||||
private final InjectConstruct construct = new InjectConstruct(this);
|
private final InjectConstruct construct = new InjectConstruct(this);
|
||||||
|
|
||||||
|
private final DrawMenu drawMenu = new DrawMenu(this);
|
||||||
private final RasterizerHook rasterizerHook = new RasterizerHook(this);
|
private final RasterizerHook rasterizerHook = new RasterizerHook(this);
|
||||||
private final MixinInjector mixinInjector = new MixinInjector(this);
|
private final MixinInjector mixinInjector = new MixinInjector(this);
|
||||||
private final DrawAfterWidgets drawAfterWidgets = new DrawAfterWidgets(this);
|
private final DrawAfterWidgets drawAfterWidgets = new DrawAfterWidgets(this);
|
||||||
@@ -331,6 +333,7 @@ public class Inject
|
|||||||
scriptVM.inject();
|
scriptVM.inject();
|
||||||
clearColorBuffer.inject();
|
clearColorBuffer.inject();
|
||||||
renderDraw.inject();
|
renderDraw.inject();
|
||||||
|
drawMenu.inject();
|
||||||
}
|
}
|
||||||
|
|
||||||
private java.lang.Class injectInterface(ClassFile cf, ClassFile other)
|
private java.lang.Class injectInterface(ClassFile cf, ClassFile other)
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class InjectConstruct
|
|||||||
|
|
||||||
private final Inject inject;
|
private final Inject inject;
|
||||||
|
|
||||||
public InjectConstruct(Inject inject)
|
InjectConstruct(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ public class InjectConstruct
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectConstruct(ClassFile targetClass, java.lang.reflect.Method apiMethod) throws InjectionException
|
void injectConstruct(ClassFile targetClass, java.lang.reflect.Method apiMethod) throws InjectionException
|
||||||
{
|
{
|
||||||
logger.info("Injecting construct for {}", apiMethod);
|
logger.info("Injecting construct for {}", apiMethod);
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class InjectGetter
|
class InjectGetter
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(InjectGetter.class);
|
private static final Logger logger = LoggerFactory.getLogger(InjectGetter.class);
|
||||||
|
|
||||||
@@ -52,12 +52,12 @@ public class InjectGetter
|
|||||||
|
|
||||||
private int injectedGetters;
|
private int injectedGetters;
|
||||||
|
|
||||||
public InjectGetter(Inject inject)
|
InjectGetter(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void injectGetter(ClassFile clazz, java.lang.reflect.Method method, Field field, Number getter)
|
void injectGetter(ClassFile clazz, java.lang.reflect.Method method, Field field, Number getter)
|
||||||
{
|
{
|
||||||
// clazz = class file we're injecting the method into.
|
// clazz = class file we're injecting the method into.
|
||||||
// method = api method (java reflect) that we're overriding
|
// method = api method (java reflect) that we're overriding
|
||||||
@@ -148,7 +148,7 @@ public class InjectGetter
|
|||||||
++injectedGetters;
|
++injectedGetters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInjectedGetters()
|
int getInjectedGetters()
|
||||||
{
|
{
|
||||||
return injectedGetters;
|
return injectedGetters;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ import net.runelite.asm.signature.Signature;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class InjectHook
|
class InjectHook
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(InjectHook.class);
|
private static final Logger logger = LoggerFactory.getLogger(InjectHook.class);
|
||||||
private static final String HOOK_METHOD_SIGNATURE = "(I)V";
|
private static final String HOOK_METHOD_SIGNATURE = "(I)V";
|
||||||
@@ -64,7 +64,7 @@ public class InjectHook
|
|||||||
private final Map<Field, HookInfo> hooked = new HashMap<>();
|
private final Map<Field, HookInfo> hooked = new HashMap<>();
|
||||||
private int injectedHooks;
|
private int injectedHooks;
|
||||||
|
|
||||||
public InjectHook(Inject inject)
|
InjectHook(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ public class InjectHook
|
|||||||
hooked.put(field, hookInfo);
|
hooked.put(field, hookInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run()
|
void run()
|
||||||
{
|
{
|
||||||
Execution e = new Execution(inject.getVanilla());
|
Execution e = new Execution(inject.getVanilla());
|
||||||
e.populateInitialMethods();
|
e.populateInitialMethods();
|
||||||
@@ -129,8 +129,7 @@ public class InjectHook
|
|||||||
StackContext objectStackContext = null;
|
StackContext objectStackContext = null;
|
||||||
if (sfi instanceof PutField)
|
if (sfi instanceof PutField)
|
||||||
{
|
{
|
||||||
StackContext objectStack = ic.getPops().get(1); // Object being set on
|
objectStackContext = ic.getPops().get(1);
|
||||||
objectStackContext = objectStack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int idx = ins.getInstructions().indexOf(sfi);
|
int idx = ins.getInstructions().indexOf(sfi);
|
||||||
@@ -206,8 +205,7 @@ public class InjectHook
|
|||||||
StackContext objectStackContext = null;
|
StackContext objectStackContext = null;
|
||||||
if (arrayReferencePushed.getInstruction().getType() == InstructionType.GETFIELD)
|
if (arrayReferencePushed.getInstruction().getType() == InstructionType.GETFIELD)
|
||||||
{
|
{
|
||||||
StackContext objectReference = arrayReferencePushed.getPops().get(0);
|
objectStackContext = arrayReferencePushed.getPops().get(0);
|
||||||
objectStackContext = objectReference;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// inject hook after 'i'
|
// inject hook after 'i'
|
||||||
@@ -382,7 +380,7 @@ public class InjectHook
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInjectedHooks()
|
int getInjectedHooks()
|
||||||
{
|
{
|
||||||
return injectedHooks;
|
return injectedHooks;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,12 +53,12 @@ public class InjectHookMethod
|
|||||||
private static final Logger logger = LoggerFactory.getLogger(InjectHookMethod.class);
|
private static final Logger logger = LoggerFactory.getLogger(InjectHookMethod.class);
|
||||||
private final Inject inject;
|
private final Inject inject;
|
||||||
|
|
||||||
public InjectHookMethod(Inject inject)
|
InjectHookMethod(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process(Method method) throws InjectionException
|
void process(Method method) throws InjectionException
|
||||||
{
|
{
|
||||||
Annotations an = method.getAnnotations();
|
Annotations an = method.getAnnotations();
|
||||||
if (an == null)
|
if (an == null)
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class InjectInvoker
|
class InjectInvoker
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(InjectInvoker.class);
|
private static final Logger logger = LoggerFactory.getLogger(InjectInvoker.class);
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ public class InjectInvoker
|
|||||||
|
|
||||||
private int injectedInvokers;
|
private int injectedInvokers;
|
||||||
|
|
||||||
public InjectInvoker(Inject inject)
|
InjectInvoker(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
@@ -73,7 +73,7 @@ public class InjectInvoker
|
|||||||
* @param implementingClass Java class for the API interface the class
|
* @param implementingClass Java class for the API interface the class
|
||||||
* will implement
|
* will implement
|
||||||
*/
|
*/
|
||||||
public void process(Method m, ClassFile other, java.lang.Class<?> implementingClass)
|
void process(Method m, ClassFile other, java.lang.Class<?> implementingClass)
|
||||||
{
|
{
|
||||||
Annotations an = m.getAnnotations();
|
Annotations an = m.getAnnotations();
|
||||||
|
|
||||||
@@ -284,7 +284,7 @@ public class InjectInvoker
|
|||||||
clazz.addMethod(invokerMethodSignature);
|
clazz.addMethod(invokerMethodSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInjectedInvokers()
|
int getInjectedInvokers()
|
||||||
{
|
{
|
||||||
return injectedInvokers;
|
return injectedInvokers;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class InjectSetter
|
class InjectSetter
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(InjectSetter.class);
|
private static final Logger logger = LoggerFactory.getLogger(InjectSetter.class);
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ public class InjectSetter
|
|||||||
|
|
||||||
private int injectedSetters;
|
private int injectedSetters;
|
||||||
|
|
||||||
public InjectSetter(Inject inject)
|
InjectSetter(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
@@ -67,9 +67,8 @@ public class InjectSetter
|
|||||||
* setter declared
|
* setter declared
|
||||||
* @param field Field of vanilla that will be set
|
* @param field Field of vanilla that will be set
|
||||||
* @param exportedName exported name of field
|
* @param exportedName exported name of field
|
||||||
* @param setter
|
|
||||||
*/
|
*/
|
||||||
public void injectSetter(ClassFile targetClass, Class<?> targetApiClass, Field field, String exportedName, Number setter)
|
void injectSetter(ClassFile targetClass, Class<?> targetApiClass, Field field, String exportedName, Number setter)
|
||||||
{
|
{
|
||||||
java.lang.reflect.Method method = inject.findImportMethodOnApi(targetApiClass, exportedName, true);
|
java.lang.reflect.Method method = inject.findImportMethodOnApi(targetApiClass, exportedName, true);
|
||||||
if (method == null)
|
if (method == null)
|
||||||
@@ -152,7 +151,7 @@ public class InjectSetter
|
|||||||
ins.add(new VReturn(instructions));
|
ins.add(new VReturn(instructions));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInjectedSetters()
|
int getInjectedSetters()
|
||||||
{
|
{
|
||||||
return injectedSetters;
|
return injectedSetters;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package net.runelite.injector;
|
||||||
|
|
||||||
|
import net.runelite.asm.ClassFile;
|
||||||
|
import net.runelite.asm.Field;
|
||||||
|
import net.runelite.asm.Method;
|
||||||
|
import net.runelite.asm.signature.Signature;
|
||||||
|
import net.runelite.deob.DeobAnnotations;
|
||||||
|
|
||||||
|
public class InjectUtil
|
||||||
|
{
|
||||||
|
public static Method findStaticObMethod(Inject inject, String name) throws InjectionException
|
||||||
|
{
|
||||||
|
for (ClassFile c : inject.getVanilla().getClasses())
|
||||||
|
{
|
||||||
|
for (Method m : c.getMethods())
|
||||||
|
{
|
||||||
|
if (!m.getName().equals(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InjectionException(String.format("Method \"%s\" could not be found.", name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Method findMethod(Inject inject, String name) throws InjectionException
|
||||||
|
{
|
||||||
|
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
||||||
|
{
|
||||||
|
for (Method m : c.getMethods())
|
||||||
|
{
|
||||||
|
if (!m.getName().equals(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
||||||
|
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m);
|
||||||
|
|
||||||
|
ClassFile c2 = inject.toObClass(c);
|
||||||
|
|
||||||
|
return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InjectionException("Couldn't find method " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Method findStaticMethod(Inject inject, String name) throws InjectionException
|
||||||
|
{
|
||||||
|
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
||||||
|
{
|
||||||
|
for (Method m : c.getMethods())
|
||||||
|
{
|
||||||
|
if (!m.isStatic() || !m.getName().equals(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
||||||
|
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m);
|
||||||
|
|
||||||
|
ClassFile c2 = inject.toObClass(c);
|
||||||
|
|
||||||
|
return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InjectionException("Couldn't find static method " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Field findObField(Inject inject, String name) throws InjectionException
|
||||||
|
{
|
||||||
|
for (ClassFile c : inject.getVanilla().getClasses())
|
||||||
|
{
|
||||||
|
for (Field f : c.getFields())
|
||||||
|
{
|
||||||
|
if (!f.getName().equals(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InjectionException(String.format("Field \"%s\" could not be found.", name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Field findDeobField(Inject inject, String name) throws InjectionException
|
||||||
|
{
|
||||||
|
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
||||||
|
{
|
||||||
|
for (Field f : c.getFields())
|
||||||
|
{
|
||||||
|
if (!f.getName().equals(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
|
||||||
|
|
||||||
|
ClassFile c2 = inject.toObClass(c);
|
||||||
|
return c2.findField(obfuscatedName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InjectionException(String.format("Mapped field \"%s\" could not be found.", name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Field findDeobFieldButUseless(Inject inject, String name) throws InjectionException
|
||||||
|
{
|
||||||
|
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
||||||
|
{
|
||||||
|
for (Field f : c.getFields())
|
||||||
|
{
|
||||||
|
if (!f.getName().equals(name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InjectionException(String.format("Mapped field \"%s\" could not be found.", name));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -67,7 +67,7 @@ public class Injector
|
|||||||
instance.run();
|
instance.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(File out) throws IOException
|
private void save(File out) throws IOException
|
||||||
{
|
{
|
||||||
JarUtil.saveJar(vanilla, out);
|
JarUtil.saveJar(vanilla, out);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
*
|
*
|
||||||
* @author Adam
|
* @author Adam
|
||||||
*/
|
*/
|
||||||
public class InjectorValidator
|
class InjectorValidator
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(InjectorValidator.class);
|
private static final Logger logger = LoggerFactory.getLogger(InjectorValidator.class);
|
||||||
|
|
||||||
@@ -49,12 +49,12 @@ public class InjectorValidator
|
|||||||
|
|
||||||
private int error, missing, okay;
|
private int error, missing, okay;
|
||||||
|
|
||||||
public InjectorValidator(ClassGroup group)
|
InjectorValidator(ClassGroup group)
|
||||||
{
|
{
|
||||||
this.group = group;
|
this.group = group;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validate()
|
void validate()
|
||||||
{
|
{
|
||||||
for (ClassFile cf : group.getClasses())
|
for (ClassFile cf : group.getClasses())
|
||||||
{
|
{
|
||||||
@@ -131,17 +131,17 @@ public class InjectorValidator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getError()
|
int getError()
|
||||||
{
|
{
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMissing()
|
int getMissing()
|
||||||
{
|
{
|
||||||
return missing;
|
return missing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getOkay()
|
int getOkay()
|
||||||
{
|
{
|
||||||
return okay;
|
return okay;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ public class MixinInjector
|
|||||||
// Use net.runelite.asm.pool.Field instead of Field because the pool version has hashcode implemented
|
// Use net.runelite.asm.pool.Field instead of Field because the pool version has hashcode implemented
|
||||||
private final Map<net.runelite.asm.pool.Field, Field> shadowFields = new HashMap<>();
|
private final Map<net.runelite.asm.pool.Field, Field> shadowFields = new HashMap<>();
|
||||||
|
|
||||||
public MixinInjector(Inject inject)
|
MixinInjector(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject = inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
@@ -165,9 +165,6 @@ public class MixinInjector
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds fields that are marked @Inject and inject them into the target
|
* Finds fields that are marked @Inject and inject them into the target
|
||||||
*
|
|
||||||
* @param mixinClasses
|
|
||||||
* @throws InjectionException
|
|
||||||
*/
|
*/
|
||||||
private void injectFields(Map<Class<?>, List<ClassFile>> mixinClasses) throws InjectionException
|
private void injectFields(Map<Class<?>, List<ClassFile>> mixinClasses) throws InjectionException
|
||||||
{
|
{
|
||||||
@@ -245,9 +242,6 @@ public class MixinInjector
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Find fields which are marked @Shadow, and what they shadow
|
* Find fields which are marked @Shadow, and what they shadow
|
||||||
*
|
|
||||||
* @param mixinClasses
|
|
||||||
* @throws InjectionException
|
|
||||||
*/
|
*/
|
||||||
private void findShadowFields(Map<Class<?>, List<ClassFile>> mixinClasses) throws InjectionException
|
private void findShadowFields(Map<Class<?>, List<ClassFile>> mixinClasses) throws InjectionException
|
||||||
{
|
{
|
||||||
@@ -287,7 +281,7 @@ public class MixinInjector
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Shadow a field already in the gamepack
|
// Shadow a field already in the gamepack
|
||||||
Field shadowField = findDeobField(shadowName);
|
Field shadowField = InjectUtil.findDeobFieldButUseless(inject, shadowName);
|
||||||
|
|
||||||
if (shadowField == null)
|
if (shadowField == null)
|
||||||
{
|
{
|
||||||
@@ -316,21 +310,6 @@ public class MixinInjector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Field findDeobField(String name)
|
|
||||||
{
|
|
||||||
for (ClassFile cf : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (Field f : cf.getFields())
|
|
||||||
{
|
|
||||||
if (f.getName().equals(name) && f.isStatic())
|
|
||||||
{
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void injectMethods(ClassFile mixinCf, ClassFile cf, Map<net.runelite.asm.pool.Field, Field> shadowFields)
|
private void injectMethods(ClassFile mixinCf, ClassFile cf, Map<net.runelite.asm.pool.Field, Field> shadowFields)
|
||||||
throws InjectionException
|
throws InjectionException
|
||||||
{
|
{
|
||||||
@@ -901,7 +880,7 @@ public class MixinInjector
|
|||||||
if (targetField == null)
|
if (targetField == null)
|
||||||
{
|
{
|
||||||
// first try non static fields, then static
|
// first try non static fields, then static
|
||||||
targetField = findDeobField(hookName);
|
targetField = InjectUtil.findDeobFieldButUseless(inject, hookName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetField == null)
|
if (targetField == null)
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
|||||||
import net.runelite.asm.attributes.code.instructions.LDC;
|
import net.runelite.asm.attributes.code.instructions.LDC;
|
||||||
import net.runelite.asm.pool.Class;
|
import net.runelite.asm.pool.Class;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
import net.runelite.deob.DeobAnnotations;
|
|
||||||
import net.runelite.injector.Inject;
|
import net.runelite.injector.Inject;
|
||||||
|
import net.runelite.injector.InjectUtil;
|
||||||
import net.runelite.injector.InjectionException;
|
import net.runelite.injector.InjectionException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -39,7 +39,7 @@ public class ClearColorBuffer
|
|||||||
|
|
||||||
private void injectColorBufferHooks() throws InjectionException
|
private void injectColorBufferHooks() throws InjectionException
|
||||||
{
|
{
|
||||||
net.runelite.asm.pool.Method fillRectangle = findStaticMethod("Rasterizer2D_fillRectangle").getPoolMethod();
|
net.runelite.asm.pool.Method fillRectangle = InjectUtil.findStaticMethod(inject, "Rasterizer2D_fillRectangle").getPoolMethod();
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int replaced = 0;
|
int replaced = 0;
|
||||||
@@ -119,28 +119,4 @@ public class ClearColorBuffer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Method findStaticMethod(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (Method m : c.getMethods())
|
|
||||||
{
|
|
||||||
if (!m.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
|
||||||
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m);
|
|
||||||
|
|
||||||
ClassFile c2 = inject.toObClass(c);
|
|
||||||
|
|
||||||
return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException("Couldn't find static method " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -38,9 +38,9 @@ import net.runelite.asm.attributes.code.instructions.GetStatic;
|
|||||||
import net.runelite.asm.attributes.code.instructions.IMul;
|
import net.runelite.asm.attributes.code.instructions.IMul;
|
||||||
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
import net.runelite.deob.DeobAnnotations;
|
|
||||||
import net.runelite.injector.Inject;
|
import net.runelite.injector.Inject;
|
||||||
import static net.runelite.injector.InjectHookMethod.HOOKS;
|
import static net.runelite.injector.InjectHookMethod.HOOKS;
|
||||||
|
import static net.runelite.injector.InjectUtil.findStaticMethod;
|
||||||
import net.runelite.injector.InjectionException;
|
import net.runelite.injector.InjectionException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -107,7 +107,7 @@ public class DrawAfterWidgets
|
|||||||
|
|
||||||
boolean injected = false;
|
boolean injected = false;
|
||||||
|
|
||||||
Method noClip = findStaticMethod("Rasterizer2D_resetClip"); // !!!!!
|
Method noClip = findStaticMethod(inject, "Rasterizer2D_resetClip"); // !!!!!
|
||||||
|
|
||||||
if (noClip == null)
|
if (noClip == null)
|
||||||
{
|
{
|
||||||
@@ -261,27 +261,4 @@ public class DrawAfterWidgets
|
|||||||
throw new InjectionException("injectDrawAfterWidgets failed to inject!");
|
throw new InjectionException("injectDrawAfterWidgets failed to inject!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Method findStaticMethod(String name)
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (Method m : c.getMethods())
|
|
||||||
{
|
|
||||||
if (!m.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
|
||||||
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m);
|
|
||||||
|
|
||||||
ClassFile c2 = inject.toObClass(c);
|
|
||||||
|
|
||||||
return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,193 +1,135 @@
|
|||||||
/*
|
|
||||||
package net.runelite.injector.raw;
|
package net.runelite.injector.raw;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import java.util.ListIterator;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import net.runelite.asm.ClassFile;
|
import net.runelite.asm.ClassFile;
|
||||||
import net.runelite.asm.Method;
|
import net.runelite.asm.Method;
|
||||||
import net.runelite.asm.Type;
|
|
||||||
import net.runelite.asm.attributes.Annotations;
|
|
||||||
import net.runelite.asm.attributes.Code;
|
import net.runelite.asm.attributes.Code;
|
||||||
import net.runelite.asm.attributes.annotation.Annotation;
|
|
||||||
import net.runelite.asm.attributes.code.Instruction;
|
import net.runelite.asm.attributes.code.Instruction;
|
||||||
import net.runelite.asm.attributes.code.Instructions;
|
import net.runelite.asm.attributes.code.Instructions;
|
||||||
import net.runelite.asm.attributes.code.Label;
|
import net.runelite.asm.attributes.code.Label;
|
||||||
import net.runelite.asm.attributes.code.instruction.types.ComparisonInstruction;
|
|
||||||
import net.runelite.asm.attributes.code.instruction.types.JumpingInstruction;
|
import net.runelite.asm.attributes.code.instruction.types.JumpingInstruction;
|
||||||
import net.runelite.asm.attributes.code.instruction.types.ReturnInstruction;
|
|
||||||
import net.runelite.asm.attributes.code.instructions.GetStatic;
|
import net.runelite.asm.attributes.code.instructions.GetStatic;
|
||||||
import net.runelite.asm.attributes.code.instructions.IfACmpEq;
|
|
||||||
import net.runelite.asm.attributes.code.instructions.IfACmpNe;
|
|
||||||
import net.runelite.asm.attributes.code.instructions.IfEq;
|
import net.runelite.asm.attributes.code.instructions.IfEq;
|
||||||
import net.runelite.asm.attributes.code.instructions.IfNe;
|
import net.runelite.asm.attributes.code.instructions.IfNe;
|
||||||
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
||||||
import net.runelite.asm.execution.Execution;
|
|
||||||
import net.runelite.asm.execution.InstructionContext;
|
|
||||||
import net.runelite.asm.pool.Class;
|
import net.runelite.asm.pool.Class;
|
||||||
import net.runelite.asm.pool.Field;
|
import net.runelite.asm.pool.Field;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
import net.runelite.deob.DeobAnnotations;
|
|
||||||
import net.runelite.injector.Inject;
|
import net.runelite.injector.Inject;
|
||||||
|
import static net.runelite.injector.InjectUtil.findDeobField;
|
||||||
|
import static net.runelite.injector.InjectUtil.findStaticMethod;
|
||||||
import net.runelite.injector.InjectionException;
|
import net.runelite.injector.InjectionException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class DrawMenu
|
public class DrawMenu
|
||||||
{
|
{
|
||||||
|
private final Logger log = LoggerFactory.getLogger(DrawMenu.class);
|
||||||
private final Inject inject;
|
private final Inject inject;
|
||||||
private static final Field isMenuOpen = new Field(
|
|
||||||
new Class("Client"),
|
|
||||||
"isMenuOpen",
|
|
||||||
Type.BOOLEAN
|
|
||||||
);
|
|
||||||
private static final net.runelite.asm.pool.Method hook = new net.runelite.asm.pool.Method(
|
private static final net.runelite.asm.pool.Method hook = new net.runelite.asm.pool.Method(
|
||||||
new Class("net.runelite.client.callback.Hooks"),
|
new Class("net.runelite.client.callback.Hooks"),
|
||||||
"drawMenu",
|
"drawMenu",
|
||||||
new Signature("()Z")
|
new Signature("()Z")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//Label Getstatic client.isMenuOpen
|
||||||
|
//Ifne -> Label Drawmenu
|
||||||
|
//Jump -> Label Drawtext
|
||||||
|
|
||||||
|
//Label drawtext
|
||||||
|
//Ldc xxx
|
||||||
|
//Getstatic client. something with viewport size?
|
||||||
|
//Imul
|
||||||
|
//Iconst_m1
|
||||||
|
//Ifne -> Label after draw menu <- info we need
|
||||||
|
//Getstatic / LDC (same getstatic and LDC before)
|
||||||
|
//Getstatic / LDC
|
||||||
|
|
||||||
public DrawMenu(Inject inject)
|
public DrawMenu(Inject inject)
|
||||||
{
|
{
|
||||||
this.inject =inject;
|
this.inject = inject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void inject() throws InjectionException
|
public void inject() throws InjectionException
|
||||||
{
|
{
|
||||||
Method drawLoggedIn = findDeobThing("drawLoggedIn", "Client", false);
|
Field isMenuOpen = findDeobField(inject, "isMenuOpen").getPoolField();
|
||||||
Instructions ins = drawLoggedIn.getCode().getInstructions();
|
net.runelite.asm.pool.Method topLeftText = findStaticMethod(inject, "drawMenuActionTextAt").getPoolMethod();
|
||||||
|
|
||||||
int menuOpenIdx = -1;
|
for (ClassFile cf : inject.getVanilla().getClasses())
|
||||||
Field field = toObField(isMenuOpen).getPoolField();
|
|
||||||
|
|
||||||
for (Instruction i : ins.getInstructions())
|
|
||||||
{
|
|
||||||
if (!(i instanceof GetStatic))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((GetStatic) i).getField().equals(field))
|
|
||||||
{
|
|
||||||
menuOpenIdx = ins.getInstructions().indexOf(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (menuOpenIdx == -1)
|
|
||||||
{
|
|
||||||
throw new InjectionException("Couldn't find the isMenuOpen check!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is where the IFEQ or IFNE will be
|
|
||||||
final Instruction jump = ins.getInstructions().get(menuOpenIdx + 1);
|
|
||||||
// We want to inject if it's false so
|
|
||||||
if (jump instanceof IfEq)
|
|
||||||
{
|
|
||||||
// Not this one, but we gotta find out where the paths will intersect
|
|
||||||
Set<Label> labels = getLabels(jump);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<Label> getLabels(Instruction i)
|
|
||||||
{
|
|
||||||
Set<Label> labels = new HashSet<>();
|
|
||||||
Execution ex = new Execution(inject.getVanilla());
|
|
||||||
ex.addMethod(i.getInstructions().getCode().getMethod());
|
|
||||||
ex.noInvoke = true;
|
|
||||||
|
|
||||||
ex.addExecutionVisitor((InstructionContext ic) ->
|
|
||||||
{
|
|
||||||
Instruction in = ic.getInstruction();
|
|
||||||
Instructions ins = in.getInstructions();
|
|
||||||
Code code = ins.getCode();
|
|
||||||
Method method = code.getMethod();
|
|
||||||
//ic.
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<Label> findLabels(Instructions ins, int idx)
|
|
||||||
{
|
|
||||||
Set<Label> labels = new HashSet<>();
|
|
||||||
Instruction i = null;
|
|
||||||
while (labels.size() < 10 || !(i instanceof ReturnInstruction))
|
|
||||||
{
|
|
||||||
i = ins.getInstructions().get(idx);
|
|
||||||
if (i instanceof JumpingInstruction)
|
|
||||||
{
|
|
||||||
Label cur = ((JumpingInstruction) i).getJumps().get(0);
|
|
||||||
labels.add((Label) cur);
|
|
||||||
|
|
||||||
idx = ins.getInstructions().indexOf(cur) + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return labels;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Method findDeobThing(String name, String hint, boolean isStatic) throws InjectionException
|
|
||||||
{
|
|
||||||
if (!Strings.isNullOrEmpty(hint))
|
|
||||||
{
|
|
||||||
ClassFile hintCf = inject.getDeobfuscated().findClass(hint);
|
|
||||||
if (hintCf != null)
|
|
||||||
{
|
|
||||||
for (Method m : hintCf.getMethods())
|
|
||||||
{
|
|
||||||
if (isStatic != m.isStatic())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Annotations an = m.getAnnotations();
|
|
||||||
if (an == null || an.find(DeobAnnotations.EXPORT) == null)
|
|
||||||
{
|
|
||||||
continue; // not an exported field
|
|
||||||
}
|
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(an);
|
|
||||||
return inject.toObClass(hintCf).findMethod(obfuscatedName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ClassFile cf : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
{
|
||||||
for (Method m : cf.getMethods())
|
for (Method m : cf.getMethods())
|
||||||
{
|
{
|
||||||
if (isStatic != m.isStatic())
|
Code c = m.getCode();
|
||||||
|
if (c == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Annotations an = m.getAnnotations();
|
Instructions ins = c.getInstructions();
|
||||||
if (an == null || an.find(DeobAnnotations.EXPORT) == null)
|
ListIterator<Instruction> it = ins.getInstructions().listIterator();
|
||||||
|
int injectIndex = -1;
|
||||||
|
Label after = null;
|
||||||
|
boolean foundBefore = false;
|
||||||
|
boolean foundAfter = false;
|
||||||
|
|
||||||
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
continue; // not an exported field
|
Instruction i = it.next();
|
||||||
|
|
||||||
|
if (!(i instanceof GetStatic) && !(i instanceof InvokeStatic))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundBefore && i instanceof GetStatic)
|
||||||
|
{
|
||||||
|
if (!((GetStatic) i).getField().equals(isMenuOpen))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = it.next();
|
||||||
|
if (!(i instanceof IfEq) && !(i instanceof IfNe))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i instanceof IfEq)
|
||||||
|
{
|
||||||
|
injectIndex = it.nextIndex();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
injectIndex = ins.getInstructions().indexOf(((IfNe) i).getJumps().get(0)) + 1;
|
||||||
|
}
|
||||||
|
foundBefore = true;
|
||||||
|
}
|
||||||
|
else if (!foundAfter && i instanceof InvokeStatic
|
||||||
|
&& ((InvokeStatic) i).getMethod().equals(topLeftText))
|
||||||
|
{
|
||||||
|
i = it.next();
|
||||||
|
assert i instanceof JumpingInstruction;
|
||||||
|
after = ((JumpingInstruction) i).getJumps().get(0);
|
||||||
|
foundAfter = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundBefore && foundAfter)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(an);
|
if (!foundBefore || !foundAfter || injectIndex == -1)
|
||||||
return inject.toObClass(cf).findMethod(obfuscatedName);
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ins.addInstruction(injectIndex, new IfNe(ins, after));
|
||||||
|
ins.addInstruction(injectIndex, new InvokeStatic(ins, hook));
|
||||||
|
log.info("Injected drawmenu hook in {} at index {}", m, injectIndex);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new InjectionException("Method not found!");
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private net.runelite.asm.Field toObField(Field field) throws InjectionException
|
|
||||||
{
|
|
||||||
ClassFile cf = inject.getDeobfuscated().findClass(field.getClazz().getName());
|
|
||||||
for (net.runelite.asm.Field f : cf.getFields())
|
|
||||||
{
|
|
||||||
if (f.getPoolField().equals(field))
|
|
||||||
{
|
|
||||||
return inject.toObField(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new InjectionException("Field not found!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@@ -4,7 +4,6 @@ import java.util.ArrayList;
|
|||||||
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 net.runelite.asm.ClassFile;
|
|
||||||
import net.runelite.asm.Field;
|
import net.runelite.asm.Field;
|
||||||
import net.runelite.asm.Method;
|
import net.runelite.asm.Method;
|
||||||
import net.runelite.asm.attributes.Code;
|
import net.runelite.asm.attributes.Code;
|
||||||
@@ -27,8 +26,9 @@ import net.runelite.asm.execution.Execution;
|
|||||||
import net.runelite.asm.execution.InstructionContext;
|
import net.runelite.asm.execution.InstructionContext;
|
||||||
import net.runelite.asm.pool.Class;
|
import net.runelite.asm.pool.Class;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
import net.runelite.deob.DeobAnnotations;
|
|
||||||
import net.runelite.injector.Inject;
|
import net.runelite.injector.Inject;
|
||||||
|
import static net.runelite.injector.InjectUtil.findDeobField;
|
||||||
|
import static net.runelite.injector.InjectUtil.findStaticMethod;
|
||||||
import net.runelite.injector.InjectionException;
|
import net.runelite.injector.InjectionException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -101,8 +101,8 @@ public class RasterizerHook
|
|||||||
|
|
||||||
private void runR3DAlpha(String methodName, int req, String fieldName) throws InjectionException
|
private void runR3DAlpha(String methodName, int req, String fieldName) throws InjectionException
|
||||||
{
|
{
|
||||||
Method meth = findStaticMethod(methodName);
|
Method meth = findStaticMethod(inject, methodName);
|
||||||
Field field = findDeobField(fieldName);
|
Field field = findDeobField(inject, fieldName);
|
||||||
Instructions ins = meth.getCode().getInstructions();
|
Instructions ins = meth.getCode().getInstructions();
|
||||||
int varIdx = 0; // This is obviously dumb but I cba making this better
|
int varIdx = 0; // This is obviously dumb but I cba making this better
|
||||||
int added = 0;
|
int added = 0;
|
||||||
@@ -118,8 +118,6 @@ public class RasterizerHook
|
|||||||
throw new InjectionException("Couldn't find hook location in " + methodName);
|
throw new InjectionException("Couldn't find hook location in " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
int oldCount = count;
|
|
||||||
|
|
||||||
for (int i : indices)
|
for (int i : indices)
|
||||||
{
|
{
|
||||||
for (int codeIndex = i + added; codeIndex < ins.getInstructions().size(); codeIndex++)
|
for (int codeIndex = i + added; codeIndex < ins.getInstructions().size(); codeIndex++)
|
||||||
@@ -146,8 +144,8 @@ public class RasterizerHook
|
|||||||
|
|
||||||
private void runAlpha(String methodName, int req, int extraArg, int varIndex) throws InjectionException
|
private void runAlpha(String methodName, int req, int extraArg, int varIndex) throws InjectionException
|
||||||
{
|
{
|
||||||
final net.runelite.asm.pool.Field pixels = findDeobField("Rasterizer2D_pixels").getPoolField();
|
final net.runelite.asm.pool.Field pixels = findDeobField(inject, "Rasterizer2D_pixels").getPoolField();
|
||||||
Method meth = findStaticMethod(methodName);
|
Method meth = findStaticMethod(inject, methodName);
|
||||||
if (meth == null)
|
if (meth == null)
|
||||||
{
|
{
|
||||||
throw new InjectionException(methodName + " couldnt be found");
|
throw new InjectionException(methodName + " couldnt be found");
|
||||||
@@ -215,8 +213,7 @@ public class RasterizerHook
|
|||||||
|
|
||||||
private void runFontAlpha(String methodName, int req, int extraArg) throws InjectionException
|
private void runFontAlpha(String methodName, int req, int extraArg) throws InjectionException
|
||||||
{
|
{
|
||||||
final net.runelite.asm.pool.Field pixels = findDeobField("Rasterizer2D_pixels").getPoolField();
|
Method meth = findStaticMethod(inject, methodName);
|
||||||
Method meth = findStaticMethod(methodName);
|
|
||||||
Instructions ins = meth.getCode().getInstructions();
|
Instructions ins = meth.getCode().getInstructions();
|
||||||
int varIdx = 0; // This is obviously dumb but I cba making this better
|
int varIdx = 0; // This is obviously dumb but I cba making this better
|
||||||
int added = 0;
|
int added = 0;
|
||||||
@@ -252,13 +249,9 @@ public class RasterizerHook
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count - oldCount > req)
|
if (count - req != oldCount)
|
||||||
{
|
{
|
||||||
throw new InjectionException("Too many drawAlpha's were injected into " + methodName);
|
throw new InjectionException(req != oldCount ? req > count - oldCount ? "Not enough" : "Too many" : "No" + " drawAlpha's were injected into " + methodName);
|
||||||
}
|
|
||||||
if (count == oldCount)
|
|
||||||
{
|
|
||||||
throw new InjectionException("Couldn't find any drawAlpha positions in " + methodName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +275,7 @@ public class RasterizerHook
|
|||||||
private void run() throws InjectionException
|
private void run() throws InjectionException
|
||||||
{
|
{
|
||||||
final int startCount = count; // Cause you can't just count shit ty
|
final int startCount = count; // Cause you can't just count shit ty
|
||||||
final net.runelite.asm.pool.Field pixels = findDeobField("Rasterizer2D_pixels").getPoolField();
|
final net.runelite.asm.pool.Field pixels = findDeobField(inject, "Rasterizer2D_pixels").getPoolField();
|
||||||
|
|
||||||
Execution ex = new Execution(inject.getVanilla());
|
Execution ex = new Execution(inject.getVanilla());
|
||||||
ex.populateInitialMethods();
|
ex.populateInitialMethods();
|
||||||
@@ -341,7 +334,7 @@ public class RasterizerHook
|
|||||||
|
|
||||||
private void runOnMethodWithVar(String meth, int varIndex) throws InjectionException
|
private void runOnMethodWithVar(String meth, int varIndex) throws InjectionException
|
||||||
{
|
{
|
||||||
Method method = findStaticMethod(meth);
|
Method method = findStaticMethod(inject, meth);
|
||||||
|
|
||||||
Instructions ins = method.getCode().getInstructions();
|
Instructions ins = method.getCode().getInstructions();
|
||||||
List<Integer> indices = new ArrayList<>();
|
List<Integer> indices = new ArrayList<>();
|
||||||
@@ -374,48 +367,4 @@ public class RasterizerHook
|
|||||||
|
|
||||||
logger.info("Added {} instructions in {}. {} total", added >>> 1, meth, count);
|
logger.info("Added {} instructions in {}. {} total", added >>> 1, meth, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Method findStaticMethod(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (Method m : c.getMethods())
|
|
||||||
{
|
|
||||||
if (!m.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
|
||||||
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m);
|
|
||||||
|
|
||||||
ClassFile c2 = inject.toObClass(c);
|
|
||||||
|
|
||||||
return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException("Couldn't find static method " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Field findDeobField(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (Field f : c.getFields())
|
|
||||||
{
|
|
||||||
if (!f.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
|
|
||||||
|
|
||||||
ClassFile c2 = inject.toObClass(c);
|
|
||||||
return c2.findField(obfuscatedName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException(String.format("Mapped field \"%s\" could not be found.", name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package net.runelite.injector.raw;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.runelite.asm.ClassFile;
|
|
||||||
import net.runelite.asm.attributes.code.Instruction;
|
import net.runelite.asm.attributes.code.Instruction;
|
||||||
import net.runelite.asm.attributes.code.Instructions;
|
import net.runelite.asm.attributes.code.Instructions;
|
||||||
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
||||||
@@ -10,8 +9,8 @@ import net.runelite.asm.attributes.code.instructions.InvokeVirtual;
|
|||||||
import net.runelite.asm.pool.Class;
|
import net.runelite.asm.pool.Class;
|
||||||
import net.runelite.asm.pool.Method;
|
import net.runelite.asm.pool.Method;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
import net.runelite.deob.DeobAnnotations;
|
|
||||||
import net.runelite.injector.Inject;
|
import net.runelite.injector.Inject;
|
||||||
|
import static net.runelite.injector.InjectUtil.findMethod;
|
||||||
import net.runelite.injector.InjectionException;
|
import net.runelite.injector.InjectionException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -38,8 +37,8 @@ public class RenderDraw
|
|||||||
|
|
||||||
private void injectColorBufferHooks() throws InjectionException
|
private void injectColorBufferHooks() throws InjectionException
|
||||||
{
|
{
|
||||||
net.runelite.asm.Method obmethod = findObMethod("drawTile");
|
net.runelite.asm.Method obmethod = findMethod(inject, "drawTile");
|
||||||
Method renderDraw = findObMethod("renderDraw").getPoolMethod();
|
Method renderDraw = findMethod(inject, "renderDraw").getPoolMethod();
|
||||||
Instructions ins = obmethod.getCode().getInstructions();
|
Instructions ins = obmethod.getCode().getInstructions();
|
||||||
replace(ins, renderDraw);
|
replace(ins, renderDraw);
|
||||||
}
|
}
|
||||||
@@ -69,24 +68,4 @@ public class RenderDraw
|
|||||||
ins.replace(i, invoke);
|
ins.replace(i, invoke);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private net.runelite.asm.Method findObMethod(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile cf : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (net.runelite.asm.Method m : cf.getMethods())
|
|
||||||
{
|
|
||||||
if (!m.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
|
||||||
|
|
||||||
ClassFile c2 = inject.toObClass(cf);
|
|
||||||
return c2.findMethod(obfuscatedName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException(String.format("Method \"%s\" could not be found.", name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import java.util.HashSet;
|
|||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import net.runelite.asm.ClassFile;
|
|
||||||
import net.runelite.asm.Field;
|
import net.runelite.asm.Field;
|
||||||
import net.runelite.asm.Method;
|
import net.runelite.asm.Method;
|
||||||
import net.runelite.asm.Type;
|
import net.runelite.asm.Type;
|
||||||
@@ -54,6 +53,9 @@ import net.runelite.asm.execution.MethodContext;
|
|||||||
import net.runelite.asm.execution.StackContext;
|
import net.runelite.asm.execution.StackContext;
|
||||||
import net.runelite.deob.DeobAnnotations;
|
import net.runelite.deob.DeobAnnotations;
|
||||||
import net.runelite.injector.Inject;
|
import net.runelite.injector.Inject;
|
||||||
|
import net.runelite.injector.InjectUtil;
|
||||||
|
import static net.runelite.injector.InjectUtil.findDeobField;
|
||||||
|
import static net.runelite.injector.InjectUtil.findObField;
|
||||||
import net.runelite.injector.InjectionException;
|
import net.runelite.injector.InjectionException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -104,12 +106,12 @@ public class ScriptVM
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
String scriptObName = DeobAnnotations.getObfuscatedName(inject.getDeobfuscated().findClass("Script").getAnnotations());
|
String scriptObName = DeobAnnotations.getObfuscatedName(inject.getDeobfuscated().findClass("Script").getAnnotations());
|
||||||
Method runScript = findObMethod("copy$runScript0");
|
Method runScript = InjectUtil.findStaticObMethod(inject, "copy$runScript0");
|
||||||
Method vmExecuteOpcode = findObMethod("vmExecuteOpcode");
|
Method vmExecuteOpcode = InjectUtil.findStaticObMethod(inject, "vmExecuteOpcode");
|
||||||
Field scriptInstructions = findDeobField("opcodes");
|
Field scriptInstructions = findDeobField(inject, "opcodes");
|
||||||
Field scriptStatePC = findDeobField("pc");
|
Field scriptStatePC = findDeobField(inject, "pc");
|
||||||
Field currentScriptField = findObField("currentScript");
|
Field currentScriptField = findObField(inject, "currentScript");
|
||||||
Field currentScriptPCField = findObField("currentScriptPC");
|
Field currentScriptPCField = findObField(inject, "currentScriptPC");
|
||||||
|
|
||||||
Execution e = new Execution(inject.getVanilla());
|
Execution e = new Execution(inject.getVanilla());
|
||||||
e.addMethod(runScript);
|
e.addMethod(runScript);
|
||||||
@@ -295,59 +297,4 @@ public class ScriptVM
|
|||||||
instrs.addInstruction(istorepc + 2, new InvokeStatic(instrs, vmExecuteOpcode.getPoolMethod()));
|
instrs.addInstruction(istorepc + 2, new InvokeStatic(instrs, vmExecuteOpcode.getPoolMethod()));
|
||||||
instrs.addInstruction(istorepc + 3, new IfNe(instrs, nextIteration));
|
instrs.addInstruction(istorepc + 3, new IfNe(instrs, nextIteration));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Method findObMethod(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getVanilla().getClasses())
|
|
||||||
{
|
|
||||||
for (Method m : c.getMethods())
|
|
||||||
{
|
|
||||||
if (!m.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException(String.format("Method \"%s\" could not be found.", name));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Field findObField(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getVanilla().getClasses())
|
|
||||||
{
|
|
||||||
for (Field f : c.getFields())
|
|
||||||
{
|
|
||||||
if (!f.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException(String.format("Field \"%s\" could not be found.", name));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Field findDeobField(String name) throws InjectionException
|
|
||||||
{
|
|
||||||
for (ClassFile c : inject.getDeobfuscated().getClasses())
|
|
||||||
{
|
|
||||||
for (Field f : c.getFields())
|
|
||||||
{
|
|
||||||
if (!f.getName().equals(name))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
|
|
||||||
|
|
||||||
ClassFile c2 = inject.toObClass(c);
|
|
||||||
return c2.findField(obfuscatedName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InjectionException(String.format("Mapped field \"%s\" could not be found.", name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user