use of net.runelite.asm.attributes.code.Instruction 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.Instruction in project runelite by runelite.
the class FieldInliner method makeConstantValues.
private void makeConstantValues() {
for (ClassFile cf : group.getClasses()) {
for (Field f : cf.getFields()) {
if (!f.isStatic() || !f.getType().equals(Type.STRING))
continue;
Object constantValue = f.getValue();
if (constantValue != null)
continue;
List<FieldInstruction> sfis = fieldInstructions.get(f).stream().filter(f2 -> f2 instanceof SetFieldInstruction).collect(Collectors.toList());
if (sfis.size() != 1)
continue;
SetFieldInstruction sfi = (SetFieldInstruction) sfis.get(0);
Instruction ins = (Instruction) sfi;
Method mOfSet = ins.getInstructions().getCode().getMethod();
if (!mOfSet.getName().equals("<clinit>"))
continue;
// get prev instruction and change to a constant value
Instructions instructions = mOfSet.getCode().getInstructions();
int idx = instructions.getInstructions().indexOf(ins);
assert idx != -1;
Instruction prev = instructions.getInstructions().get(idx - 1);
if (!(prev instanceof PushConstantInstruction))
continue;
PushConstantInstruction pci = (PushConstantInstruction) prev;
constantValue = pci.getConstant();
f.setValue(constantValue);
fields.add(f);
boolean b = instructions.getInstructions().remove(prev);
assert b;
b = instructions.getInstructions().remove(ins);
assert b;
}
}
}
use of net.runelite.asm.attributes.code.Instruction 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;
}
use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.
the class Lvt method process.
private void process(Method method) {
Code code = method.getCode();
if (code == null) {
return;
}
Mappings mappings = new Mappings(code.getMaxLocals());
for (Instruction ins : code.getInstructions().getInstructions()) {
if (!(ins instanceof LVTInstruction)) {
continue;
}
LVTInstruction lv = (LVTInstruction) ins;
Integer newIdx = mappings.remap(lv.getVariableIndex(), lv.type());
if (newIdx == null) {
continue;
}
assert newIdx != lv.getVariableIndex();
Instruction newIns = lv.setVariableIndex(newIdx);
assert ins == newIns;
++count;
}
}
use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.
the class CodeVisitor method createInstructionFromOpcode.
private Instruction createInstructionFromOpcode(int opcode) {
InstructionType type = InstructionType.findInstructionFromCode(opcode);
assert type != null;
try {
Constructor<? extends Instruction> con = type.getInstructionClass().getConstructor(Instructions.class, InstructionType.class);
Instruction ins = con.newInstance(code.getInstructions(), type);
code.getInstructions().addInstruction(ins);
return ins;
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new RuntimeException(ex);
}
}
Aggregations