use of net.runelite.asm.attributes.code.instructions.InvokeVirtual 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);
}
use of net.runelite.asm.attributes.code.instructions.InvokeVirtual in project runelite by runelite.
the class InjectHook method injectCallback.
private void injectCallback(Instructions ins, int idx, HookInfo hookInfo, StackContext index, StackContext objectPusher) throws InjectionException {
if (hookInfo.staticMethod == false) {
if (objectPusher == null) {
throw new InjectionException("Null object pusher");
}
idx = recursivelyPush(ins, idx, objectPusher);
if (index != null) {
idx = recursivelyPush(ins, idx, index);
} else {
ins.getInstructions().add(idx++, new LDC(ins, -1));
}
InvokeVirtual invoke = new InvokeVirtual(ins, new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(hookInfo.clazz), hookInfo.method, new Signature(HOOK_METHOD_SIGNATURE)));
ins.getInstructions().add(idx++, invoke);
} else {
if (index != null) {
idx = recursivelyPush(ins, idx, index);
} else {
ins.getInstructions().add(idx++, new LDC(ins, -1));
}
InvokeStatic invoke = new InvokeStatic(ins, new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(hookInfo.clazz), hookInfo.method, new Signature(HOOK_METHOD_SIGNATURE)));
ins.getInstructions().add(idx++, invoke);
}
}
use of net.runelite.asm.attributes.code.instructions.InvokeVirtual in project runelite by runelite.
the class InjectInvoker method injectInvoker.
private void injectInvoker(ClassFile clazz, java.lang.reflect.Method method, Method deobfuscatedMethod, Method invokeMethod, String garbage) {
if (clazz.findMethod(method.getName(), deobfuscatedMethod.getDescriptor()) != null) {
logger.warn("Not injecting method {} because it already exists!", method);
// this can happen from exporting a field and method with the same name
return;
}
assert invokeMethod.isStatic() == deobfuscatedMethod.isStatic();
assert invokeMethod.isStatic() || invokeMethod.getClassFile() == clazz;
Type lastGarbageArgumentType = null;
if (deobfuscatedMethod.getDescriptor().getArguments().size() != invokeMethod.getDescriptor().getArguments().size()) {
// allow for obfuscated method to have a single bogus signature at the end
assert deobfuscatedMethod.getDescriptor().size() + 1 == invokeMethod.getDescriptor().size();
List<Type> arguments = invokeMethod.getDescriptor().getArguments();
lastGarbageArgumentType = arguments.get(arguments.size() - 1);
}
// Injected method signature is always the same as the API
Signature apiSignature = inject.javaMethodToSignature(method);
Method invokerMethodSignature = new Method(clazz, method.getName(), apiSignature);
invokerMethodSignature.setAccessFlags(ACC_PUBLIC);
// create code attribute
Code code = new Code(invokerMethodSignature);
invokerMethodSignature.setCode(code);
Instructions instructions = code.getInstructions();
List<Instruction> ins = instructions.getInstructions();
// this + arguments
code.setMaxStack(1 + invokeMethod.getDescriptor().size());
// load function arguments onto the stack.
int index = 0;
if (!invokeMethod.isStatic()) {
// this
ins.add(new ALoad(instructions, index++));
} else {
// this method is always non static
++index;
}
for (int i = 0; i < deobfuscatedMethod.getDescriptor().size(); ++i) {
Type type = deobfuscatedMethod.getDescriptor().getTypeOfArg(i);
Instruction loadInstruction = inject.createLoadForTypeIndex(instructions, type, index);
ins.add(loadInstruction);
Signature invokeDesc = invokeMethod.getDescriptor();
Type obType = invokeDesc.getTypeOfArg(i);
if (!type.equals(obType)) {
CheckCast checkCast = new CheckCast(instructions);
checkCast.setType(obType);
ins.add(checkCast);
}
if (loadInstruction instanceof DLoad || loadInstruction instanceof LLoad) {
index += 2;
} else {
index += 1;
}
}
if (lastGarbageArgumentType != null) {
// if garbage is null here it might just be an unused parameter, not part of the obfuscation
if (garbage == null) {
garbage = "0";
}
switch(lastGarbageArgumentType.toString()) {
case "Z":
case "B":
case "C":
ins.add(new BiPush(instructions, Byte.parseByte(garbage)));
break;
case "S":
ins.add(new SiPush(instructions, Short.parseShort(garbage)));
break;
case "I":
ins.add(new LDC(instructions, Integer.parseInt(garbage)));
break;
case "D":
ins.add(new LDC(instructions, Double.parseDouble(garbage)));
break;
case "F":
ins.add(new LDC(instructions, Float.parseFloat(garbage)));
break;
case "J":
ins.add(new LDC(instructions, Long.parseLong(garbage)));
break;
default:
throw new RuntimeException("Unknown type");
}
}
if (invokeMethod.isStatic()) {
ins.add(new InvokeStatic(instructions, invokeMethod.getPoolMethod()));
} else {
ins.add(new InvokeVirtual(instructions, invokeMethod.getPoolMethod()));
}
Type returnValue = invokeMethod.getDescriptor().getReturnValue();
InstructionType returnType;
if (returnValue.isPrimitive() && returnValue.getDimensions() == 0) {
switch(returnValue.toString()) {
case "Z":
case "I":
returnType = InstructionType.IRETURN;
break;
case "J":
returnType = InstructionType.LRETURN;
break;
case "F":
returnType = InstructionType.FRETURN;
break;
case "D":
returnType = InstructionType.DRETURN;
break;
case "V":
returnType = InstructionType.RETURN;
break;
default:
assert false;
return;
}
} else {
returnType = InstructionType.ARETURN;
}
ins.add(new Return(instructions, returnType));
clazz.addMethod(invokerMethodSignature);
}
use of net.runelite.asm.attributes.code.instructions.InvokeVirtual in project runelite by runelite.
the class MaxMemoryTransformer method transform.
private void transform(Method m) {
Code code = m.getCode();
if (code == null) {
return;
}
Instructions ins = code.getInstructions();
for (Instruction i : ins.getInstructions()) {
if (i instanceof InvokeVirtual) {
/*
invokestatic java/lang/Runtime/getRuntime()Ljava/lang/Runtime;
invokevirtual java/lang/Runtime/maxMemory()J
ldc2_w 1048576
ldiv
l2i
*/
if (((InvokeVirtual) i).getMethod().getName().equals("maxMemory")) {
insert(ins, ins.getInstructions().indexOf(i));
done = true;
break;
}
}
}
}
use of net.runelite.asm.attributes.code.instructions.InvokeVirtual in project runelite by runelite.
the class ReflectionTransformer method transformMethodName.
// invokevirtual java/lang/reflect/Method/getName()Ljava/lang/String;
// to
// invokestatic net/runelite/rs/Reflection/getMethodName(Ljava/lang/reflect/Method;)Ljava/lang/String;
private void transformMethodName(Instructions instructions, Instruction i) {
if (!(i instanceof InvokeVirtual)) {
return;
}
InvokeVirtual iv = (InvokeVirtual) i;
if (iv.getMethod().getClazz().getName().equals("java/lang/reflect/Method") && iv.getMethod().getName().equals("getName")) {
InvokeStatic is = new InvokeStatic(instructions, new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class("net/runelite/rs/Reflection"), "getMethodName", new Signature("(Ljava/lang/reflect/Method;)Ljava/lang/String;")));
instructions.replace(iv, is);
logger.info("Transformed Method.getName call");
}
}
Aggregations