Merge pull request #543 from Lucwousin/iodsangoisndiognadsoihnioadsfnhoidafsniogndsaiohgnoifdsanhiosnd

Add menu raw injector
This commit is contained in:
Lucwousin
2019-06-10 15:26:25 +02:00
committed by GitHub
23 changed files with 546 additions and 470 deletions

View File

@@ -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()

View File

@@ -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]));

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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]));
} }
} }

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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)

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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));
}
}

View File

@@ -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);
} }

View File

@@ -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;
} }

View File

@@ -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)

View File

@@ -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);
}
} }

View File

@@ -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;
}
} }

View File

@@ -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!");
} }
} }
*/

View File

@@ -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));
}
} }

View File

@@ -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));
}
} }

View File

@@ -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));
}
} }