use of net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction in project runelite by runelite.
the class ConstantParameter method findConstantParameter.
// find constant values passed as parameters
private void findConstantParameter(List<Method> methods, InstructionContext invokeCtx) {
checkMethodsAreConsistent(methods);
// all methods must have the same signature etc
Method method = methods.get(0);
int offset = method.isStatic() ? 0 : 1;
List<StackContext> pops = invokeCtx.getPops();
outer: // object is popped first, then param 1, 2, 3, etc. double and long take two slots.
for (int lvtOffset = offset, parameterIndex = 0; parameterIndex < method.getDescriptor().size(); lvtOffset += method.getDescriptor().getTypeOfArg(parameterIndex++).getSize()) {
// get(0) == first thing popped which is the last parameter,
// get(descriptor.size() - 1) == first parameter
StackContext ctx = pops.get(method.getDescriptor().size() - 1 - parameterIndex);
ConstantMethodParameter cmp = getCMPFor(methods, parameterIndex, lvtOffset);
if (cmp.invalid) {
continue;
}
if (ctx.getPushed().getInstruction() instanceof PushConstantInstruction) {
PushConstantInstruction pc = (PushConstantInstruction) ctx.getPushed().getInstruction();
if (!(pc.getConstant() instanceof Number)) {
cmp.invalid = true;
continue;
}
Number number = (Number) pc.getConstant();
if (!cmp.values.contains(number)) {
cmp.values.add((Number) pc.getConstant());
}
} else {
cmp.invalid = true;
}
}
}
use of net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction in project runelite by runelite.
the class ExprArgOrder method compare.
public static int compare(Method method, InstructionType type, Expression expr1, Expression expr2) {
Instruction i1 = expr1.getHead().getInstruction();
Instruction i2 = expr2.getHead().getInstruction();
if (type == IF_ICMPEQ || type == IF_ICMPNE || type == IADD || type == IMUL) {
if (!(i1 instanceof PushConstantInstruction) && (i2 instanceof PushConstantInstruction)) {
return 1;
}
if (i1 instanceof PushConstantInstruction && !(i2 instanceof PushConstantInstruction)) {
return -1;
}
}
if (type == IF_ACMPEQ || type == IF_ACMPNE) {
if (!(i1 instanceof AConstNull) && (i2 instanceof AConstNull)) {
return 1;
}
if (i1 instanceof AConstNull && !(i2 instanceof AConstNull)) {
return -1;
}
}
int hash1 = hash(method, expr1.getHead());
int hash2 = hash(method, expr2.getHead());
if (hash1 == hash2) {
logger.debug("Unable to differentiate {} from {}", expr1.getHead(), expr2.getHead());
}
return Integer.compare(hash1, hash2);
}
use of net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction 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.instruction.types.PushConstantInstruction in project runelite by runelite.
the class PacketTypeFinder method run.
private void run(Code code) {
if (code == null) {
return;
}
Instructions instructions = code.getInstructions();
for (int i = 0; i < instructions.getInstructions().size() - 1; ++i) {
Instruction i1 = instructions.getInstructions().get(i), i2 = instructions.getInstructions().get(i + 1);
if (i1 instanceof PushConstantInstruction && i2.getType() == InstructionType.PUTSTATIC) {
PushConstantInstruction pci = (PushConstantInstruction) i1;
SetFieldInstruction sfi = (SetFieldInstruction) i2;
Field field = sfi.getMyField();
if (Objects.equal(-1, pci.getConstant()) && field != null) {
Integer count = sets.get(field);
if (count == null) {
sets.put(field, 1);
} else {
sets.put(field, count + 1);
}
}
}
}
}
use of net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction 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);
}
Aggregations