Search in sources :

Example 1 with JumpingInstruction

use of net.runelite.asm.attributes.code.instruction.types.JumpingInstruction in project runelite by runelite.

the class DrawAfterWidgets method injectDrawAfterWidgets.

private void injectDrawAfterWidgets() throws InjectionException {
    /*
			This call has to be injected using raw injection because the
			drawWidgets method gets inlined in some revisions. If it wouldn't be,
			mixins would be used to add the call to the end of drawWidgets.

			--> This hook depends on the positions of "if (535573958 * kl != -1)" and "jz.db();".


			Revision 153 - client.ll():
			______________________________________________________

			if (535573958 * kl != -1) {
				me = 0;
				var1 = kl * 1593233303;
				var2 = 523525871 * q;
				var3 = -1668171507 * h.n;
				if (!bo.p(var1, (byte)111)) {
					for(var4 = 0; var4 < 100; ++var4) {
						mb[var4] = true;
					}
				} else {
					z.lj = null;
					bl.hz(fa.g[var1], -1, 0, 0, var2, var3, 0, 0, -1, 1505114436);
					if (z.lj != null) {
						bl.hz(z.lj, -1412584499, 0, 0, var2, var3, 1475313862 * bq.la, aq.lc * 1205565233, -1, 2123188146);
						z.lj = null;
					}
				}
			}

			// <-- INJECT CALL HERE

			jz.db(); <-- noClip method
			______________________________________________________
		 */
    boolean injected = false;
    Method noClip = findStaticMethod("noClip");
    if (noClip == null) {
        throw new InjectionException("Mapped method \"noClip\" could not be found.");
    }
    net.runelite.asm.pool.Method poolNoClip = noClip.getPoolMethod();
    for (ClassFile c : inject.getVanilla().getClasses()) {
        for (Method m : c.getMethods()) {
            if (m.getCode() == null) {
                continue;
            }
            Instructions instructions = m.getCode().getInstructions();
            Set<Label> labels = new HashSet<>();
            // Let's find "invokestatic <some class>.noClip()" and its label
            ListIterator<Instruction> labelIterator = instructions.getInstructions().listIterator();
            while (labelIterator.hasNext()) {
                Instruction i = labelIterator.next();
                if (!(i instanceof InvokeStatic)) {
                    continue;
                }
                InvokeStatic is = (InvokeStatic) i;
                if (!is.getMethod().equals(poolNoClip)) {
                    continue;
                }
                labelIterator.previous();
                Instruction i2 = labelIterator.previous();
                labelIterator.next();
                labelIterator.next();
                // Find the label that marks the code path for the instruction
                if (!(i2 instanceof Label)) {
                    continue;
                }
                // There can be several noClip invocations in a method, so let's catch them all
                labels.add((Label) i2);
            }
            if (labels.isEmpty()) {
                // If we get here, we're either in the wrong method
                // or Jagex has removed the "if (535573958 * kl != -1)"
                logger.debug("Could not find the label for jumping to the " + noClip + " call in " + m);
                continue;
            }
            Set<Label> labelsToInjectAfter = new HashSet<>();
            ListIterator<Instruction> jumpIterator = instructions.getInstructions().listIterator();
            while (jumpIterator.hasNext()) {
                Instruction i = jumpIterator.next();
                if (!(i instanceof JumpingInstruction)) {
                    continue;
                }
                JumpingInstruction ji = (JumpingInstruction) i;
                Label label = null;
                for (Label l : labels) {
                    if (ji.getJumps().contains(l)) {
                        label = l;
                        break;
                    }
                }
                if (label == null) {
                    continue;
                }
                jumpIterator.previous();
                Set<Instruction> insns = new HashSet<>();
                insns.add(jumpIterator.previous());
                insns.add(jumpIterator.previous());
                insns.add(jumpIterator.previous());
                insns.add(jumpIterator.previous());
                // Get the iterator back to i's position
                jumpIterator.next();
                jumpIterator.next();
                jumpIterator.next();
                jumpIterator.next();
                jumpIterator.next();
                /*
						Check that these instruction types are passed into the if-statement:

						ICONST_M1
						GETSTATIC client.kr : I
						LDC 634425425
						IMUL

						We cannot depend on the order of these because of the obfuscation,
						so let's make it easier by just checking that they are there.
					 */
                if (insns.stream().filter(i2 -> i2 instanceof PushConstantInstruction).count() != 2 || insns.stream().filter(i2 -> i2 instanceof IMul).count() != 1 || insns.stream().filter(i2 -> i2 instanceof GetStatic).count() != 1) {
                    continue;
                }
                // At this point, we have found the real injection point
                labelsToInjectAfter.add(label);
            }
            for (Label l : labelsToInjectAfter) {
                InvokeStatic invoke = new InvokeStatic(instructions, new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(HOOKS), "drawAfterWidgets", new Signature("()V")));
                instructions.addInstruction(instructions.getInstructions().indexOf(l) + 1, invoke);
                logger.info("injectDrawAfterWidgets injected a call after " + l);
                injected = true;
            }
        }
    }
    if (!injected) {
        throw new InjectionException("injectDrawAfterWidgets failed to inject!");
    }
}
Also used : DeobAnnotations(net.runelite.deob.DeobAnnotations) Logger(org.slf4j.Logger) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) ListIterator(java.util.ListIterator) HOOKS(net.runelite.injector.InjectHookMethod.HOOKS) IMul(net.runelite.asm.attributes.code.instructions.IMul) LoggerFactory(org.slf4j.LoggerFactory) Set(java.util.Set) Inject(net.runelite.injector.Inject) InvokeStatic(net.runelite.asm.attributes.code.instructions.InvokeStatic) HashSet(java.util.HashSet) ClassFile(net.runelite.asm.ClassFile) Label(net.runelite.asm.attributes.code.Label) Method(net.runelite.asm.Method) Instructions(net.runelite.asm.attributes.code.Instructions) JumpingInstruction(net.runelite.asm.attributes.code.instruction.types.JumpingInstruction) InjectionException(net.runelite.injector.InjectionException) Signature(net.runelite.asm.signature.Signature) Instruction(net.runelite.asm.attributes.code.Instruction) GetStatic(net.runelite.asm.attributes.code.instructions.GetStatic) ClassFile(net.runelite.asm.ClassFile) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) Label(net.runelite.asm.attributes.code.Label) Instructions(net.runelite.asm.attributes.code.Instructions) Method(net.runelite.asm.Method) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) JumpingInstruction(net.runelite.asm.attributes.code.instruction.types.JumpingInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) InjectionException(net.runelite.injector.InjectionException) JumpingInstruction(net.runelite.asm.attributes.code.instruction.types.JumpingInstruction) GetStatic(net.runelite.asm.attributes.code.instructions.GetStatic) Signature(net.runelite.asm.signature.Signature) IMul(net.runelite.asm.attributes.code.instructions.IMul) HashSet(java.util.HashSet) InvokeStatic(net.runelite.asm.attributes.code.instructions.InvokeStatic)

Example 2 with JumpingInstruction

use of net.runelite.asm.attributes.code.instruction.types.JumpingInstruction in project runelite by runelite.

the class CodeVisitor method visitJumpInsn.

@Override
public void visitJumpInsn(int opcode, Label label) {
    JumpingInstruction i = (JumpingInstruction) createInstructionFromOpcode(opcode);
    i.setLabel(label);
}
Also used : JumpingInstruction(net.runelite.asm.attributes.code.instruction.types.JumpingInstruction)

Example 3 with JumpingInstruction

use of net.runelite.asm.attributes.code.instruction.types.JumpingInstruction 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 4 with JumpingInstruction

use of net.runelite.asm.attributes.code.instruction.types.JumpingInstruction in project runelite by runelite.

the class ConstantParameter method removeDeadOperations.

// remove logically dead comparisons
private int removeDeadOperations(MethodContext mctx) {
    int count = 0;
    for (ConstantMethodParameter cmp : parameters.values()) {
        if (cmp.invalid) {
            continue;
        }
        if (!cmp.methods.contains(mctx.getMethod())) {
            continue;
        }
        // only annotate garbage value of last param
        if (cmp.paramIndex + 1 == mctx.getMethod().getDescriptor().size()) {
            annotateObfuscatedSignature(cmp);
        }
        for (// comparisons
        Instruction ins : // comparisons
        cmp.operations) {
            if (ins.getInstructions() == null || ins.getInstructions().getCode().getMethod() != mctx.getMethod()) {
                continue;
            }
            InstructionContext ctx = mctx.getInstructonContexts(ins).toArray(new InstructionContext[0])[0];
            // branch that is always taken
            boolean branch = cmp.result;
            if (ins.getInstructions() == null) {
                // ins already removed?
                continue;
            }
            Instructions instructions = ins.getInstructions();
            // remove the if
            if (ctx.getInstruction() instanceof If) {
                ctx.removeStack(1);
            }
            ctx.removeStack(0);
            int idx = instructions.getInstructions().indexOf(ins);
            if (idx == -1) {
                // already removed?
                continue;
            }
            ++count;
            Instruction to;
            if (branch) {
                JumpingInstruction jumpIns = (JumpingInstruction) ins;
                assert jumpIns.getJumps().size() == 1;
                to = jumpIns.getJumps().get(0);
            } else {
                // just go to next instruction
                to = instructions.getInstructions().get(idx + 1);
            }
            assert to.getInstructions() == instructions;
            assert ins != to;
            assert instructions.getInstructions().contains(to);
            instructions.remove(ins);
            assert instructions.getInstructions().contains(to);
            if (branch) {
                Goto gotoins = new Goto(instructions, instructions.createLabelFor(to));
                // insert goto
                instructions.getInstructions().add(idx, gotoins);
            }
        }
    }
    return count;
}
Also used : InstructionContext(net.runelite.asm.execution.InstructionContext) JumpingInstruction(net.runelite.asm.attributes.code.instruction.types.JumpingInstruction) Goto(net.runelite.asm.attributes.code.instructions.Goto) Instructions(net.runelite.asm.attributes.code.Instructions) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) 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) ComparisonInstruction(net.runelite.asm.attributes.code.instruction.types.ComparisonInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) If(net.runelite.asm.attributes.code.instructions.If)

Example 5 with JumpingInstruction

use of net.runelite.asm.attributes.code.instruction.types.JumpingInstruction in project runelite by runelite.

the class HandlerFinder method insertReturn.

private void insertReturn(Instructions ins, Instruction start, Instruction end) {
    assert end instanceof Label;
    int idx = ins.getInstructions().indexOf(end);
    assert idx != -1;
    Instruction before = ins.getInstructions().get(idx - 1);
    if (// XXX check isTerminal?
    before.getType() == InstructionType.RETURN) {
        return;
    }
    // insert return before end
    logger.info("Inserting return before {}", end);
    Instruction ret = new VReturn(ins);
    ins.addInstruction(idx, ret);
    Label label = ins.createLabelFor(ret);
    // Change jumps which go to the next handler to instead go to return
    for (Instruction i : ins.getInstructions()) {
        if (i instanceof JumpingInstruction) {
            JumpingInstruction j = (JumpingInstruction) i;
            if (i == start) {
                continue;
            }
            if (j.getJumps().size() == 1 && j.getJumps().get(0) == end) {
                j.setJumps(Collections.singletonList(label));
            }
        }
    }
}
Also used : JumpingInstruction(net.runelite.asm.attributes.code.instruction.types.JumpingInstruction) Label(net.runelite.asm.attributes.code.Label) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) JumpingInstruction(net.runelite.asm.attributes.code.instruction.types.JumpingInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) VReturn(net.runelite.asm.attributes.code.instructions.VReturn)

Aggregations

JumpingInstruction (net.runelite.asm.attributes.code.instruction.types.JumpingInstruction)5 Instruction (net.runelite.asm.attributes.code.Instruction)4 Instructions (net.runelite.asm.attributes.code.Instructions)3 PushConstantInstruction (net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction)3 Label (net.runelite.asm.attributes.code.Label)2 ComparisonInstruction (net.runelite.asm.attributes.code.instruction.types.ComparisonInstruction)2 Goto (net.runelite.asm.attributes.code.instructions.Goto)2 If (net.runelite.asm.attributes.code.instructions.If)2 HashSet (java.util.HashSet)1 ListIterator (java.util.ListIterator)1 Set (java.util.Set)1 ClassFile (net.runelite.asm.ClassFile)1 Method (net.runelite.asm.Method)1 InvokeInstruction (net.runelite.asm.attributes.code.instruction.types.InvokeInstruction)1 LVTInstruction (net.runelite.asm.attributes.code.instruction.types.LVTInstruction)1 AThrow (net.runelite.asm.attributes.code.instructions.AThrow)1 GetStatic (net.runelite.asm.attributes.code.instructions.GetStatic)1 IMul (net.runelite.asm.attributes.code.instructions.IMul)1 InvokeStatic (net.runelite.asm.attributes.code.instructions.InvokeStatic)1 VReturn (net.runelite.asm.attributes.code.instructions.VReturn)1