use of net.runelite.asm.attributes.code.instructions.GetStatic in project runelite by runelite.
the class RuneliteBufferTransformer method injectPacketFinish.
private void injectPacketFinish(ClassGroup group) {
PacketFlushFinder pff = new PacketFlushFinder(group);
pff.find();
for (InstructionContext queueForWriteCtx : pff.getQueueForWrite()) {
Instruction before = // socket
queueForWriteCtx.getPops().get(3).getPushed().getInstruction();
GetStatic getBuffer;
try {
getBuffer = (GetStatic) // buffer
queueForWriteCtx.getPops().get(2).getPushed().getPops().get(// getstatic
0).getPushed().getInstruction();
} catch (ClassCastException ex) {
continue;
}
Instructions instructions = before.getInstructions();
int idx = instructions.getInstructions().indexOf(before);
assert idx != -1;
instructions.addInstruction(idx++, getBuffer.clone());
net.runelite.asm.pool.Method method = new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(getBuffer.getField().getType().getInternalName()), RUNELITE_FINISH_PACKET, new Signature("()V"));
instructions.addInstruction(idx++, new InvokeVirtual(instructions, method));
}
}
use of net.runelite.asm.attributes.code.instructions.GetStatic in project runelite by runelite.
the class HandlerFinder method findHandlers.
private List<PacketHandler> findHandlers(Method process, Field packetOpcode) {
List<PacketHandler> handlers = new ArrayList<>();
Instructions ins = process.getCode().getInstructions();
for (int j = 0; j < ins.getInstructions().size(); ++j) {
Instruction i = ins.getInstructions().get(j);
if (i.getType() != InstructionType.GETSTATIC) {
continue;
}
GetStatic gs = (GetStatic) i;
if (gs.getMyField() != packetOpcode) {
continue;
}
Instruction push = ins.getInstructions().get(j + 1);
if (!(push instanceof PushConstantInstruction)) {
continue;
}
PushConstantInstruction pci = (PushConstantInstruction) push;
if (!(pci.getConstant() instanceof Number)) {
continue;
}
int opcode = ((Number) pci.getConstant()).intValue();
if (opcode == -1) {
continue;
}
Instruction jump = ins.getInstructions().get(j + 2);
if (jump.getType() != InstructionType.IF_ICMPEQ && jump.getType() != InstructionType.IF_ICMPNE) {
continue;
}
Instruction start, end;
if (jump.getType() == InstructionType.IF_ICMPEQ) {
// this seems to not ever happen
start = ((If) jump).getJumps().get(0);
// end = ins.getInstructions().get(j + 3);
end = null;
} else {
start = ins.getInstructions().get(j + 3);
end = ((If) jump).getJumps().get(0);
}
PacketHandler handler = new PacketHandler(process, jump, start, push, opcode);
handlers.add(handler);
if (end != null) {
// Anything else which jumps to here instead needs to return.
insertReturn(ins, jump, end);
}
logger.info("Found packet handler {} opcode {}", handler, handler.getOpcode());
}
return handlers;
}
use of net.runelite.asm.attributes.code.instructions.GetStatic in project runelite by runelite.
the class PacketLengthFinder method run.
// getstatic class272/field3690 [I
// getstatic Client/packetType I
// iaload
// putstatic Client/packetLength I
private void run(Code code) {
if (code == null) {
return;
}
Instructions instructions = code.getInstructions();
Field type = packetType.getPacketType();
for (int i = 0; i < instructions.getInstructions().size() - 3; ++i) {
Instruction i1 = instructions.getInstructions().get(i), i2 = instructions.getInstructions().get(i + 1), i3 = instructions.getInstructions().get(i + 2), i4 = instructions.getInstructions().get(i + 3);
if (!(i1 instanceof GetStatic)) {
continue;
}
if (!(i2 instanceof GetStatic)) {
continue;
}
GetStatic gs = (GetStatic) i2;
if (gs.getMyField() != type) {
continue;
}
if (!(i3 instanceof IALoad)) {
continue;
}
if (!(i4 instanceof PutStatic)) {
continue;
}
PutStatic ps = (PutStatic) i4;
assert packetLength == null : "packetLength already found";
packetLength = ps.getMyField();
getArray = (GetStatic) i1;
getType = gs;
load = (IALoad) i3;
store = ps;
return;
}
}
use of net.runelite.asm.attributes.code.instructions.GetStatic in project runelite by runelite.
the class OpcodeReplacer method run.
public void run(ClassGroup group, Collection<PacketWrite> writes) {
int count = 0;
ClassFile runeliteOpcodes = group.findClass(RUNELITE_OPCODES);
assert runeliteOpcodes != null : "Opcodes class must exist";
for (PacketWrite wp : writes) {
Instructions ins = wp.getInstructions();
Instruction param = wp.getOpcodeIns();
if (!(param instanceof PushConstantInstruction)) {
continue;
}
final String fieldName = "PACKET_CLIENT_" + wp.getOpcode();
net.runelite.asm.pool.Field field = new net.runelite.asm.pool.Field(new net.runelite.asm.pool.Class(RUNELITE_OPCODES), fieldName, Type.INT);
ins.replace(param, new GetStatic(ins, field));
if (runeliteOpcodes.findField(fieldName) == null) {
Field opField = new Field(runeliteOpcodes, fieldName, Type.INT);
// ACC_FINAL causes javac to inline the fields, which prevents
// the mapper from doing field mapping
opField.setAccessFlags(ACC_PUBLIC | ACC_STATIC);
// setting a non-final static field value
// doesn't work with fernflower
opField.setValue(wp.getOpcode());
runeliteOpcodes.addField(opField);
// add initialization
Method clinit = runeliteOpcodes.findMethod("<clinit>");
assert clinit != null;
Instructions instructions = clinit.getCode().getInstructions();
instructions.addInstruction(0, new LDC(instructions, wp.getOpcode()));
instructions.addInstruction(1, new PutStatic(instructions, opField));
}
++count;
}
logger.info("Injected {} packet writes", count);
}
use of net.runelite.asm.attributes.code.instructions.GetStatic in project runelite by runelite.
the class InjectGetter method injectGetter.
public void injectGetter(ClassFile clazz, java.lang.reflect.Method method, Field field, Number getter) {
assert clazz.findMethod(method.getName()) == null;
assert field.isStatic() || field.getClassFile() == clazz;
Signature sig = new Signature.Builder().setReturnType(Inject.classToType(method.getReturnType())).build();
Method getterMethod = new Method(clazz, method.getName(), sig);
getterMethod.setAccessFlags(ACC_PUBLIC);
// create code
Code code = new Code(getterMethod);
getterMethod.setCode(code);
Instructions instructions = code.getInstructions();
List<Instruction> ins = instructions.getInstructions();
if (field.isStatic()) {
code.setMaxStack(1);
ins.add(new GetStatic(instructions, field.getPoolField()));
} else {
code.setMaxStack(2);
ins.add(new ALoad(instructions, 0));
ins.add(new GetField(instructions, field.getPoolField()));
}
if (getter != null) {
code.setMaxStack(2);
assert getter instanceof Integer || getter instanceof Long;
if (getter instanceof Integer) {
ins.add(new LDC(instructions, (int) getter));
ins.add(new IMul(instructions));
} else {
ins.add(new LDC(instructions, (long) getter));
ins.add(new LMul(instructions));
}
}
InstructionType returnType;
if (field.getType().isPrimitive() && field.getType().getDimensions() == 0) {
switch(field.getType().toString()) {
case "B":
case "C":
case "I":
case "S":
case "Z":
returnType = InstructionType.IRETURN;
break;
case "D":
returnType = InstructionType.DRETURN;
break;
case "F":
returnType = InstructionType.FRETURN;
break;
case "J":
returnType = InstructionType.LRETURN;
break;
default:
throw new RuntimeException("Unknown type");
}
} else {
returnType = InstructionType.ARETURN;
}
ins.add(new Return(instructions, returnType));
clazz.addMethod(getterMethod);
++injectedGetters;
}
Aggregations