Redirect supercalls in obfuscated overrides.
This commit is contained in:
@@ -24,13 +24,15 @@ import net.runelite.deob.attributes.code.instructions.LLoad;
|
|||||||
import net.runelite.deob.attributes.code.instructions.New;
|
import net.runelite.deob.attributes.code.instructions.New;
|
||||||
import net.runelite.deob.attributes.code.instructions.Pop;
|
import net.runelite.deob.attributes.code.instructions.Pop;
|
||||||
import net.runelite.deob.attributes.code.instructions.Return;
|
import net.runelite.deob.attributes.code.instructions.Return;
|
||||||
|
import net.runelite.deob.pool.NameAndType;
|
||||||
import net.runelite.deob.signature.Type;
|
import net.runelite.deob.signature.Type;
|
||||||
|
|
||||||
public class InjectReplace
|
public class InjectReplace
|
||||||
{
|
{
|
||||||
private static final Type REPLACE = new Type("Lnet/runelite/mapping/Replace;");
|
private static final Type REPLACE = new Type("Lnet/runelite/mapping/Replace;");
|
||||||
private static final Type OBFUSCATED_OVERRIDE = new Type("Lnet/runelite/mapping/ObfuscatedOverride;");
|
private static final Type OBFUSCATED_OVERRIDE = new Type("Lnet/runelite/mapping/ObfuscatedOverride;");
|
||||||
private static final Type OBFUSCATED_NAME = new Type("Lnet/runelite/mapping/ObfuscatedName;");
|
//private static final Type OBFUSCATED_NAME = new Type("Lnet/runelite/mapping/ObfuscatedName;");
|
||||||
|
private static final Type EXPORT = new Type("Lnet/runelite/mapping/Export;");
|
||||||
|
|
||||||
private ClassFile cf, vanilla;
|
private ClassFile cf, vanilla;
|
||||||
|
|
||||||
@@ -71,7 +73,7 @@ public class InjectReplace
|
|||||||
vanilla.getGroup().addClass(classToInject);
|
vanilla.getGroup().addClass(classToInject);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert classToInject.getParentClass().getName().equals("java/lang/Object");
|
// parent is either java/lang/Object or a dummy class so that invokespecial (super) calls work.
|
||||||
assert classToInject.isAbstract();
|
assert classToInject.isAbstract();
|
||||||
|
|
||||||
// set parent
|
// set parent
|
||||||
@@ -220,7 +222,8 @@ public class InjectReplace
|
|||||||
String overridenMethod = annotation.getElement().getString(); // name of @Exported method to override
|
String overridenMethod = annotation.getElement().getString(); // name of @Exported method to override
|
||||||
|
|
||||||
// Find method with exported name on 'cf'
|
// Find method with exported name on 'cf'
|
||||||
Method obfuscatedMethodToOverride = findMethodByObfuscatedName(overridenMethod);
|
Method obfuscatedMethodToOverride = findMethodByExportedName(overridenMethod);
|
||||||
|
NameAndType deobfuscatedNat = m.getNameAndType();
|
||||||
|
|
||||||
assert obfuscatedMethodToOverride != null;
|
assert obfuscatedMethodToOverride != null;
|
||||||
assert !obfuscatedMethodToOverride.isFinal();
|
assert !obfuscatedMethodToOverride.isFinal();
|
||||||
@@ -246,23 +249,44 @@ public class InjectReplace
|
|||||||
|
|
||||||
// Now that the function is overriden, when the invoke injector is called, it turns around and invokevirtuals
|
// Now that the function is overriden, when the invoke injector is called, it turns around and invokevirtuals
|
||||||
// the parent method, which hits ours.
|
// the parent method, which hits ours.
|
||||||
|
|
||||||
|
// locate super.method() calls and modify...
|
||||||
|
for (Instruction i : m.getCode().getInstructions().getInstructions())
|
||||||
|
{
|
||||||
|
if (!(i instanceof InvokeSpecial))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
InvokeSpecial is = (InvokeSpecial) i;
|
||||||
|
|
||||||
|
net.runelite.deob.pool.Method invokedMethod = (net.runelite.deob.pool.Method) is.getMethod();
|
||||||
|
|
||||||
|
if (invokedMethod.getNameAndType().equals(deobfuscatedNat))
|
||||||
|
{
|
||||||
|
is.setMethod(
|
||||||
|
new net.runelite.deob.pool.Method(
|
||||||
|
classToInject.getParentClass(), // invokedMethod.getClassEntry() is probably our dummy class
|
||||||
|
m.getNameAndType() // set to obfuscated name
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Method findMethodByObfuscatedName(String name)
|
private Method findMethodByExportedName(String name)
|
||||||
{
|
{
|
||||||
for (Method m : cf.getMethods().getMethods())
|
for (Method m : cf.getMethods().getMethods())
|
||||||
{
|
{
|
||||||
Attributes attributes = m.getAttributes();
|
Attributes attributes = m.getAttributes();
|
||||||
Annotations annotations = attributes.getAnnotations();
|
Annotations annotations = attributes.getAnnotations();
|
||||||
|
|
||||||
if (annotations == null || annotations.find(OBFUSCATED_NAME) == null)
|
if (annotations == null || annotations.find(EXPORT) == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Annotation annotation = annotations.find(OBFUSCATED_NAME);
|
Annotation annotation = annotations.find(EXPORT);
|
||||||
String obfuscatedName = annotation.getElement().getString();
|
String exportedName = annotation.getElement().getString();
|
||||||
|
|
||||||
if (name.equals(obfuscatedName))
|
if (name.equals(exportedName))
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,6 +343,10 @@ public class InjectReplace
|
|||||||
// new vanilla -> new classToInject
|
// new vanilla -> new classToInject
|
||||||
|
|
||||||
for (ClassFile cf : vanilla.getGroup().getClasses())
|
for (ClassFile cf : vanilla.getGroup().getClasses())
|
||||||
|
{
|
||||||
|
if (cf == classToInject)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (Method m : cf.getMethods().getMethods())
|
for (Method m : cf.getMethods().getMethods())
|
||||||
{
|
{
|
||||||
Code code = m.getCode();
|
Code code = m.getCode();
|
||||||
@@ -364,5 +392,6 @@ public class InjectReplace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user