Search in sources :

Example 6 with InvokeVirtual

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

the class RuneliteBufferTransformer method injectLengthHeader.

/**
 * inject the length header after the packet opcode
 *
 * @param group
 */
private void injectLengthHeader(ClassGroup group) {
    RWOpcodeFinder rw = new RWOpcodeFinder(group);
    rw.find();
    Method writeOpcode = rw.getWriteOpcode();
    Code code = writeOpcode.getCode();
    Instructions instructions = code.getInstructions();
    List<Instruction> ins = instructions.getInstructions();
    Instruction start = ins.get(0);
    Instruction end = ins.stream().filter(i -> i.getType() == RETURN).findFirst().get();
    Label labelForStart = instructions.createLabelFor(start);
    Label labelForEnd = instructions.createLabelFor(end);
    final net.runelite.asm.pool.Field runelitePacketField = new net.runelite.asm.pool.Field(new net.runelite.asm.pool.Class(findClient(group).getName()), RUNELITE_PACKET, Type.BOOLEAN);
    int idx = ins.indexOf(labelForStart);
    instructions.addInstruction(idx++, new GetStatic(instructions, runelitePacketField));
    instructions.addInstruction(idx++, new IfEq(instructions, labelForStart));
    net.runelite.asm.pool.Method method = new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(writeOpcode.getClassFile().getName()), RUNELITE_FINISH_PACKET, new Signature("()V"));
    instructions.addInstruction(idx++, new ALoad(instructions, 0));
    instructions.addInstruction(idx++, new InvokeVirtual(instructions, method));
    idx = ins.indexOf(labelForEnd);
    instructions.addInstruction(idx++, new GetStatic(instructions, runelitePacketField));
    instructions.addInstruction(idx++, new IfEq(instructions, labelForEnd));
    method = new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(writeOpcode.getClassFile().getName()), RUNELITE_INIT_PACKET, new Signature("()V"));
    instructions.addInstruction(idx++, new ALoad(instructions, 0));
    instructions.addInstruction(idx++, new InvokeVirtual(instructions, method));
    logger.info("Injected finish/init packet calls into {}", writeOpcode);
}
Also used : RWOpcodeFinder(net.runelite.deob.c2s.RWOpcodeFinder) Label(net.runelite.asm.attributes.code.Label) Instructions(net.runelite.asm.attributes.code.Instructions) Method(net.runelite.asm.Method) IfEq(net.runelite.asm.attributes.code.instructions.IfEq) Instruction(net.runelite.asm.attributes.code.Instruction) Code(net.runelite.asm.attributes.Code) Field(net.runelite.asm.Field) GetStatic(net.runelite.asm.attributes.code.instructions.GetStatic) InvokeVirtual(net.runelite.asm.attributes.code.instructions.InvokeVirtual) Signature(net.runelite.asm.signature.Signature) ALoad(net.runelite.asm.attributes.code.instructions.ALoad)

Example 7 with InvokeVirtual

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

the class InjectHook method injectCallback.

private void injectCallback(Instructions ins, int idx, HookInfo hookInfo, StackContext index, StackContext objectPusher) throws InjectionException {
    if (hookInfo.staticMethod == false) {
        if (objectPusher == null) {
            throw new InjectionException("Null object pusher");
        }
        idx = recursivelyPush(ins, idx, objectPusher);
        if (index != null) {
            idx = recursivelyPush(ins, idx, index);
        } else {
            ins.getInstructions().add(idx++, new LDC(ins, -1));
        }
        InvokeVirtual invoke = new InvokeVirtual(ins, new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(hookInfo.clazz), hookInfo.method, new Signature(HOOK_METHOD_SIGNATURE)));
        ins.getInstructions().add(idx++, invoke);
    } else {
        if (index != null) {
            idx = recursivelyPush(ins, idx, index);
        } else {
            ins.getInstructions().add(idx++, new LDC(ins, -1));
        }
        InvokeStatic invoke = new InvokeStatic(ins, new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(hookInfo.clazz), hookInfo.method, new Signature(HOOK_METHOD_SIGNATURE)));
        ins.getInstructions().add(idx++, invoke);
    }
}
Also used : InvokeVirtual(net.runelite.asm.attributes.code.instructions.InvokeVirtual) Signature(net.runelite.asm.signature.Signature) LDC(net.runelite.asm.attributes.code.instructions.LDC) InvokeStatic(net.runelite.asm.attributes.code.instructions.InvokeStatic)

Example 8 with InvokeVirtual

use of net.runelite.asm.attributes.code.instructions.InvokeVirtual 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 9 with InvokeVirtual

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

the class MaxMemoryTransformer method transform.

private void transform(Method m) {
    Code code = m.getCode();
    if (code == null) {
        return;
    }
    Instructions ins = code.getInstructions();
    for (Instruction i : ins.getInstructions()) {
        if (i instanceof InvokeVirtual) {
            /*
					invokestatic          java/lang/Runtime/getRuntime()Ljava/lang/Runtime;
					invokevirtual         java/lang/Runtime/maxMemory()J
					ldc2_w                1048576
					ldiv
					l2i
				 */
            if (((InvokeVirtual) i).getMethod().getName().equals("maxMemory")) {
                insert(ins, ins.getInstructions().indexOf(i));
                done = true;
                break;
            }
        }
    }
}
Also used : InvokeVirtual(net.runelite.asm.attributes.code.instructions.InvokeVirtual) Instructions(net.runelite.asm.attributes.code.Instructions) Instruction(net.runelite.asm.attributes.code.Instruction) Code(net.runelite.asm.attributes.Code)

Example 10 with InvokeVirtual

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

the class ReflectionTransformer method transformMethodName.

// invokevirtual         java/lang/reflect/Method/getName()Ljava/lang/String;
// to
// invokestatic          net/runelite/rs/Reflection/getMethodName(Ljava/lang/reflect/Method;)Ljava/lang/String;
private void transformMethodName(Instructions instructions, Instruction i) {
    if (!(i instanceof InvokeVirtual)) {
        return;
    }
    InvokeVirtual iv = (InvokeVirtual) i;
    if (iv.getMethod().getClazz().getName().equals("java/lang/reflect/Method") && iv.getMethod().getName().equals("getName")) {
        InvokeStatic is = new InvokeStatic(instructions, new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class("net/runelite/rs/Reflection"), "getMethodName", new Signature("(Ljava/lang/reflect/Method;)Ljava/lang/String;")));
        instructions.replace(iv, is);
        logger.info("Transformed Method.getName call");
    }
}
Also used : InvokeVirtual(net.runelite.asm.attributes.code.instructions.InvokeVirtual) Signature(net.runelite.asm.signature.Signature) InvokeStatic(net.runelite.asm.attributes.code.instructions.InvokeStatic)

Aggregations

InvokeVirtual (net.runelite.asm.attributes.code.instructions.InvokeVirtual)17 Signature (net.runelite.asm.signature.Signature)15 InvokeStatic (net.runelite.asm.attributes.code.instructions.InvokeStatic)8 Instruction (net.runelite.asm.attributes.code.Instruction)7 Instructions (net.runelite.asm.attributes.code.Instructions)6 Method (net.runelite.asm.Method)5 Code (net.runelite.asm.attributes.Code)5 LDC (net.runelite.asm.attributes.code.instructions.LDC)4 ALoad (net.runelite.asm.attributes.code.instructions.ALoad)3 GetStatic (net.runelite.asm.attributes.code.instructions.GetStatic)3 Field (net.runelite.asm.Field)2 Type (net.runelite.asm.Type)2 InstructionContext (net.runelite.asm.execution.InstructionContext)2 InputStream (java.io.InputStream)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 List (java.util.List)1 ClassFile (net.runelite.asm.ClassFile)1 ClassGroup (net.runelite.asm.ClassGroup)1 InstructionType (net.runelite.asm.attributes.code.InstructionType)1