Search in sources :

Example 51 with Method

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

the class IsaacCipherFinder method find.

public void find() {
    Method highest = null;
    int count = 0;
    for (ClassFile cf : group.getClasses()) {
        for (Method m : cf.getMethods()) {
            Code code = m.getCode();
            int i = find(m, code);
            if (i > count) {
                count = i;
                highest = m;
            }
        }
    }
    assert highest != null;
    isaacCipher = highest.getClassFile();
    // find nextInt
    for (Method method : isaacCipher.getMethods()) {
        if (method.getDescriptor().size() == 0 && method.getDescriptor().getReturnValue().equals(Type.INT)) {
            getNext = method;
        }
    }
    logger.debug("Found cipher {}, getNext {}", isaacCipher, getNext);
}
Also used : ClassFile(net.runelite.asm.ClassFile) Method(net.runelite.asm.Method) Code(net.runelite.asm.attributes.Code)

Example 52 with Method

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

the class EnumDeobfuscator method makeEnum.

private void makeEnum(ClassFile cf) {
    // make class an enum
    cf.setEnum();
    // enums super class is java/lang/Enum
    assert cf.getParentClass().getName().equals("java/lang/Object");
    cf.setSuperName("java/lang/Enum");
    // all static fields of the type of the class become enum members
    for (Field field : cf.getFields()) {
        if (field.isStatic() && field.getType().equals(new Type("L" + cf.getName() + ";"))) {
            field.setEnum();
        }
    }
    for (Method method : cf.getMethods()) {
        if (!method.getName().equals("<init>")) {
            continue;
        }
        // Add string as first argument, which is the field name,
        // and ordinal as second argument
        Signature signature = new Signature.Builder().setReturnType(method.getDescriptor().getReturnValue()).addArgument(Type.STRING).addArgument(Type.INT).addArguments(method.getDescriptor().getArguments()).build();
        method.setDescriptor(signature);
        // Remove instructions up to invokespecial
        Instructions ins = method.getCode().getInstructions();
        Instruction i;
        do {
            i = ins.getInstructions().get(0);
            ins.remove(i);
        } while (i.getType() != InstructionType.INVOKESPECIAL);
        // load this
        ins.addInstruction(0, new ALoad(ins, 0));
        // load constant name
        ins.addInstruction(1, new ALoad(ins, 1));
        // ordinal
        ins.addInstruction(2, new ILoad(ins, 2));
        // invoke enum constructor
        ins.addInstruction(3, new InvokeSpecial(ins, ENUM_INIT));
        // Shift all indexes after this up +2 because of the new String and int argument
        for (int j = 4; j < ins.getInstructions().size(); ++j) {
            i = ins.getInstructions().get(j);
            if (i instanceof LVTInstruction) {
                LVTInstruction lvt = ((LVTInstruction) i);
                int idx = lvt.getVariableIndex();
                if (idx != 0) {
                    lvt.setVariableIndex(idx + 2);
                }
            }
        }
    }
    // Order of fields being set in clinit, which is the order
    // the enum fields are actually in
    List<Field> order = new ArrayList<>();
    for (Method method : cf.getMethods()) {
        if (!method.getName().equals("<clinit>")) {
            continue;
        }
        Instructions ins = method.getCode().getInstructions();
        int count = 0;
        // sometimes there is new new invokespecial invokespecial putfield
        // for eg enum member field30(1, 2, String.class, new class5());
        boolean seenDup = false;
        for (int j = 0; j < ins.getInstructions().size(); ++j) {
            Instruction i = ins.getInstructions().get(j);
            if (i.getType() == InstructionType.DUP && !seenDup) {
                // XXX this should actually be the field name, but it seems to have no effect on fernflower
                ins.addInstruction(j + 1, new LDC(ins, "runelite"));
                ins.addInstruction(j + 2, new LDC(ins, count++));
                seenDup = true;
            } else if (i.getType() == InstructionType.INVOKESPECIAL) {
                Instruction next = ins.getInstructions().get(j + 1);
                // check if this is the invokespecial on the enum, putstatic comes next
                if (next.getType() == InstructionType.PUTSTATIC) {
                    InvokeSpecial is = (InvokeSpecial) i;
                    PutStatic ps = (PutStatic) next;
                    net.runelite.asm.pool.Method pmethod = new net.runelite.asm.pool.Method(is.getMethod().getClazz(), is.getMethod().getName(), new Signature.Builder().setReturnType(is.getMethod().getType().getReturnValue()).addArgument(Type.STRING).addArgument(Type.INT).addArguments(is.getMethod().getType().getArguments()).build());
                    is.setMethod(pmethod);
                    Field field = ps.getMyField();
                    assert field != null;
                    order.add(field);
                    seenDup = false;
                }
            }
        }
    }
    // Enum fields must be first. Also they are in order in clinit.
    // Sort fields
    Collections.sort(cf.getFields(), (f1, f2) -> {
        int idx1 = order.indexOf(f1);
        int idx2 = order.indexOf(f2);
        if (idx1 == -1) {
            idx1 = Integer.MAX_VALUE;
        }
        if (idx2 == -1) {
            idx2 = Integer.MAX_VALUE;
        }
        return Integer.compare(idx1, idx2);
    });
}
Also used : InvokeSpecial(net.runelite.asm.attributes.code.instructions.InvokeSpecial) ILoad(net.runelite.asm.attributes.code.instructions.ILoad) ArrayList(java.util.ArrayList) 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) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) PutStatic(net.runelite.asm.attributes.code.instructions.PutStatic) Field(net.runelite.asm.Field) InstructionType(net.runelite.asm.attributes.code.InstructionType) Type(net.runelite.asm.Type) Signature(net.runelite.asm.signature.Signature) ALoad(net.runelite.asm.attributes.code.instructions.ALoad)

Example 53 with Method

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

the class Execution method getInitialMethods.

public List<Method> getInitialMethods() {
    List<Method> methods = new ArrayList<>();
    // required when looking up methods
    group.buildClassGraph();
    // lookup methods
    group.lookup();
    for (ClassFile cf : group.getClasses()) {
        boolean extendsApplet = extendsApplet(cf);
        for (Method m : cf.getMethods()) {
            if (!Deob.isObfuscated(m.getName()) && !m.getName().equals("<init>")) {
                if (m.getCode() == null) {
                    methods.add(m);
                    continue;
                }
                // I guess this method name is overriding a jre interface (init, run, ?).
                methods.add(m);
                logger.debug("Adding initial method {}", m);
            }
            if (m.getName().equals("<init>") && extendsApplet) {
                methods.add(m);
            }
        }
    }
    return methods;
}
Also used : ClassFile(net.runelite.asm.ClassFile) ArrayList(java.util.ArrayList) Method(net.runelite.asm.Method)

Example 54 with Method

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

the class Stack method push.

public void push(StackContext i) {
    if (size == stack.length) {
        Method m = i.getPushed().getInstruction().getInstructions().getCode().getMethod();
        System.err.println("stack overflow in " + m.getClassFile().getName() + " method " + m.getName());
        for (int c = 0; c < stack.length; ++c) printStack(stack[c], 0);
        throw new RuntimeException("Stack overflow");
    }
    assert !i.getType().equals(Type.VOID);
    stack[size] = i;
    ++size;
}
Also used : Method(net.runelite.asm.Method)

Example 55 with Method

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

the class VirtualMethods method findMethodUp.

private static void findMethodUp(List<Method> methods, Set<ClassFile> visited, ClassFile cf, String name, Signature type) {
    if (cf == null || visited.contains(cf))
        return;
    // can do diamond inheritance with interfaces
    visited.add(cf);
    Method m = cf.findMethod(name, type);
    if (m != null && !m.isStatic())
        methods.add(m);
    for (ClassFile child : cf.getChildren()) findMethodUp(methods, visited, child, name, type);
}
Also used : ClassFile(net.runelite.asm.ClassFile) Method(net.runelite.asm.Method)

Aggregations

Method (net.runelite.asm.Method)90 ClassFile (net.runelite.asm.ClassFile)64 Field (net.runelite.asm.Field)34 Instruction (net.runelite.asm.attributes.code.Instruction)29 Code (net.runelite.asm.attributes.Code)28 Instructions (net.runelite.asm.attributes.code.Instructions)28 Signature (net.runelite.asm.signature.Signature)28 ClassGroup (net.runelite.asm.ClassGroup)20 ArrayList (java.util.ArrayList)18 Type (net.runelite.asm.Type)18 List (java.util.List)13 Test (org.junit.Test)13 PushConstantInstruction (net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction)12 Logger (org.slf4j.Logger)12 LoggerFactory (org.slf4j.LoggerFactory)12 LDC (net.runelite.asm.attributes.code.instructions.LDC)10 DeobAnnotations (net.runelite.deob.DeobAnnotations)9 Annotation (net.runelite.asm.attributes.annotation.Annotation)8 InstructionType (net.runelite.asm.attributes.code.InstructionType)8 Label (net.runelite.asm.attributes.code.Label)8