use of net.runelite.asm.ClassGroup in project runelite by runelite.
the class InjectHookMethod method process.
public void process(Method method) throws InjectionException {
Annotations an = method.getAnnotations();
if (an == null) {
return;
}
Annotation a = an.find(DeobAnnotations.HOOK);
if (a == null) {
return;
}
// Method is hooked
// String hookName = DeobAnnotations.getHookName(an); // hook name
// Find equivalent method in vanilla, and insert callback at the beginning
ClassFile cf = method.getClassFile();
String obfuscatedMethodName = DeobAnnotations.getObfuscatedName(an), obfuscatedClassName = DeobAnnotations.getObfuscatedName(cf.getAnnotations());
// might be a constructor
if (obfuscatedMethodName == null && method.getName().equals("<init>")) {
obfuscatedMethodName = "<init>";
}
assert obfuscatedClassName != null : "hook on method in class with no obfuscated name";
assert obfuscatedMethodName != null : "hook on method with no obfuscated name";
Signature obfuscatedSignature = inject.getMethodSignature(method);
ClassGroup vanilla = inject.getVanilla();
ClassFile vanillaClass = vanilla.findClass(obfuscatedClassName);
Method vanillaMethod = vanillaClass.findMethod(obfuscatedMethodName, obfuscatedSignature);
// Insert instructions at beginning of method
injectHookMethod(a, method, vanillaMethod);
}
use of net.runelite.asm.ClassGroup in project runelite by runelite.
the class Deob method main.
public static void main(String[] args) throws IOException {
if (args == null || args.length < 2) {
System.err.println("Syntax: input_jar output_jar");
System.exit(-1);
}
logger.info("Deobfuscator revision {}", DeobProperties.getRevision());
Stopwatch stopwatch = Stopwatch.createStarted();
ClassGroup group = JarUtil.loadJar(new File(args[0]));
// remove except RuntimeException
run(group, new RuntimeExceptions());
run(group, new ControlFlowDeobfuscator());
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 illegal state exceptions, frees up some parameters
run(group, new IllegalStateExceptions());
// remove constant logically dead parameters
run(group, new ConstantParameter());
// remove unhit blocks
run(group, new UnreachedCode());
run(group, new UnusedMethods());
// remove unused parameters
run(group, new UnusedParameters());
// remove unused fields
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());
run(group, new UnusedClass());
runMath(group);
run(group, new ExprArgOrder());
run(group, new Lvt());
run(group, new CastNull());
run(group, new EnumDeobfuscator());
new OpcodesTransformer().transform(group);
// run(group, new PacketHandlerOrder());
// run(group, new PacketWriteDeobfuscator());
run(group, new MenuActionDeobfuscator());
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]));
stopwatch.stop();
logger.info("Done in {}", stopwatch);
}
use of net.runelite.asm.ClassGroup in project runelite by runelite.
the class UnusedParameters method removeParameter.
public void removeParameter(ClassGroup group, List<Method> methods, Signature signature, Execution execution, int paramIndex, int lvtIndex) {
int slots = signature.getTypeOfArg(paramIndex).getSize();
for (ClassFile cf : group.getClasses()) {
for (Method m : cf.getMethods()) {
Code c = m.getCode();
if (c == null) {
continue;
}
for (Instruction i : new ArrayList<>(c.getInstructions().getInstructions())) {
if (!(i instanceof InvokeInstruction)) {
continue;
}
InvokeInstruction ii = (InvokeInstruction) i;
if (!ii.getMethods().stream().anyMatch(me -> methods.contains(me))) {
continue;
}
// remove parameter from instruction
ii.removeParameter(paramIndex);
Collection<InstructionContext> ics = invokes.get(i);
assert ics != null;
if (ics != null) {
for (InstructionContext ins : ics) {
// index from top of stack of parameter. 0 is the last parameter
int pops = signature.size() - paramIndex - 1;
StackContext sctx = ins.getPops().get(pops);
if (sctx.getPushed().getInstruction().getInstructions() == null) {
continue;
}
// remove parameter from stack
ins.removeStack(pops);
}
}
}
}
}
for (Method method : methods) {
if (method.getCode() != null) // adjust lvt indexes to get rid of idx in the method
{
for (Instruction ins : method.getCode().getInstructions().getInstructions()) {
if (ins instanceof LVTInstruction) {
LVTInstruction lins = (LVTInstruction) ins;
int i = lins.getVariableIndex();
// current unused variable detection just looks for no accesses
assert i != lvtIndex;
// reassign
if (i > lvtIndex) {
assert i > 0;
assert i >= lvtIndex + slots;
Instruction newIns = lins.setVariableIndex(i - slots);
assert ins == newIns;
}
}
}
}
}
for (Method method : methods) {
method.getDescriptor().remove(paramIndex);
}
}
use of net.runelite.asm.ClassGroup in project runelite by runelite.
the class PutField method getMyField.
@Override
public net.runelite.asm.Field getMyField() {
Class clazz = field.getClazz();
ClassGroup group = this.getInstructions().getCode().getMethod().getClassFile().getGroup();
ClassFile cf = group.findClass(clazz.getName());
if (cf == null) {
return null;
}
net.runelite.asm.Field f2 = cf.findFieldDeep(field.getName(), field.getType());
return f2;
}
use of net.runelite.asm.ClassGroup in project runelite by runelite.
the class InjectHookMethodTest method testProcess.
@Test
public void testProcess() throws IOException, InjectionException {
InputStream in = getClass().getResourceAsStream("Actor.class");
ClassFile cf = ClassUtil.loadClass(in);
cf.setName("Actor");
cf.findMethod("bar").setDescriptor(new Signature("(LActor;I)I"));
ClassGroup deobfuscated = new ClassGroup();
deobfuscated.addClass(cf);
in = getClass().getResourceAsStream("Obfuscated.class");
ClassFile obcf = ClassUtil.loadClass(in);
obcf.setName("Obfuscated");
obcf.findMethod("foo").setDescriptor(new Signature("(LObfuscated;I)I"));
ClassGroup obfuscated = new ClassGroup();
obfuscated.addClass(obcf);
Method method = cf.findMethod("bar");
assert method != null;
Inject inject = new Inject(deobfuscated, obfuscated);
InjectHookMethod injectHookMethod = new InjectHookMethod(inject);
injectHookMethod.process(method);
method = obcf.findMethod("foo");
assert method != null;
Code code = method.getCode();
List<InvokeStatic> invokeIns = code.getInstructions().getInstructions().stream().filter(i -> i instanceof InvokeStatic).map(i -> (InvokeStatic) i).filter(i -> i.getMethod().getClazz().getName().equals(HOOKS)).collect(Collectors.toList());
assertTrue(!invokeIns.isEmpty());
assertEquals(2, invokeIns.size());
InvokeStatic invokeStatic = invokeIns.get(0);
Signature signature = invokeStatic.getMethod().getType();
// this + patamers
assertEquals(3, signature.size());
Type arg = signature.getTypeOfArg(1);
assertEquals(RL_API_PACKAGE_BASE.replace('.', '/') + "Actor", arg.getInternalName());
}
Aggregations