Search in sources :

Example 51 with Instruction

use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.

the class InjectInvoker method injectInvoker.

private void injectInvoker(ClassFile clazz, java.lang.reflect.Method method, Method deobfuscatedMethod, Method invokeMethod, String garbage) {
    if (clazz.findMethod(method.getName(), deobfuscatedMethod.getDescriptor()) != null) {
        logger.warn("Not injecting method {} because it already exists!", method);
        // this can happen from exporting a field and method with the same name
        return;
    }
    assert invokeMethod.isStatic() == deobfuscatedMethod.isStatic();
    assert invokeMethod.isStatic() || invokeMethod.getClassFile() == clazz;
    Type lastGarbageArgumentType = null;
    if (deobfuscatedMethod.getDescriptor().getArguments().size() != invokeMethod.getDescriptor().getArguments().size()) {
        // allow for obfuscated method to have a single bogus signature at the end
        assert deobfuscatedMethod.getDescriptor().size() + 1 == invokeMethod.getDescriptor().size();
        List<Type> arguments = invokeMethod.getDescriptor().getArguments();
        lastGarbageArgumentType = arguments.get(arguments.size() - 1);
    }
    // Injected method signature is always the same as the API
    Signature apiSignature = inject.javaMethodToSignature(method);
    Method invokerMethodSignature = new Method(clazz, method.getName(), apiSignature);
    invokerMethodSignature.setAccessFlags(ACC_PUBLIC);
    // create code attribute
    Code code = new Code(invokerMethodSignature);
    invokerMethodSignature.setCode(code);
    Instructions instructions = code.getInstructions();
    List<Instruction> ins = instructions.getInstructions();
    // this + arguments
    code.setMaxStack(1 + invokeMethod.getDescriptor().size());
    // load function arguments onto the stack.
    int index = 0;
    if (!invokeMethod.isStatic()) {
        // this
        ins.add(new ALoad(instructions, index++));
    } else {
        // this method is always non static
        ++index;
    }
    for (int i = 0; i < deobfuscatedMethod.getDescriptor().size(); ++i) {
        Type type = deobfuscatedMethod.getDescriptor().getTypeOfArg(i);
        Instruction loadInstruction = inject.createLoadForTypeIndex(instructions, type, index);
        ins.add(loadInstruction);
        Signature invokeDesc = invokeMethod.getDescriptor();
        Type obType = invokeDesc.getTypeOfArg(i);
        if (!type.equals(obType)) {
            CheckCast checkCast = new CheckCast(instructions);
            checkCast.setType(obType);
            ins.add(checkCast);
        }
        if (loadInstruction instanceof DLoad || loadInstruction instanceof LLoad) {
            index += 2;
        } else {
            index += 1;
        }
    }
    if (lastGarbageArgumentType != null) {
        // if garbage is null here it might just be an unused parameter, not part of the obfuscation
        if (garbage == null) {
            garbage = "0";
        }
        switch(lastGarbageArgumentType.toString()) {
            case "Z":
            case "B":
            case "C":
                ins.add(new BiPush(instructions, Byte.parseByte(garbage)));
                break;
            case "S":
                ins.add(new SiPush(instructions, Short.parseShort(garbage)));
                break;
            case "I":
                ins.add(new LDC(instructions, Integer.parseInt(garbage)));
                break;
            case "D":
                ins.add(new LDC(instructions, Double.parseDouble(garbage)));
                break;
            case "F":
                ins.add(new LDC(instructions, Float.parseFloat(garbage)));
                break;
            case "J":
                ins.add(new LDC(instructions, Long.parseLong(garbage)));
                break;
            default:
                throw new RuntimeException("Unknown type");
        }
    }
    if (invokeMethod.isStatic()) {
        ins.add(new InvokeStatic(instructions, invokeMethod.getPoolMethod()));
    } else {
        ins.add(new InvokeVirtual(instructions, invokeMethod.getPoolMethod()));
    }
    Type returnValue = invokeMethod.getDescriptor().getReturnValue();
    InstructionType returnType;
    if (returnValue.isPrimitive() && returnValue.getDimensions() == 0) {
        switch(returnValue.toString()) {
            case "Z":
            case "I":
                returnType = InstructionType.IRETURN;
                break;
            case "J":
                returnType = InstructionType.LRETURN;
                break;
            case "F":
                returnType = InstructionType.FRETURN;
                break;
            case "D":
                returnType = InstructionType.DRETURN;
                break;
            case "V":
                returnType = InstructionType.RETURN;
                break;
            default:
                assert false;
                return;
        }
    } else {
        returnType = InstructionType.ARETURN;
    }
    ins.add(new Return(instructions, returnType));
    clazz.addMethod(invokerMethodSignature);
}
Also used : SiPush(net.runelite.asm.attributes.code.instructions.SiPush) LLoad(net.runelite.asm.attributes.code.instructions.LLoad) Return(net.runelite.asm.attributes.code.instructions.Return) InstructionType(net.runelite.asm.attributes.code.InstructionType) DLoad(net.runelite.asm.attributes.code.instructions.DLoad) Instructions(net.runelite.asm.attributes.code.Instructions) LDC(net.runelite.asm.attributes.code.instructions.LDC) Method(net.runelite.asm.Method) CheckCast(net.runelite.asm.attributes.code.instructions.CheckCast) Instruction(net.runelite.asm.attributes.code.Instruction) BiPush(net.runelite.asm.attributes.code.instructions.BiPush) Code(net.runelite.asm.attributes.Code) InstructionType(net.runelite.asm.attributes.code.InstructionType) Type(net.runelite.asm.Type) InvokeVirtual(net.runelite.asm.attributes.code.instructions.InvokeVirtual) Signature(net.runelite.asm.signature.Signature) ALoad(net.runelite.asm.attributes.code.instructions.ALoad) InvokeStatic(net.runelite.asm.attributes.code.instructions.InvokeStatic)

Example 52 with Instruction

use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.

the class FieldInliner method makeConstantValues.

private void makeConstantValues() {
    for (ClassFile cf : group.getClasses()) {
        for (Field f : cf.getFields()) {
            if (!f.isStatic() || !f.getType().equals(Type.STRING))
                continue;
            Object constantValue = f.getValue();
            if (constantValue != null)
                continue;
            List<FieldInstruction> sfis = fieldInstructions.get(f).stream().filter(f2 -> f2 instanceof SetFieldInstruction).collect(Collectors.toList());
            if (sfis.size() != 1)
                continue;
            SetFieldInstruction sfi = (SetFieldInstruction) sfis.get(0);
            Instruction ins = (Instruction) sfi;
            Method mOfSet = ins.getInstructions().getCode().getMethod();
            if (!mOfSet.getName().equals("<clinit>"))
                continue;
            // get prev instruction and change to a constant value
            Instructions instructions = mOfSet.getCode().getInstructions();
            int idx = instructions.getInstructions().indexOf(ins);
            assert idx != -1;
            Instruction prev = instructions.getInstructions().get(idx - 1);
            if (!(prev instanceof PushConstantInstruction))
                continue;
            PushConstantInstruction pci = (PushConstantInstruction) prev;
            constantValue = pci.getConstant();
            f.setValue(constantValue);
            fields.add(f);
            boolean b = instructions.getInstructions().remove(prev);
            assert b;
            b = instructions.getInstructions().remove(ins);
            assert b;
        }
    }
}
Also used : Logger(org.slf4j.Logger) FieldInstruction(net.runelite.asm.attributes.code.instruction.types.FieldInstruction) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) Field(net.runelite.asm.Field) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) LoggerFactory(org.slf4j.LoggerFactory) GetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction) Code(net.runelite.asm.attributes.Code) Multimap(com.google.common.collect.Multimap) Type(net.runelite.asm.Type) Deobfuscator(net.runelite.deob.Deobfuscator) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) ClassGroup(net.runelite.asm.ClassGroup) List(java.util.List) ClassFile(net.runelite.asm.ClassFile) HashMultimap(com.google.common.collect.HashMultimap) Method(net.runelite.asm.Method) LDC(net.runelite.asm.attributes.code.instructions.LDC) Instructions(net.runelite.asm.attributes.code.Instructions) Instruction(net.runelite.asm.attributes.code.Instruction) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) ClassFile(net.runelite.asm.ClassFile) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) Instructions(net.runelite.asm.attributes.code.Instructions) Method(net.runelite.asm.Method) FieldInstruction(net.runelite.asm.attributes.code.instruction.types.FieldInstruction) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) GetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) Field(net.runelite.asm.Field) 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)

Example 53 with Instruction

use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.

the class IllegalStateExceptions method processOne.

private void processOne(InstructionContext ic) {
    Instruction ins = ic.getInstruction();
    Instructions instructions = ins.getInstructions();
    if (instructions == null)
        return;
    List<Instruction> ilist = instructions.getInstructions();
    JumpingInstruction jumpIns = (JumpingInstruction) ins;
    assert jumpIns.getJumps().size() == 1;
    Instruction to = jumpIns.getJumps().get(0);
    // remove stack of if.
    if (ins instanceof If) {
        ic.removeStack(1);
    }
    ic.removeStack(0);
    int i = ilist.indexOf(ins);
    assert i != -1;
    // remove up to athrow
    while (!(ins instanceof AThrow)) {
        instructions.remove(ins);
        // don't need to ++i because
        ins = ilist.get(i);
    }
    // remove athrow
    instructions.remove(ins);
    // insert goto
    assert ilist.contains(to);
    Goto g = new Goto(instructions, instructions.createLabelFor(to));
    ilist.add(i, g);
    ++count;
}
Also used : JumpingInstruction(net.runelite.asm.attributes.code.instruction.types.JumpingInstruction) Goto(net.runelite.asm.attributes.code.instructions.Goto) Instructions(net.runelite.asm.attributes.code.Instructions) ComparisonInstruction(net.runelite.asm.attributes.code.instruction.types.ComparisonInstruction) JumpingInstruction(net.runelite.asm.attributes.code.instruction.types.JumpingInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) If(net.runelite.asm.attributes.code.instructions.If) AThrow(net.runelite.asm.attributes.code.instructions.AThrow)

Example 54 with Instruction

use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.

the class Lvt method process.

private void process(Method method) {
    Code code = method.getCode();
    if (code == null) {
        return;
    }
    Mappings mappings = new Mappings(code.getMaxLocals());
    for (Instruction ins : code.getInstructions().getInstructions()) {
        if (!(ins instanceof LVTInstruction)) {
            continue;
        }
        LVTInstruction lv = (LVTInstruction) ins;
        Integer newIdx = mappings.remap(lv.getVariableIndex(), lv.type());
        if (newIdx == null) {
            continue;
        }
        assert newIdx != lv.getVariableIndex();
        Instruction newIns = lv.setVariableIndex(newIdx);
        assert ins == newIns;
        ++count;
    }
}
Also used : Mappings(net.runelite.deob.deobfuscators.lvt.Mappings) Instruction(net.runelite.asm.attributes.code.Instruction) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) Code(net.runelite.asm.attributes.Code)

Example 55 with Instruction

use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.

the class CodeVisitor method createInstructionFromOpcode.

private Instruction createInstructionFromOpcode(int opcode) {
    InstructionType type = InstructionType.findInstructionFromCode(opcode);
    assert type != null;
    try {
        Constructor<? extends Instruction> con = type.getInstructionClass().getConstructor(Instructions.class, InstructionType.class);
        Instruction ins = con.newInstance(code.getInstructions(), type);
        code.getInstructions().addInstruction(ins);
        return ins;
    } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
        throw new RuntimeException(ex);
    }
}
Also used : InstructionType(net.runelite.asm.attributes.code.InstructionType) FieldInstruction(net.runelite.asm.attributes.code.instruction.types.FieldInstruction) TypeInstruction(net.runelite.asm.attributes.code.instruction.types.TypeInstruction) InvokeInstruction(net.runelite.asm.attributes.code.instruction.types.InvokeInstruction) JumpingInstruction(net.runelite.asm.attributes.code.instruction.types.JumpingInstruction) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) IntInstruction(net.runelite.asm.attributes.code.instruction.types.IntInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Aggregations

Instruction (net.runelite.asm.attributes.code.Instruction)109 Instructions (net.runelite.asm.attributes.code.Instructions)69 Code (net.runelite.asm.attributes.Code)48 LDC (net.runelite.asm.attributes.code.instructions.LDC)39 LVTInstruction (net.runelite.asm.attributes.code.instruction.types.LVTInstruction)32 PushConstantInstruction (net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction)32 ClassGroup (net.runelite.asm.ClassGroup)31 InvokeInstruction (net.runelite.asm.attributes.code.instruction.types.InvokeInstruction)29 IMul (net.runelite.asm.attributes.code.instructions.IMul)28 VReturn (net.runelite.asm.attributes.code.instructions.VReturn)28 Test (org.junit.Test)27 ILoad (net.runelite.asm.attributes.code.instructions.ILoad)25 Method (net.runelite.asm.Method)24 IStore (net.runelite.asm.attributes.code.instructions.IStore)24 Execution (net.runelite.asm.execution.Execution)23 Deobfuscator (net.runelite.deob.Deobfuscator)22 Label (net.runelite.asm.attributes.code.Label)19 ArrayList (java.util.ArrayList)17 InstructionContext (net.runelite.asm.execution.InstructionContext)17 Field (net.runelite.asm.Field)16