Search in sources :

Example 16 with Instructions

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

the class MultiplyOneDeobfuscatorTest method test2.

// iconst_1
// iconst_m1
// iload                 5
// if_icmpeq             LABEL0x56d1
// iload                 5
// iconst_1
// if_icmpne             LABEL0x56e8
// goto                  LABEL0x56d1
// LABEL0x56d1:
// getstatic             class139/field2130 I
// ldc_w                 -1440517609
// imul
// goto                  LABEL0x5708
// LABEL0x56e8:
// getstatic             class139/field2130 I
// ldc_w                 -1440517609
// imul
// getstatic             client/field377 I
// iadd
// iconst_2
// idiv
// LABEL0x5708:
// imul
// putstatic             client/field377 I
// 
// client.field377 = 1 * (-1 != var5 && var5 != 1?(class139.field2130 + client.field377) / 2:class139.field2130);
@Test
public void test2() {
    ClassGroup group = ClassGroupFactory.generateGroup();
    Code code = group.findClass("test").findMethod("func").getCode();
    Instructions ins = code.getInstructions();
    code.setMaxStack(2);
    // vars[0] = 3
    Instruction[] prepareVariables = { new LDC(ins, 3), new IStore(ins, 0), new LDC(ins, 2), new IStore(ins, 1) };
    for (Instruction i : prepareVariables) ins.addInstruction(i);
    Label label = new Label(ins), label2 = new Label(ins), label3 = new Label(ins);
    LDC one = new LDC(ins, 1);
    IMul mul = new IMul(ins);
    Instruction[] body = { one, new LDC(ins, -1), new ILoad(ins, 0), new IfICmpEq(ins, label), new Goto(ins, label2), label, new ILoad(ins, 1), new LDC(ins, -1440517609), new IDiv(ins), new Goto(ins, label3), label2, new ILoad(ins, 1), new LDC(ins, -1440517609), new IDiv(ins), label3, mul, new VReturn(ins) };
    for (Instruction i : body) ins.addInstruction(i);
    // check execution runs ok
    Execution e = new Execution(group);
    e.populateInitialMethods();
    e.run();
    Deobfuscator d = new MultiplyOneDeobfuscator(false);
    d.run(group);
    Assert.assertTrue(one.getInstructions() == null);
    Assert.assertTrue(mul.getInstructions() == null);
}
Also used : IfICmpEq(net.runelite.asm.attributes.code.instructions.IfICmpEq) IStore(net.runelite.asm.attributes.code.instructions.IStore) Goto(net.runelite.asm.attributes.code.instructions.Goto) 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) IDiv(net.runelite.asm.attributes.code.instructions.IDiv) 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) Execution(net.runelite.asm.execution.Execution) ClassGroup(net.runelite.asm.ClassGroup) IMul(net.runelite.asm.attributes.code.instructions.IMul) Test(org.junit.Test)

Example 17 with Instructions

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

the class If0 method resolve.

@Override
public void resolve() {
    Instructions ins = this.getInstructions();
    to = ins.findLabel(asmlabel);
    assert to != null;
}
Also used : Instructions(net.runelite.asm.attributes.code.Instructions)

Example 18 with Instructions

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

the class Goto method resolve.

@Override
public void resolve() {
    Instructions ins = this.getInstructions();
    to = ins.findLabel(asmlabel);
    assert to != null;
}
Also used : Instructions(net.runelite.asm.attributes.code.Instructions)

Example 19 with Instructions

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

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

the class InjectHookMethod method injectHookMethod.

private void injectHookMethod(Annotation hook, Method deobMethod, Method vanillaMethod) throws InjectionException {
    String hookName = hook.getElement().getString();
    Instructions instructions = vanillaMethod.getCode().getInstructions();
    Signature.Builder builder = new Signature.Builder().setReturnType(// Hooks always return void
    Type.VOID);
    for (Type type : deobMethod.getDescriptor().getArguments()) {
        builder.addArgument(inject.deobfuscatedTypeToApiType(type));
    }
    assert deobMethod.isStatic() == vanillaMethod.isStatic();
    if (!deobMethod.isStatic()) {
        // Add variable to signature
        builder.addArgument(0, inject.deobfuscatedTypeToApiType(new Type(deobMethod.getClassFile().getName())));
    }
    Signature signature = builder.build();
    List<Integer> insertIndexes = findHookLocations(hook, vanillaMethod);
    insertIndexes.sort((a, b) -> Integer.compare(b, a));
    for (int insertPos : insertIndexes) {
        if (!deobMethod.isStatic()) {
            instructions.addInstruction(insertPos++, new ALoad(instructions, 0));
        }
        // current variable index
        int index = deobMethod.isStatic() ? 0 : 1;
        for (int i = index; i < signature.size(); ++i) {
            Type type = signature.getTypeOfArg(i);
            Instruction load = inject.createLoadForTypeIndex(instructions, type, index);
            instructions.addInstruction(insertPos++, load);
            index += type.getSize();
        }
        // Invoke callback
        InvokeStatic invoke = new InvokeStatic(instructions, new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(HOOKS), hookName, signature));
        instructions.addInstruction(insertPos++, invoke);
    }
    logger.info("Injected method hook {} in {} with {} args: {}", hookName, vanillaMethod, signature.size(), signature.getArguments());
}
Also used : Instructions(net.runelite.asm.attributes.code.Instructions) ReturnInstruction(net.runelite.asm.attributes.code.instruction.types.ReturnInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) 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) InvokeStatic(net.runelite.asm.attributes.code.instructions.InvokeStatic)

Aggregations

Instructions (net.runelite.asm.attributes.code.Instructions)86 Instruction (net.runelite.asm.attributes.code.Instruction)72 Code (net.runelite.asm.attributes.Code)47 LDC (net.runelite.asm.attributes.code.instructions.LDC)40 ClassGroup (net.runelite.asm.ClassGroup)32 VReturn (net.runelite.asm.attributes.code.instructions.VReturn)30 Test (org.junit.Test)30 Method (net.runelite.asm.Method)26 IMul (net.runelite.asm.attributes.code.instructions.IMul)26 ILoad (net.runelite.asm.attributes.code.instructions.ILoad)24 IStore (net.runelite.asm.attributes.code.instructions.IStore)24 Execution (net.runelite.asm.execution.Execution)22 Deobfuscator (net.runelite.deob.Deobfuscator)22 ClassFile (net.runelite.asm.ClassFile)17 Field (net.runelite.asm.Field)17 Type (net.runelite.asm.Type)17 Label (net.runelite.asm.attributes.code.Label)17 PushConstantInstruction (net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction)16 Signature (net.runelite.asm.signature.Signature)16 Pop (net.runelite.asm.attributes.code.instructions.Pop)14