Search in sources :

Example 1 with Exceptions

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

the class ControlFlowDeobfuscator method split.

/**
 * Add gotos at the end of blocks without terminal instructions
 *
 * @param code
 */
private void split(Code code) {
    Instructions ins = code.getInstructions();
    Exceptions exceptions = code.getExceptions();
    ControlFlowGraph graph = new ControlFlowGraph.Builder().build(code);
    List<Exception> exc = new ArrayList<>(exceptions.getExceptions());
    // Must clear this before ins.clear() runs
    exceptions.clear();
    ins.clear();
    // insert jumps where blocks flow into others
    for (Block block : graph.getBlocks()) {
        if (block.getFlowsInto() == null) {
            continue;
        }
        Block into = block.getFlowsInto();
        assert into.getFlowsFrom() == block;
        Instruction first = into.getInstructions().get(0);
        Label label;
        if (!(first instanceof Label)) {
            label = new Label(null);
            into.addInstruction(0, label);
        } else {
            label = (Label) first;
        }
        Goto g = new Goto(null, label);
        block.addInstruction(g);
        block.setFlowsInto(null);
        into.setFlowsFrom(null);
        ++insertedJump;
    }
    // Readd instructions from modified blocks
    for (Block block : graph.getBlocks()) {
        for (Instruction i : block.getInstructions()) {
            assert i.getInstructions() == null;
            // I shouldn't have to do this here
            i.setInstructions(ins);
            ins.addInstruction(i);
        }
    }
    // Readd exceptions
    for (Exception ex : exc) {
        exceptions.add(ex);
    }
}
Also used : Goto(net.runelite.asm.attributes.code.instructions.Goto) Exceptions(net.runelite.asm.attributes.code.Exceptions) ArrayList(java.util.ArrayList) Label(net.runelite.asm.attributes.code.Label) Instructions(net.runelite.asm.attributes.code.Instructions) Instruction(net.runelite.asm.attributes.code.Instruction) Exception(net.runelite.asm.attributes.code.Exception)

Example 2 with Exceptions

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

the class Renamer method renameClass.

private void renameClass(ClassGroup group, ClassFile cf, String name) {
    for (ClassFile c : group.getClasses()) {
        // rename on child interfaces and classes
        renameClass(c, cf, name);
        for (Method method : c.getMethods()) {
            // rename on instructions. this includes method calls and field accesses.
            if (method.getCode() != null) {
                Code code = method.getCode();
                // rename on instructions
                for (Instruction i : code.getInstructions().getInstructions()) {
                    i.renameClass(cf.getName(), name);
                }
                // rename on exception handlers
                Exceptions exceptions = code.getExceptions();
                exceptions.renameClass(cf, name);
            }
            // rename on parameters
            Signature.Builder builder = new Signature.Builder();
            Signature signature = method.getDescriptor();
            for (int i = 0; i < signature.size(); ++i) {
                Type type = signature.getTypeOfArg(i);
                if (type.getInternalName().equals(cf.getName())) {
                    builder.addArgument(Type.getType("L" + name + ";", type.getDimensions()));
                } else {
                    builder.addArgument(type);
                }
            }
            // rename return type
            if (signature.getReturnValue().getInternalName().equals(cf.getName())) {
                builder.setReturnType(Type.getType("L" + name + ";", signature.getReturnValue().getDimensions()));
            } else {
                builder.setReturnType(signature.getReturnValue());
            }
            Signature newSignature = builder.build();
            if (!method.getDescriptor().equals(newSignature)) {
                // Signature was updated. Annotate it
                if (method.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE) == null) {
                    // Signature was not previously renamed
                    method.getAnnotations().addAnnotation(DeobAnnotations.OBFUSCATED_SIGNATURE, "signature", method.getDescriptor().toString());
                }
            }
            method.setDescriptor(newSignature);
            // rename on exceptions thrown
            if (method.getExceptions() != null) {
                method.getExceptions().renameClass(cf, name);
            }
        }
        // rename on fields
        for (Field field : c.getFields()) {
            if (field.getType().getInternalName().equals(cf.getName())) {
                if (field.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE) == null) {
                    // Signature was updated. Annotate it
                    field.getAnnotations().addAnnotation(DeobAnnotations.OBFUSCATED_SIGNATURE, "signature", field.getType().toString());
                }
                field.setType(Type.getType("L" + name + ";", field.getType().getDimensions()));
            }
        }
    }
    if (cf.getAnnotations().find(DeobAnnotations.OBFUSCATED_NAME) == null) {
        cf.getAnnotations().addAnnotation(DeobAnnotations.OBFUSCATED_NAME, "value", cf.getName());
    }
    group.renameClass(cf, name);
}
Also used : Field(net.runelite.asm.Field) Type(net.runelite.asm.Type) ClassFile(net.runelite.asm.ClassFile) Signature(net.runelite.asm.signature.Signature) Exceptions(net.runelite.asm.attributes.code.Exceptions) Method(net.runelite.asm.Method) Instruction(net.runelite.asm.attributes.code.Instruction) Code(net.runelite.asm.attributes.Code)

Example 3 with Exceptions

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

the class CodeVisitor method visitTryCatchBlock.

@Override
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
    Exceptions exceptions = code.getExceptions();
    net.runelite.asm.attributes.code.Exception e = new net.runelite.asm.attributes.code.Exception(exceptions);
    Instructions ins = code.getInstructions();
    net.runelite.asm.attributes.code.Label startL = ins.findOrCreateLabel(start);
    net.runelite.asm.attributes.code.Label endL = ins.findOrCreateLabel(end);
    net.runelite.asm.attributes.code.Label handlerL = ins.findOrCreateLabel(handler);
    assert startL != null;
    assert endL != null;
    assert handlerL != null;
    e.setStart(startL);
    e.setEnd(endL);
    e.setHandler(handlerL);
    if (type != null) {
        e.setCatchType(new net.runelite.asm.pool.Class(type));
    }
    exceptions.add(e);
}
Also used : Exceptions(net.runelite.asm.attributes.code.Exceptions) Instructions(net.runelite.asm.attributes.code.Instructions) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 4 with Exceptions

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

the class ControlFlowDeobfuscator method run.

private void run(Code code) {
    Instructions ins = code.getInstructions();
    Exceptions exceptions = code.getExceptions();
    ControlFlowGraph graph = new ControlFlowGraph.Builder().build(code);
    for (Block block : graph.getBlocks()) {
        assert block.getFlowsFrom() == null;
        assert block.getFlowsInto() == null;
    }
    if (// graph.toString() is expensive
    logger.isDebugEnabled()) {
        logger.debug(graph.toString());
    }
    List<Exception> originalExceptions = new ArrayList<>(exceptions.getExceptions());
    // Clear existing exceptions and instructions as we are going to
    // rebuild them
    exceptions.clear();
    ins.clear();
    List<Block> done = new ArrayList<>();
    Queue<Block> queue = new PriorityQueue<>(this::compareBlock);
    // add initial code block
    queue.add(graph.getHead());
    while (!queue.isEmpty()) {
        Block block = queue.remove();
        if (done.contains(block)) {
            continue;
        }
        done.add(block);
        ++placedBlocks;
        logger.debug("Placed block {}", block.getId());
        List<Block> next = block.getNext();
        if (next.isEmpty() == false) {
            // jumps are added in order their instructions are reached by ControlFlowGraph,
            // so the last jump is the goto.
            // 
            // removing this line causes the priority queue (due to implementation detail on how
            // it handles objects with equal priority) to try to optimize for block closeness
            // (how close blocks which are neighbors are to each other in bytecode).
            // I get a jump delta of ~+14k with this on 143, vs ~-47k when priotiziing optimizing
            // out jumps. I can't tell which is better.
            next.get(next.size() - 1).setJumptarget(true);
        }
        // add next reachable blocks
        for (Block bl : next) {
            queue.add(bl);
        }
        for (Instruction i : block.getInstructions()) {
            assert i.getInstructions() == null;
            // I shouldn't have to do this here
            i.setInstructions(ins);
            ins.addInstruction(i);
        }
    }
}
Also used : Exceptions(net.runelite.asm.attributes.code.Exceptions) ArrayList(java.util.ArrayList) Instructions(net.runelite.asm.attributes.code.Instructions) PriorityQueue(java.util.PriorityQueue) Instruction(net.runelite.asm.attributes.code.Instruction) Exception(net.runelite.asm.attributes.code.Exception)

Aggregations

Exceptions (net.runelite.asm.attributes.code.Exceptions)4 Instruction (net.runelite.asm.attributes.code.Instruction)3 Instructions (net.runelite.asm.attributes.code.Instructions)3 ArrayList (java.util.ArrayList)2 Exception (net.runelite.asm.attributes.code.Exception)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 PriorityQueue (java.util.PriorityQueue)1 ClassFile (net.runelite.asm.ClassFile)1 Field (net.runelite.asm.Field)1 Method (net.runelite.asm.Method)1 Type (net.runelite.asm.Type)1 Code (net.runelite.asm.attributes.Code)1 Label (net.runelite.asm.attributes.code.Label)1 Goto (net.runelite.asm.attributes.code.instructions.Goto)1 Signature (net.runelite.asm.signature.Signature)1