project: Update injector

This commit is contained in:
Owain van Brakel
2022-06-23 18:26:28 +02:00
parent 50f415e8ba
commit e7dc8fd2c9
47 changed files with 1752 additions and 308 deletions

View File

@@ -3,14 +3,17 @@
* All rights reserved.
*
* This code is licensed under GPL3, see the complete license in
* the LICENSE file in the root directory of this source tree.
* the LICENSE file in the root directory of this submodule.
*/
package com.openosrs.injector;
import com.openosrs.injector.injection.InjectData;
import static com.openosrs.injector.rsapi.RSApi.API_BASE;
import static com.openosrs.injector.rsapi.RSApi.RL_API_BASE;
import com.openosrs.injector.rsapi.RSApiClass;
import com.openosrs.injector.rsapi.RSApiMethod;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -42,8 +45,6 @@ import net.runelite.asm.signature.Signature;
import net.runelite.deob.DeobAnnotations;
import net.runelite.deob.deobfuscators.arithmetic.DMath;
import org.jetbrains.annotations.Nullable;
import static com.openosrs.injector.rsapi.RSApi.API_BASE;
import static com.openosrs.injector.rsapi.RSApi.RL_API_BASE;
public interface InjectUtil
{
@@ -62,11 +63,10 @@ public interface InjectUtil
/**
* Finds a static method in deob and converts it to ob
*
* @param data InjectData instance
* @param name The name of the method you want to find
* @param data InjectData instance
* @param name The name of the method you want to find
* @param classHint The name of the class you expect the method to be in, or null
* @param sig The signature the method has in deob, or null
*
* @param sig The signature the method has in deob, or null
* @return The obfuscated version of the found method
*/
static Method findMethod(
@@ -81,8 +81,8 @@ public interface InjectUtil
/**
* Finds a method in injectData's deobfuscated classes.
*
* @param data InjectData instance
* @param name (Exported) method name
* @param data InjectData instance
* @param name (Exported) method name
* @param classHint The (exported) name of a class you expect (or know) the method to be in, or null, if you're not sure
* @throws InjectException If the hint class couldn't be found, or no method matching the settings was found
*/
@@ -90,7 +90,7 @@ public interface InjectUtil
InjectData data,
String name,
@Nullable String classHint)
throws InjectException
throws InjectException
{
return findMethod(data, name, classHint, null, false, false);
}
@@ -98,13 +98,12 @@ public interface InjectUtil
/**
* Finds a method in injectData's deobfuscated classes.
*
* @param data InjectData instance
* @param name (Exported) method name
* @param classHint The (exported) name of a class you expect (or know) the method to be in, or null, if you're not sure
* @param sig The deobfuscated methods' signature, or null, if you're unsure
* @param notStatic If this is true, only check non-static methods. If classHint isn't null, check only subclasses
* @param data InjectData instance
* @param name (Exported) method name
* @param classHint The (exported) name of a class you expect (or know) the method to be in, or null, if you're not sure
* @param sig The deobfuscated methods' signature, or null, if you're unsure
* @param notStatic If this is true, only check non-static methods. If classHint isn't null, check only subclasses
* @param returnDeob If this is true, this method will return the deobfuscated method, instead of turning it into vanilla first
*
* @throws InjectException If the hint class couldn't be found, or no method matching the settings was found
*/
static Method findMethod(
@@ -114,7 +113,7 @@ public interface InjectUtil
@Nullable Predicate<Signature> sig,
boolean notStatic,
boolean returnDeob)
throws InjectException
throws InjectException
{
final ClassGroup deob = data.getDeobfuscated();
if (classHint != null)
@@ -125,23 +124,41 @@ public interface InjectUtil
if (notStatic)
{
if (sig == null)
{
m = InjectUtil.findMethodDeep(cf, name, s -> true);
}
else
{
m = InjectUtil.findMethodDeep(cf, name, sig);
}
}
else
{
m = cf.findMethod(name);
}
if (m != null)
{
return returnDeob ? m : data.toVanilla(m);
}
}
for (ClassFile cf : deob)
{
for (Method m : cf.getMethods())
{
if (m.getName().equals(name))
{
if (!notStatic || !m.isStatic())
{
if (sig == null || sig.test(m.getDescriptor()))
{
return returnDeob ? m : data.toVanilla(m);
}
}
}
}
}
throw new InjectException(String.format("Couldn't find %s", name));
}
@@ -150,7 +167,9 @@ public interface InjectUtil
{
ClassFile clazz = group.findClass(name);
if (clazz == null)
{
throw new InjectException("Hint class " + name + " doesn't exist");
}
return clazz;
}
@@ -161,10 +180,18 @@ public interface InjectUtil
static Method findMethodDeep(ClassFile clazz, String name, Predicate<Signature> type)
{
do
{
for (Method method : clazz.getMethods())
{
if (method.getName().equals(name))
{
if (type.test(method.getDescriptor()))
{
return method;
}
}
}
}
while ((clazz = clazz.getParent()) != null);
throw new InjectException(String.format("Method %s couldn't be found", name + type.toString()));
@@ -172,7 +199,7 @@ public interface InjectUtil
/**
* Fail-fast implementation of ClassGroup.findStaticField
*
* <p>
* well...
*/
static Field findStaticField(ClassGroup group, String name)
@@ -181,7 +208,9 @@ public interface InjectUtil
{
Field f = clazz.findField(name);
if (f != null && f.isStatic())
{
return f;
}
}
throw new InjectException("Couldn't find static field " + name);
@@ -190,11 +219,10 @@ public interface InjectUtil
/**
* Finds a static field in deob and converts it to ob
*
* @param data InjectData instance
* @param name The name of the field you want to find
* @param data InjectData instance
* @param name The name of the field you want to find
* @param classHint The name of the class you expect the field to be in, or null
* @param type The type the method has in deob, or null
*
* @param type The type the method has in deob, or null
* @return The obfuscated version of the found field
*/
static Field findStaticField(InjectData data, String name, String classHint, Type type)
@@ -207,23 +235,35 @@ public interface InjectUtil
ClassFile clazz = findClassOrThrow(deob, classHint);
if (type == null)
{
field = clazz.findField(name);
}
else
{
field = clazz.findField(name, type);
}
if (field != null)
{
return field;
}
}
for (ClassFile clazz : deob)
{
if (type == null)
{
field = clazz.findField(name);
}
else
{
field = clazz.findField(name, type);
}
if (field != null)
{
return field;
}
}
throw new InjectException(String.format("Static field %s doesn't exist", (type != null ? type + " " : "") + name));
@@ -237,8 +277,12 @@ public interface InjectUtil
Field f;
do
{
if ((f = clazz.findField(name)) != null)
{
return f;
}
}
while ((clazz = clazz.getParent()) != null);
throw new InjectException("Couldn't find field " + name);
@@ -259,12 +303,18 @@ public interface InjectUtil
field = clazz.findField(name);
if (field != null)
{
return field;
}
}
for (ClassFile clazz : group)
{
if ((field = clazz.findField(name)) != null)
{
return field;
}
}
throw new InjectException("Field " + name + " doesn't exist");
}
@@ -291,39 +341,62 @@ public interface InjectUtil
}
static Type apiToDeob(InjectData data, Type api)
{
return apiToDeob(data, api, null);
}
static Type apiToDeob(InjectData data, Type api, Type deobType)
{
if (api.isPrimitive())
{
return api;
}
final String internalName = api.getInternalName();
if (internalName.startsWith(API_BASE))
{
return Type.getType("L" + api.getInternalName().substring(API_BASE.length()) + ";", api.getDimensions());
}
else if (internalName.startsWith(RL_API_BASE))
{
Class rlApiC = new Class(internalName);
RSApiClass highestKnown = data.getRsApi().withInterface(rlApiC);
Set<RSApiClass> allClasses = data.getRsApi().withInterface(rlApiC);
// Cheeky unchecked exception
assert highestKnown != null : "No rs api class implements rl api class " + rlApiC.toString();
assert allClasses.size() > 0 : "No rs api class implements rl api class " + rlApiC;
boolean changed;
do
if (allClasses.size() == 1)
{
changed = false;
for (RSApiClass interf : highestKnown.getApiInterfaces())
RSApiClass highestKnown = allClasses.stream().findFirst().get();
boolean changed;
do
{
if (interf.getInterfaces().contains(rlApiC))
changed = false;
for (RSApiClass interf : highestKnown.getApiInterfaces())
{
highestKnown = interf;
changed = true;
break;
if (interf.getInterfaces().contains(rlApiC))
{
highestKnown = interf;
changed = true;
break;
}
}
}
while (changed);
return apiToDeob(data, Type.getType(highestKnown.getName(), api.getDimensions()));
}
else
{
for (RSApiClass rsApiClass : allClasses)
{
if (rsApiClass.getName().contains(deobType.getInternalName()))
{
return apiToDeob(data, Type.getType(rsApiClass.getName(), api.getDimensions()));
}
}
}
while (changed);
return apiToDeob(data, Type.getType(highestKnown.getName(), api.getDimensions()));
}
return api;
@@ -332,11 +405,15 @@ public interface InjectUtil
static Type deobToVanilla(InjectData data, Type deobT)
{
if (deobT.isPrimitive())
{
return deobT;
}
final ClassFile deobClass = data.getDeobfuscated().findClass(deobT.getInternalName());
if (deobClass == null)
{
return deobT;
}
return Type.getType("L" + data.toVanilla(deobClass).getName() + ";", deobT.getDimensions());
}
@@ -352,18 +429,24 @@ public interface InjectUtil
List<Type> bb = b.getArguments();
if (aa.size() != bb.size())
{
return false;
}
for (int i = 0; i < aa.size(); i++)
{
if (!aa.get(i).equals(bb.get(i)))
{
return false;
}
}
return true;
}
/**
* Gets the obfuscated name from something's annotations.
*
* <p>
* If the annotation doesn't exist return the current name instead.
*/
static <T extends Annotated & Named> String getObfuscatedName(T from)
@@ -387,7 +470,9 @@ public interface InjectUtil
static Instruction createLoadForTypeIndex(Instructions instructions, Type type, int index)
{
if (type.getDimensions() > 0 || !type.isPrimitive())
{
return new ALoad(instructions, index);
}
switch (type.toString())
{
@@ -414,7 +499,9 @@ public interface InjectUtil
static Instruction createReturnForType(Instructions instructions, Type type)
{
if (!type.isPrimitive())
{
return new Return(instructions, InstructionType.ARETURN);
}
switch (type.toString())
{
@@ -440,9 +527,13 @@ public interface InjectUtil
static Instruction createInvokeFor(Instructions instructions, net.runelite.asm.pool.Method method, boolean isStatic)
{
if (isStatic)
{
return new InvokeStatic(instructions, method);
}
else
{
return new InvokeVirtual(instructions, method);
}
}
/**
@@ -463,9 +554,13 @@ public interface InjectUtil
into.accept(new LDC(instrs, getter));
if (getter instanceof Integer)
{
into.accept(new IMul(instrs));
}
else if (getter instanceof Long)
{
into.accept(new LMul(instrs));
}
}
/**
@@ -477,4 +572,27 @@ public interface InjectUtil
{
injectObfuscatedGetter(DMath.modInverse(getter), instrs, into);
}
private static List<Type> findArgs(final String str, final List<Type> ret, final int from, final int to)
{
if (from >= to)
{
return ret;
}
int i = from;
while (str.charAt(i) == '[')
{
++i;
}
if (str.charAt(i) == 'L')
{
i = str.indexOf(';', i);
}
ret.add(new Type(str.substring(from, ++i)));
return findArgs(str, ret, i, to);
}
}