Search in sources :

Example 41 with LDC

use of net.runelite.asm.attributes.code.instructions.LDC in project runelite by runelite.

the class ModArith method findConstants.

// find associated constants with each field
private void findConstants(MethodContext mctx) {
    for (InstructionContext ctx : mctx.getInstructionContexts()) {
        if (ctx.getInstruction() instanceof FieldInstruction) {
            FieldInstruction fi = (FieldInstruction) ctx.getInstruction();
            if (fi.getMyField() == null) {
                continue;
            }
            if ((!fi.getField().getType().equals(Type.INT) && !fi.getField().getType().equals(Type.LONG)) || fi.getField().getType().isArray()) {
                continue;
            }
            FieldInfo fieldInfo = getFieldInfo(fi.getMyField());
            List<InstructionContext> l = getInsInExpr(ctx, new HashSet(), false);
            // check if this contains another field
            boolean other = false;
            boolean getter = false, setter = false;
            for (InstructionContext i : l) {
                if (i.getInstruction() instanceof FieldInstruction) {
                    FieldInstruction fi2 = (FieldInstruction) i.getInstruction();
                    Field myField = fi2.getMyField();
                    if (myField != null && myField != fi.getMyField()) {
                        Type t = myField.getType();
                        if (t.equals(fi.getMyField().getType())) {
                            other = true;
                        }
                    } else if (myField != null && myField == fi.getMyField()) {
                        if (fi2 instanceof SetFieldInstruction) {
                            setter = true;
                        } else {
                            getter = true;
                        }
                    }
                }
            }
            // check if this is a constant assignment
            boolean constant = false;
            if (fi instanceof SetFieldInstruction) {
                // value being set
                InstructionContext pushedsfi = ctx.getPops().get(0).getPushed();
                pushedsfi = pushedsfi.resolve(ctx.getPops().get(0));
                if (pushedsfi.getInstruction() instanceof LDC) {
                    constant = true;
                }
            }
            for (InstructionContext i : l) {
                if (i.getInstruction() instanceof LDC) {
                    PushConstantInstruction w = (PushConstantInstruction) i.getInstruction();
                    if (w.getConstant() instanceof Integer || w.getConstant() instanceof Long) {
                        AssociatedConstant n = new AssociatedConstant();
                        n.value = (Number) w.getConstant();
                        n.other = other;
                        n.constant = constant;
                        n.getter = getter;
                        n.setter = setter;
                        fieldInfo.constants.add(n);
                    }
                }
            }
        }
    }
}
Also used : InstructionContext(net.runelite.asm.execution.InstructionContext) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) LDC(net.runelite.asm.attributes.code.instructions.LDC) Field(net.runelite.asm.Field) Type(net.runelite.asm.Type) FieldInstruction(net.runelite.asm.attributes.code.instruction.types.FieldInstruction) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) GetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction) HashSet(java.util.HashSet)

Example 42 with LDC

use of net.runelite.asm.attributes.code.instructions.LDC in project runelite by runelite.

the class MultiplyZeroDeobfuscator method visit.

private void visit(MethodContext mctx) {
    for (InstructionContext ictx : mctx.getInstructionContexts()) {
        Instruction instruction = ictx.getInstruction();
        Instructions ins = instruction.getInstructions();
        if (ins == null) {
            continue;
        }
        if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) {
            continue;
        }
        List<Instruction> ilist = ins.getInstructions();
        StackContext one = ictx.getPops().get(0);
        StackContext two = ictx.getPops().get(1);
        Instruction ione = one.getPushed().getInstruction(), itwo = two.getPushed().getInstruction();
        boolean remove = false;
        if (ione instanceof PushConstantInstruction) {
            PushConstantInstruction pci = (PushConstantInstruction) ione;
            Number value = (Number) pci.getConstant();
            if (DMath.equals(value, 0)) {
                remove = true;
            }
        }
        if (itwo instanceof PushConstantInstruction) {
            PushConstantInstruction pci = (PushConstantInstruction) itwo;
            Number value = (Number) pci.getConstant();
            if (DMath.equals(value, 0)) {
                remove = true;
            }
        }
        if (remove == false) {
            continue;
        }
        if (!ilist.contains(instruction)) {
            // already done
            continue;
        }
        if (!MultiplicationDeobfuscator.isOnlyPath(ictx, null)) {
            continue;
        }
        // remove both, remove imul, push 0
        ictx.removeStack(1);
        ictx.removeStack(0);
        if (instruction instanceof IMul) {
            ins.replace(instruction, new LDC(ins, 0));
        } else if (instruction instanceof LMul) {
            ins.replace(instruction, new LDC(ins, 0L));
        } else {
            throw new IllegalStateException();
        }
        ++count;
    }
}
Also used : InstructionContext(net.runelite.asm.execution.InstructionContext) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) StackContext(net.runelite.asm.execution.StackContext) IMul(net.runelite.asm.attributes.code.instructions.IMul) Instructions(net.runelite.asm.attributes.code.Instructions) LDC(net.runelite.asm.attributes.code.instructions.LDC) LMul(net.runelite.asm.attributes.code.instructions.LMul) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) Instruction(net.runelite.asm.attributes.code.Instruction)

Example 43 with LDC

use of net.runelite.asm.attributes.code.instructions.LDC in project runelite by runelite.

the class OpcodeReplacer method run.

public void run(ClassGroup group, Collection<PacketWrite> writes) {
    int count = 0;
    ClassFile runeliteOpcodes = group.findClass(RUNELITE_OPCODES);
    assert runeliteOpcodes != null : "Opcodes class must exist";
    for (PacketWrite wp : writes) {
        Instructions ins = wp.getInstructions();
        Instruction param = wp.getOpcodeIns();
        if (!(param instanceof PushConstantInstruction)) {
            continue;
        }
        final String fieldName = "PACKET_CLIENT_" + wp.getOpcode();
        net.runelite.asm.pool.Field field = new net.runelite.asm.pool.Field(new net.runelite.asm.pool.Class(RUNELITE_OPCODES), fieldName, Type.INT);
        ins.replace(param, new GetStatic(ins, field));
        if (runeliteOpcodes.findField(fieldName) == null) {
            Field opField = new Field(runeliteOpcodes, fieldName, Type.INT);
            // ACC_FINAL causes javac to inline the fields, which prevents
            // the mapper from doing field mapping
            opField.setAccessFlags(ACC_PUBLIC | ACC_STATIC);
            // setting a non-final static field value
            // doesn't work with fernflower
            opField.setValue(wp.getOpcode());
            runeliteOpcodes.addField(opField);
            // add initialization
            Method clinit = runeliteOpcodes.findMethod("<clinit>");
            assert clinit != null;
            Instructions instructions = clinit.getCode().getInstructions();
            instructions.addInstruction(0, new LDC(instructions, wp.getOpcode()));
            instructions.addInstruction(1, new PutStatic(instructions, opField));
        }
        ++count;
    }
    logger.info("Injected {} packet writes", count);
}
Also used : ClassFile(net.runelite.asm.ClassFile) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) Instructions(net.runelite.asm.attributes.code.Instructions) LDC(net.runelite.asm.attributes.code.instructions.LDC) Method(net.runelite.asm.Method) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) PutStatic(net.runelite.asm.attributes.code.instructions.PutStatic) Field(net.runelite.asm.Field) GetStatic(net.runelite.asm.attributes.code.instructions.GetStatic)

Example 44 with LDC

use of net.runelite.asm.attributes.code.instructions.LDC in project runelite by runelite.

the class InjectGetter method injectGetter.

public void injectGetter(ClassFile clazz, java.lang.reflect.Method method, Field field, Number getter) {
    assert clazz.findMethod(method.getName()) == null;
    assert field.isStatic() || field.getClassFile() == clazz;
    Signature sig = new Signature.Builder().setReturnType(Inject.classToType(method.getReturnType())).build();
    Method getterMethod = new Method(clazz, method.getName(), sig);
    getterMethod.setAccessFlags(ACC_PUBLIC);
    // create code
    Code code = new Code(getterMethod);
    getterMethod.setCode(code);
    Instructions instructions = code.getInstructions();
    List<Instruction> ins = instructions.getInstructions();
    if (field.isStatic()) {
        code.setMaxStack(1);
        ins.add(new GetStatic(instructions, field.getPoolField()));
    } else {
        code.setMaxStack(2);
        ins.add(new ALoad(instructions, 0));
        ins.add(new GetField(instructions, field.getPoolField()));
    }
    if (getter != null) {
        code.setMaxStack(2);
        assert getter instanceof Integer || getter instanceof Long;
        if (getter instanceof Integer) {
            ins.add(new LDC(instructions, (int) getter));
            ins.add(new IMul(instructions));
        } else {
            ins.add(new LDC(instructions, (long) getter));
            ins.add(new LMul(instructions));
        }
    }
    InstructionType returnType;
    if (field.getType().isPrimitive() && field.getType().getDimensions() == 0) {
        switch(field.getType().toString()) {
            case "B":
            case "C":
            case "I":
            case "S":
            case "Z":
                returnType = InstructionType.IRETURN;
                break;
            case "D":
                returnType = InstructionType.DRETURN;
                break;
            case "F":
                returnType = InstructionType.FRETURN;
                break;
            case "J":
                returnType = InstructionType.LRETURN;
                break;
            default:
                throw new RuntimeException("Unknown type");
        }
    } else {
        returnType = InstructionType.ARETURN;
    }
    ins.add(new Return(instructions, returnType));
    clazz.addMethod(getterMethod);
    ++injectedGetters;
}
Also used : GetField(net.runelite.asm.attributes.code.instructions.GetField) Return(net.runelite.asm.attributes.code.instructions.Return) InstructionType(net.runelite.asm.attributes.code.InstructionType) Instructions(net.runelite.asm.attributes.code.Instructions) LDC(net.runelite.asm.attributes.code.instructions.LDC) Method(net.runelite.asm.Method) Instruction(net.runelite.asm.attributes.code.Instruction) Code(net.runelite.asm.attributes.Code) GetStatic(net.runelite.asm.attributes.code.instructions.GetStatic) Signature(net.runelite.asm.signature.Signature) IMul(net.runelite.asm.attributes.code.instructions.IMul) LMul(net.runelite.asm.attributes.code.instructions.LMul) ALoad(net.runelite.asm.attributes.code.instructions.ALoad)

Example 45 with LDC

use of net.runelite.asm.attributes.code.instructions.LDC 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)

Aggregations

LDC (net.runelite.asm.attributes.code.instructions.LDC)46 Instruction (net.runelite.asm.attributes.code.Instruction)39 Instructions (net.runelite.asm.attributes.code.Instructions)38 Code (net.runelite.asm.attributes.Code)32 ClassGroup (net.runelite.asm.ClassGroup)29 Test (org.junit.Test)27 VReturn (net.runelite.asm.attributes.code.instructions.VReturn)26 IMul (net.runelite.asm.attributes.code.instructions.IMul)23 IStore (net.runelite.asm.attributes.code.instructions.IStore)23 ILoad (net.runelite.asm.attributes.code.instructions.ILoad)22 Deobfuscator (net.runelite.deob.Deobfuscator)20 Execution (net.runelite.asm.execution.Execution)19 IAdd (net.runelite.asm.attributes.code.instructions.IAdd)14 Pop (net.runelite.asm.attributes.code.instructions.Pop)13 Method (net.runelite.asm.Method)11 Type (net.runelite.asm.Type)10 Label (net.runelite.asm.attributes.code.Label)10 Field (net.runelite.asm.Field)9 PushConstantInstruction (net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction)9 Signature (net.runelite.asm.signature.Signature)8