Search in sources :

Example 1 with Label

use of net.runelite.asm.attributes.code.Label 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 2 with Label

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

the class BufferMethodInjector method inject.

private void inject(ClassFile bufferClass, Method method) {
    assert method.getExceptions().getExceptions().isEmpty();
    Method newMethod = new Method(bufferClass, method.getName(), method.getDescriptor());
    Code code = new Code(newMethod);
    newMethod.setCode(code);
    method.getCode().getInstructions().getInstructions().stream().forEach(i -> {
        if (!(i instanceof Label)) {
            i = i.clone();
        }
        if (i instanceof FieldInstruction) {
            FieldInstruction fi = (FieldInstruction) i;
            if (fi.getField().getName().equals("offset")) {
                fi.setField(bp.getOffset().getPoolField());
            } else if (fi.getField().getName().equals("payload")) {
                fi.setField(bp.getBuffer().getPoolField());
            } else if (fi.getField().getName().equals("runeliteLengthOffset")) {
                fi.setField(bufferClass.findField("runeliteLengthOffset").getPoolField());
            }
        }
        i.setInstructions(code.getInstructions());
        code.getInstructions().addInstruction(i);
    });
    code.getExceptions().getExceptions().addAll(method.getCode().getExceptions().getExceptions());
    bufferClass.addMethod(newMethod);
}
Also used : Label(net.runelite.asm.attributes.code.Label) Method(net.runelite.asm.Method) FieldInstruction(net.runelite.asm.attributes.code.instruction.types.FieldInstruction) Code(net.runelite.asm.attributes.Code)

Example 3 with Label

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

the class MenuActionDeobfuscator method insert.

private void insert(Method method, List<Comparison> comparisons) {
    Instructions instructions = method.getCode().getInstructions();
    List<Instruction> ins = instructions.getInstructions();
    // replace all if(var == constant) with a jump to the false branch
    // then, insert before the first jump the ifs to jump to the old
    // true branch
    // 
    // this is probably actually lookupswitch but it isn't mappable
    // currently...
    int min = -1;
    for (Comparison comp : comparisons) {
        if (min == -1) {
            min = ins.indexOf(comp.lvt);
        } else {
            min = Math.min(min, ins.indexOf(comp.lvt));
        }
        if (comp.cmp.getType() == InstructionType.IF_ICMPEQ) {
            If cmp = (If) comp.cmp;
            // remove
            instructions.remove(comp.ldc);
            instructions.remove((Instruction) comp.lvt);
            instructions.remove(comp.cmp);
            comp.next = cmp.getJumps().get(0);
        } else if (comp.cmp.getType() == InstructionType.IF_ICMPNE) {
            // replace with goto dest
            If cmp = (If) comp.cmp;
            int idx = ins.indexOf(cmp);
            assert idx != -1;
            comp.next = instructions.createLabelFor(ins.get(idx + 1));
            instructions.remove(comp.ldc);
            instructions.remove((Instruction) comp.lvt);
            instructions.replace(comp.cmp, new Goto(instructions, cmp.getJumps().get(0)));
        } else {
            throw new IllegalStateException();
        }
    }
    assert min != -1;
    // sort comparisons - but if they jump to the same address, they are equal..
    List<Comparison> sortedComparisons = new ArrayList<>(comparisons);
    Collections.sort(sortedComparisons, (c1, c2) -> compare(comparisons, c1, c2));
    // reinsert jumps
    for (int i = 0; i < sortedComparisons.size(); ++i) {
        Comparison comp = sortedComparisons.get(i);
        Instruction lvt = (Instruction) comp.lvt;
        lvt.setInstructions(instructions);
        comp.ldc.setInstructions(instructions);
        instructions.addInstruction(min++, lvt);
        instructions.addInstruction(min++, comp.ldc);
        // use if_icmpeq if what follows also jumps to the same location
        boolean multiple = i + 1 < sortedComparisons.size() && sortedComparisons.get(i + 1).next == comp.next;
        if (multiple) {
            instructions.addInstruction(min++, new IfICmpEq(instructions, comp.next));
        } else {
            // fernflower decompiles a series of if_icmpeq as chains of not equal expressions
            Label label = instructions.createLabelFor(ins.get(min));
            instructions.addInstruction(min++, new IfICmpNe(instructions, label));
            instructions.addInstruction(min++, new Goto(instructions, comp.next));
            // go past label
            ++min;
        }
    }
}
Also used : IfICmpEq(net.runelite.asm.attributes.code.instructions.IfICmpEq) Goto(net.runelite.asm.attributes.code.instructions.Goto) ArrayList(java.util.ArrayList) Label(net.runelite.asm.attributes.code.Label) Instructions(net.runelite.asm.attributes.code.Instructions) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) IfICmpNe(net.runelite.asm.attributes.code.instructions.IfICmpNe) If(net.runelite.asm.attributes.code.instructions.If)

Example 4 with Label

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

the class UnreachedCodeTest method testRun.

@Test
public void testRun() throws IOException {
    UnreachedCode uc = new UnreachedCode();
    uc.run(group);
    ClassFile cf = group.getClasses().get(0);
    Method method = cf.findMethod("entry");
    Assert.assertFalse(method.getCode().getExceptions().getExceptions().isEmpty());
    method = cf.findMethod("method1Unused");
    Assert.assertNotNull(method);
    Assert.assertFalse(method.getCode().getInstructions().getInstructions().stream().filter(i -> !(i instanceof Label)).findAny().isPresent());
    Assert.assertTrue(method.getCode().getExceptions().getExceptions().isEmpty());
    // Method is now invalid, remove so jar can be saved
    cf.removeMethod(method);
    // constructor now has no instructions
    method = cf.findMethod("<init>");
    Assert.assertNotNull(method);
    Assert.assertFalse(method.getCode().getInstructions().getInstructions().stream().filter(i -> !(i instanceof Label)).findAny().isPresent());
    // remove it too
    cf.removeMethod(method);
}
Also used : IOException(java.io.IOException) TemporyFolderLocation(net.runelite.deob.TemporyFolderLocation) Test(org.junit.Test) ClassGroup(net.runelite.asm.ClassGroup) JarUtil(net.runelite.deob.util.JarUtil) ClassFile(net.runelite.asm.ClassFile) Label(net.runelite.asm.attributes.code.Label) Rule(org.junit.Rule) Method(net.runelite.asm.Method) ClassUtil(net.runelite.asm.ClassUtil) After(org.junit.After) Assert(org.junit.Assert) TemporaryFolder(org.junit.rules.TemporaryFolder) Before(org.junit.Before) ClassFile(net.runelite.asm.ClassFile) Label(net.runelite.asm.attributes.code.Label) Method(net.runelite.asm.Method) Test(org.junit.Test)

Example 5 with Label

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

the class MultiplicationDeobfuscatorTest method test4.

@Test
public void test4() {
    ClassGroup group = ClassGroupFactory.generateGroup();
    Code code = group.findClass("test").findMethod("func").getCode();
    Instructions ins = code.getInstructions();
    code.setMaxStack(2);
    Instruction[] prepareVariables = { new LDC(ins, 3), new IStore(ins, 0) };
    for (Instruction i : prepareVariables) {
        ins.addInstruction(i);
    }
    LDC constant1 = new LDC(ins, 1807370871);
    LDC constant2 = new LDC(ins, 981643079);
    Label label1 = new Label(ins);
    Instruction[] body = { new ILoad(ins, 0), new LDC(ins, 2), new IMul(ins), new LDC(ins, 0), new IfEq(ins, label1), new Pop(ins), new LDC(ins, 3), label1, constant1, new IMul(ins), constant2, new IMul(ins), new VReturn(ins) };
    for (Instruction i : body) {
        ins.addInstruction(i);
    }
    Execution e = new Execution(group);
    e.populateInitialMethods();
    e.run();
    assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
    Deobfuscator d = new MultiplicationDeobfuscator();
    d.run(group);
    Assert.assertEquals(1, constant1.getConstantAsInt());
    Assert.assertEquals(1, constant2.getConstantAsInt());
}
Also used : IStore(net.runelite.asm.attributes.code.instructions.IStore) ILoad(net.runelite.asm.attributes.code.instructions.ILoad) Label(net.runelite.asm.attributes.code.Label) Instructions(net.runelite.asm.attributes.code.Instructions) LDC(net.runelite.asm.attributes.code.instructions.LDC) IfEq(net.runelite.asm.attributes.code.instructions.IfEq) Instruction(net.runelite.asm.attributes.code.Instruction) Code(net.runelite.asm.attributes.Code) VReturn(net.runelite.asm.attributes.code.instructions.VReturn) Deobfuscator(net.runelite.deob.Deobfuscator) Pop(net.runelite.asm.attributes.code.instructions.Pop) Execution(net.runelite.asm.execution.Execution) ClassGroup(net.runelite.asm.ClassGroup) IMul(net.runelite.asm.attributes.code.instructions.IMul) Test(org.junit.Test)

Aggregations

Label (net.runelite.asm.attributes.code.Label)25 Instruction (net.runelite.asm.attributes.code.Instruction)19 Instructions (net.runelite.asm.attributes.code.Instructions)17 ClassGroup (net.runelite.asm.ClassGroup)10 Code (net.runelite.asm.attributes.Code)10 LDC (net.runelite.asm.attributes.code.instructions.LDC)10 Goto (net.runelite.asm.attributes.code.instructions.Goto)9 ILoad (net.runelite.asm.attributes.code.instructions.ILoad)9 IStore (net.runelite.asm.attributes.code.instructions.IStore)9 IfEq (net.runelite.asm.attributes.code.instructions.IfEq)9 VReturn (net.runelite.asm.attributes.code.instructions.VReturn)9 Test (org.junit.Test)9 IMul (net.runelite.asm.attributes.code.instructions.IMul)8 Execution (net.runelite.asm.execution.Execution)8 ArrayList (java.util.ArrayList)7 Deobfuscator (net.runelite.deob.Deobfuscator)7 Method (net.runelite.asm.Method)6 PushConstantInstruction (net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction)6 JumpingInstruction (net.runelite.asm.attributes.code.instruction.types.JumpingInstruction)5 LVTInstruction (net.runelite.asm.attributes.code.instruction.types.LVTInstruction)5