Add menu raw injector
This commit is contained in:
@@ -203,9 +203,16 @@ public class Method
|
||||
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()
|
||||
|
||||
@@ -27,14 +27,10 @@ package net.runelite.deob;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassFile;
|
||||
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.deob.deobfuscators.CastNull;
|
||||
import net.runelite.deob.deobfuscators.StaticShouldBeInstance;
|
||||
import net.runelite.deob.deobfuscators.constparam.ConstantParameter;
|
||||
import net.runelite.deob.deobfuscators.EnumDeobfuscator;
|
||||
import net.runelite.deob.deobfuscators.FieldInliner;
|
||||
@@ -85,85 +81,70 @@ public class Deob
|
||||
|
||||
ClassGroup group = JarUtil.loadJar(new File(args[0]));
|
||||
|
||||
for (ClassFile f : group.getClasses())
|
||||
if (args.length > 2 && args[2].equals("rl"))
|
||||
{
|
||||
f.getAnnotations().clearAnnotations();
|
||||
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());
|
||||
}
|
||||
}
|
||||
run(group, new StaticShouldBeInstance());
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove except RuntimeException
|
||||
run(group, new RuntimeExceptions());
|
||||
|
||||
// remove except RuntimeException
|
||||
run(group, new RuntimeExceptions());
|
||||
run(group, new ControlFlowDeobfuscator());
|
||||
|
||||
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,
|
||||
// which is not valid, so unused methods is run after
|
||||
run(group, new UnreachedCode());
|
||||
run(group, new UnusedMethods());
|
||||
// remove illegal state exceptions, frees up some parameters
|
||||
run(group, new IllegalStateExceptions());
|
||||
|
||||
// remove illegal state exceptions, frees up some parameters
|
||||
run(group, new IllegalStateExceptions());
|
||||
// remove constant logically dead parameters
|
||||
run(group, new ConstantParameter());
|
||||
|
||||
// remove constant logically dead parameters
|
||||
run(group, new ConstantParameter());
|
||||
// remove unhit blocks
|
||||
run(group, new UnreachedCode());
|
||||
run(group, new UnusedMethods());
|
||||
|
||||
// remove unhit blocks
|
||||
run(group, new UnreachedCode());
|
||||
run(group, new UnusedMethods());
|
||||
// remove unused parameters
|
||||
run(group, new UnusedParameters());
|
||||
|
||||
// remove unused parameters
|
||||
run(group, new UnusedParameters());
|
||||
// remove unused fields
|
||||
run(group, new UnusedFields());
|
||||
|
||||
// remove unused fields
|
||||
run(group, new UnusedFields());
|
||||
run(group, new FieldInliner());
|
||||
|
||||
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,
|
||||
// so run it before removing classes below
|
||||
run(group, new Order());
|
||||
run(group, new UnusedClass());
|
||||
|
||||
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 PacketHandlerOrder());
|
||||
//run(group, new PacketWriteDeobfuscator());
|
||||
run(group, new MenuActionDeobfuscator());
|
||||
|
||||
run(group, new MenuActionDeobfuscator());
|
||||
|
||||
new GetPathTransformer().transform(group);
|
||||
new ClientErrorTransformer().transform(group);
|
||||
new ReflectionTransformer().transform(group);
|
||||
new MaxMemoryTransformer().transform(group);
|
||||
//new RuneliteBufferTransformer().transform(group);
|
||||
new GetPathTransformer().transform(group);
|
||||
new ClientErrorTransformer().transform(group);
|
||||
new ReflectionTransformer().transform(group);
|
||||
new MaxMemoryTransformer().transform(group);
|
||||
//new RuneliteBufferTransformer().transform(group);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
clinit = new Method(runeliteOpcodes, "<clinit>", new Signature("()V"));
|
||||
clinit.setStatic();
|
||||
clinit.setStatic(true);
|
||||
Code code = new Code(clinit);
|
||||
code.setMaxStack(1);
|
||||
clinit.setCode(code);
|
||||
|
||||
@@ -26,19 +26,24 @@ package net.runelite.deob.updater;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
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.AnnotationMapper;
|
||||
import net.runelite.deob.deobfuscators.mapping.Mapper;
|
||||
import net.runelite.deob.deobfuscators.mapping.ParallelExecutorMapping;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import net.runelite.deob.util.NameMappings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class UpdateMappings
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(UpdateMappings.class);
|
||||
|
||||
private static boolean renameRL = true;
|
||||
private final ClassGroup group1, group2;
|
||||
|
||||
public UpdateMappings(ClassGroup group1, ClassGroup group2)
|
||||
@@ -74,6 +79,32 @@ public class UpdateMappings
|
||||
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
|
||||
{
|
||||
JarUtil.saveJar(group2, out);
|
||||
@@ -90,7 +121,14 @@ public class UpdateMappings
|
||||
JarUtil.loadJar(new File(args[0])),
|
||||
JarUtil.loadJar(new File(args[1]))
|
||||
);
|
||||
u.update();
|
||||
if (renameRL)
|
||||
{
|
||||
u.updateRL();
|
||||
}
|
||||
else
|
||||
{
|
||||
u.update();
|
||||
}
|
||||
u.save(new File(args[2]));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user