Search in sources :

Example 56 with ClassGroup

use of net.runelite.asm.ClassGroup in project runelite by runelite.

the class ClassGroupFactory method generateGroup.

public static ClassGroup generateGroup() {
    ClassGroup group = new ClassGroup();
    ClassFile cf = new ClassFile(group);
    cf.setName("test");
    cf.setSuperName("java/lang/Object");
    group.addClass(cf);
    Field field = new Field(cf, "field", Type.INT);
    field.setStatic();
    cf.addField(field);
    Method method = new Method(cf, "func", new Signature("()V"));
    method.setStatic();
    cf.addMethod(method);
    Code code = new Code(method);
    method.setCode(code);
    {
        method = new Method(cf, "func2", new Signature("(III)V"));
        method.setStatic();
        cf.addMethod(method);
        code = new Code(method);
        method.setCode(code);
        Instructions ins = code.getInstructions();
        ins.addInstruction(new VReturn(ins));
    }
    addVoidMethod(cf, "void1");
    addVoidMethod(cf, "void2");
    addVoidMethod(cf, "void3");
    addVoidMethod(cf, "void4");
    return group;
}
Also used : Field(net.runelite.asm.Field) ClassFile(net.runelite.asm.ClassFile) ClassGroup(net.runelite.asm.ClassGroup) Signature(net.runelite.asm.signature.Signature) Instructions(net.runelite.asm.attributes.code.Instructions) Method(net.runelite.asm.Method) Code(net.runelite.asm.attributes.Code) VReturn(net.runelite.asm.attributes.code.instructions.VReturn)

Example 57 with ClassGroup

use of net.runelite.asm.ClassGroup in project runelite by runelite.

the class MixinInjectorTest method testInject.

@Test
public void testInject() throws Exception {
    InputStream deobIn = getClass().getResourceAsStream("DeobTarget.class");
    ClassFile deobTarget = ClassUtil.loadClass(deobIn);
    ClassGroup deob = new ClassGroup();
    deob.addClass(deobTarget);
    InputStream vanillaIn = getClass().getResourceAsStream("VanillaTarget.class");
    ClassFile vanillaTarget = ClassUtil.loadClass(vanillaIn);
    ClassGroup vanilla = new ClassGroup();
    vanilla.addClass(vanillaTarget);
    Map<Class<?>, List<ClassFile>> mixinClasses = new HashMap<>();
    mixinClasses.put(Source.class, Collections.singletonList(vanillaTarget));
    mixinClasses.put(Source2.class, Collections.singletonList(vanillaTarget));
    Inject inject = new Inject(deob, vanilla);
    new MixinInjector(inject).inject(mixinClasses);
    // Check if "foo" has been injected
    Field foo = vanillaTarget.findField("foo");
    assertNotNull(foo);
    assertEquals(INT, foo.getType());
    assertEquals(ACC_PUBLIC | ACC_STATIC, foo.getAccessFlags());
    // Check if "foo2()V" has been injected
    Method foo2 = vanillaTarget.findMethod("foo2");
    assertNotNull(foo2);
    assertEquals(new Signature("()V"), foo2.getDescriptor());
    assertEquals(ACC_PUBLIC, foo2.getAccessFlags());
    // Check if "ob_foo3(I)V" was copied
    Method foo3 = vanillaTarget.findMethod("copy$foo3");
    assertNotNull(foo3);
    assertEquals(new Signature("(I)V"), foo3.getDescriptor());
    assertEquals(ACC_PUBLIC, foo3.getAccessFlags());
    // Check if "ob_foo3(I)V" was replaced
    Method ob_foo3 = vanillaTarget.findMethod("ob_foo3");
    assertNotNull(ob_foo3);
    assertEquals(new Signature("(I)V"), ob_foo3.getDescriptor());
    assertEquals(ob_foo3.getCode().getInstructions().getInstructions().stream().filter(i -> i instanceof LDC && ((LDC) i).getConstant().equals("replaced")).count(), 1);
    // Check that the "foo4" field access in the new code body was mapped correctly
    assertEquals(ob_foo3.getCode().getInstructions().getInstructions().stream().filter(i -> {
        if (!(i instanceof GetStatic)) {
            return false;
        }
        net.runelite.asm.pool.Field field = ((GetStatic) i).getField();
        if (!field.getClazz().getName().equals("net/runelite/injector/VanillaTarget")) {
            return false;
        }
        if (!field.getName().equals("ob_foo4")) {
            return false;
        }
        return true;
    }).count(), 1);
    // Check that the "foo3()" call in the new code body was mapped to the copy
    assertEquals(ob_foo3.getCode().getInstructions().getInstructions().stream().filter(i -> {
        if (!(i instanceof InvokeVirtual)) {
            return false;
        }
        net.runelite.asm.pool.Method method = ((InvokeVirtual) i).getMethod();
        if (!method.getClazz().getName().equals("net/runelite/injector/VanillaTarget")) {
            return false;
        }
        if (!method.getName().equals("copy$foo3")) {
            return false;
        }
        return true;
    }).count(), 1);
    // Check if "foo5()V" was injected
    Method foo5 = vanillaTarget.findMethod("foo5");
    assertNotNull(foo5);
    assertEquals(new Signature("()V"), foo5.getDescriptor());
    assertEquals(ACC_PUBLIC, foo5.getAccessFlags());
    // Check that the shadow "foo" field access was mapped correctly
    assertEquals(foo5.getCode().getInstructions().getInstructions().stream().filter(i -> {
        if (!(i instanceof GetStatic)) {
            return false;
        }
        net.runelite.asm.pool.Field field = ((GetStatic) i).getField();
        if (!field.getClazz().getName().equals("net/runelite/injector/VanillaTarget")) {
            return false;
        }
        if (!field.getName().equals("foo")) {
            return false;
        }
        return true;
    }).count(), 1);
}
Also used : ClassFile(net.runelite.asm.ClassFile) HashMap(java.util.HashMap) InputStream(java.io.InputStream) LDC(net.runelite.asm.attributes.code.instructions.LDC) Method(net.runelite.asm.Method) Field(net.runelite.asm.Field) GetStatic(net.runelite.asm.attributes.code.instructions.GetStatic) InvokeVirtual(net.runelite.asm.attributes.code.instructions.InvokeVirtual) ClassGroup(net.runelite.asm.ClassGroup) ObfuscatedSignature(net.runelite.mapping.ObfuscatedSignature) Signature(net.runelite.asm.signature.Signature) List(java.util.List) Test(org.junit.Test)

Example 58 with ClassGroup

use of net.runelite.asm.ClassGroup in project runelite by runelite.

the class InjectMojo method execute.

@Override
public void execute() throws MojoExecutionException, MojoFailureException {
    ClientVersion ver = new ClientVersion(new File(vanillaPath));
    int version;
    try {
        version = ver.getVersion();
    } catch (IOException ex) {
        throw new MojoExecutionException("Unable to read vanilla client version", ex);
    }
    log.info("Vanilla client version " + version);
    ClassGroup rs;
    ClassGroup vanilla;
    try {
        rs = JarUtil.loadJar(new File(rsClientPath));
        vanilla = JarUtil.loadJar(new File(vanillaPath));
    } catch (IOException ex) {
        throw new MojoExecutionException("Unable to load dependency jars", ex);
    }
    Injector injector = new Injector(rs, vanilla);
    try {
        injector.inject();
    } catch (InjectionException ex) {
        throw new MojoExecutionException("Error injecting client", ex);
    }
    InjectorValidator iv = new InjectorValidator(vanilla);
    iv.validate();
    if (iv.getError() > 0) {
        throw new MojoExecutionException("Error building injected jar");
    }
    if (iv.getMissing() > 0) {
        throw new MojoExecutionException("Unable to inject all methods");
    }
    try {
        writeClasses(vanilla, outputDirectory);
    } catch (IOException ex) {
        throw new MojoExecutionException("Unable to write classes", ex);
    }
    log.info("Injector wrote " + vanilla.getClasses().size() + " classes, " + iv.getOkay() + " injected methods");
}
Also used : MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) ClassGroup(net.runelite.asm.ClassGroup) IOException(java.io.IOException) ClientVersion(net.runelite.deob.clientver.ClientVersion) File(java.io.File) ClassFile(net.runelite.asm.ClassFile)

Example 59 with ClassGroup

use of net.runelite.asm.ClassGroup in project runelite by runelite.

the class InjectConstruct method inject.

public void inject(Map<ClassFile, java.lang.Class> implemented) throws InjectionException {
    for (Entry<ClassFile, java.lang.Class> entry : implemented.entrySet()) {
        Class<?> clazz = entry.getValue();
        ClassFile cf = entry.getKey();
        if (clazz == null) {
            continue;
        }
        for (java.lang.reflect.Method method : clazz.getDeclaredMethods()) {
            if (method.isSynthetic()) {
                continue;
            }
            Construct construct = method.getAnnotation(Construct.class);
            if (construct == null) {
                continue;
            }
            String obfuscatedName = DeobAnnotations.getObfuscatedName(cf.getAnnotations());
            if (obfuscatedName == null) {
                obfuscatedName = cf.getName();
            }
            ClassGroup vanilla = inject.getVanilla();
            ClassFile other = vanilla.findClass(obfuscatedName);
            assert other != null : "unable to find vanilla class from obfuscated name: " + obfuscatedName;
            injectConstruct(other, method);
        }
    }
}
Also used : ClassFile(net.runelite.asm.ClassFile) ClassGroup(net.runelite.asm.ClassGroup) Construct(net.runelite.mapping.Construct)

Example 60 with ClassGroup

use of net.runelite.asm.ClassGroup in project runelite by runelite.

the class InjectInvoker method process.

/**
 * Inject an invoker for a method
 *
 * @param m Method in the deobfuscated client to inject an invoker for
 * @param other Class in the vanilla client of the same class m is a
 * member of
 * @param implementingClass Java class for the API interface the class
 * will implement
 */
public void process(Method m, ClassFile other, java.lang.Class<?> implementingClass) {
    Annotations an = m.getAnnotations();
    if (an == null || an.find(EXPORT) == null) {
        // not an exported method
        return;
    }
    String exportedName = DeobAnnotations.getExportedName(an);
    String obfuscatedName = DeobAnnotations.getObfuscatedName(an);
    if (obfuscatedName == null) {
        obfuscatedName = m.getName();
    }
    String garbage = DeobAnnotations.getObfuscatedValue(m);
    Method otherm = other.findMethod(obfuscatedName, inject.getMethodSignature(m));
    assert otherm != null;
    assert m.isStatic() == otherm.isStatic();
    ClassGroup vanilla = inject.getVanilla();
    ClassFile targetClass = m.isStatic() ? vanilla.findClass("client") : other;
    // Place into implementing class, unless the method is static
    java.lang.Class<?> targetClassJava = m.isStatic() ? Inject.CLIENT_CLASS : implementingClass;
    if (targetClassJava == null) {
        assert !m.isStatic();
        // non static exported method on non exported interface, weird.
        logger.debug("Non static exported method {} on non exported interface", exportedName);
        return;
    }
    // api method to invoke 'otherm'
    java.lang.reflect.Method apiMethod = inject.findImportMethodOnApi(targetClassJava, exportedName, null);
    if (apiMethod == null) {
        logger.debug("Unable to find api method on {} with imported name {}, not injecting invoker", targetClassJava, exportedName);
        return;
    }
    injectInvoker(targetClass, apiMethod, m, otherm, garbage);
    ++injectedInvokers;
}
Also used : Annotations(net.runelite.asm.attributes.Annotations) DeobAnnotations(net.runelite.deob.DeobAnnotations) ClassFile(net.runelite.asm.ClassFile) ClassGroup(net.runelite.asm.ClassGroup) Method(net.runelite.asm.Method)

Aggregations

ClassGroup (net.runelite.asm.ClassGroup)66 Test (org.junit.Test)41 Code (net.runelite.asm.attributes.Code)29 ClassFile (net.runelite.asm.ClassFile)28 Instruction (net.runelite.asm.attributes.code.Instruction)28 Instructions (net.runelite.asm.attributes.code.Instructions)28 LDC (net.runelite.asm.attributes.code.instructions.LDC)28 VReturn (net.runelite.asm.attributes.code.instructions.VReturn)26 IStore (net.runelite.asm.attributes.code.instructions.IStore)23 Deobfuscator (net.runelite.deob.Deobfuscator)22 ILoad (net.runelite.asm.attributes.code.instructions.ILoad)21 Execution (net.runelite.asm.execution.Execution)21 IMul (net.runelite.asm.attributes.code.instructions.IMul)18 Method (net.runelite.asm.Method)12 IAdd (net.runelite.asm.attributes.code.instructions.IAdd)11 Pop (net.runelite.asm.attributes.code.instructions.Pop)11 File (java.io.File)9 Label (net.runelite.asm.attributes.code.Label)9 Type (net.runelite.asm.Type)8 Signature (net.runelite.asm.signature.Signature)8