use of net.runelite.asm.attributes.code.instructions.LDC in project runelite by runelite.
the class ModArith method findConstants.
// find associated constants with each field
private void findConstants(MethodContext mctx) {
for (InstructionContext ctx : mctx.getInstructionContexts()) {
if (ctx.getInstruction() instanceof FieldInstruction) {
FieldInstruction fi = (FieldInstruction) ctx.getInstruction();
if (fi.getMyField() == null) {
continue;
}
if ((!fi.getField().getType().equals(Type.INT) && !fi.getField().getType().equals(Type.LONG)) || fi.getField().getType().isArray()) {
continue;
}
FieldInfo fieldInfo = getFieldInfo(fi.getMyField());
List<InstructionContext> l = getInsInExpr(ctx, new HashSet(), false);
// check if this contains another field
boolean other = false;
boolean getter = false, setter = false;
for (InstructionContext i : l) {
if (i.getInstruction() instanceof FieldInstruction) {
FieldInstruction fi2 = (FieldInstruction) i.getInstruction();
Field myField = fi2.getMyField();
if (myField != null && myField != fi.getMyField()) {
Type t = myField.getType();
if (t.equals(fi.getMyField().getType())) {
other = true;
}
} else if (myField != null && myField == fi.getMyField()) {
if (fi2 instanceof SetFieldInstruction) {
setter = true;
} else {
getter = true;
}
}
}
}
// check if this is a constant assignment
boolean constant = false;
if (fi instanceof SetFieldInstruction) {
// value being set
InstructionContext pushedsfi = ctx.getPops().get(0).getPushed();
pushedsfi = pushedsfi.resolve(ctx.getPops().get(0));
if (pushedsfi.getInstruction() instanceof LDC) {
constant = true;
}
}
for (InstructionContext i : l) {
if (i.getInstruction() instanceof LDC) {
PushConstantInstruction w = (PushConstantInstruction) i.getInstruction();
if (w.getConstant() instanceof Integer || w.getConstant() instanceof Long) {
AssociatedConstant n = new AssociatedConstant();
n.value = (Number) w.getConstant();
n.other = other;
n.constant = constant;
n.getter = getter;
n.setter = setter;
fieldInfo.constants.add(n);
}
}
}
}
}
}
use of net.runelite.asm.attributes.code.instructions.LDC in project runelite by runelite.
the class MultiplyZeroDeobfuscator method visit.
private void visit(MethodContext mctx) {
for (InstructionContext ictx : mctx.getInstructionContexts()) {
Instruction instruction = ictx.getInstruction();
Instructions ins = instruction.getInstructions();
if (ins == null) {
continue;
}
if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) {
continue;
}
List<Instruction> ilist = ins.getInstructions();
StackContext one = ictx.getPops().get(0);
StackContext two = ictx.getPops().get(1);
Instruction ione = one.getPushed().getInstruction(), itwo = two.getPushed().getInstruction();
boolean remove = false;
if (ione instanceof PushConstantInstruction) {
PushConstantInstruction pci = (PushConstantInstruction) ione;
Number value = (Number) pci.getConstant();
if (DMath.equals(value, 0)) {
remove = true;
}
}
if (itwo instanceof PushConstantInstruction) {
PushConstantInstruction pci = (PushConstantInstruction) itwo;
Number value = (Number) pci.getConstant();
if (DMath.equals(value, 0)) {
remove = true;
}
}
if (remove == false) {
continue;
}
if (!ilist.contains(instruction)) {
// already done
continue;
}
if (!MultiplicationDeobfuscator.isOnlyPath(ictx, null)) {
continue;
}
// remove both, remove imul, push 0
ictx.removeStack(1);
ictx.removeStack(0);
if (instruction instanceof IMul) {
ins.replace(instruction, new LDC(ins, 0));
} else if (instruction instanceof LMul) {
ins.replace(instruction, new LDC(ins, 0L));
} else {
throw new IllegalStateException();
}
++count;
}
}
use of net.runelite.asm.attributes.code.instructions.LDC 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.LDC 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;
}
use of net.runelite.asm.attributes.code.instructions.LDC in project runelite by runelite.
the class MixinInjectorTest method testInject.
@Test
public void testInject() throws Exception {
InputStream deobIn = getClass().getResourceAsStream("DeobTarget.class");
ClassFile deobTarget = ClassUtil.loadClass(deobIn);
ClassGroup deob = new ClassGroup();
deob.addClass(deobTarget);
InputStream vanillaIn = getClass().getResourceAsStream("VanillaTarget.class");
ClassFile vanillaTarget = ClassUtil.loadClass(vanillaIn);
ClassGroup vanilla = new ClassGroup();
vanilla.addClass(vanillaTarget);
Map<Class<?>, List<ClassFile>> mixinClasses = new HashMap<>();
mixinClasses.put(Source.class, Collections.singletonList(vanillaTarget));
mixinClasses.put(Source2.class, Collections.singletonList(vanillaTarget));
Inject inject = new Inject(deob, vanilla);
new MixinInjector(inject).inject(mixinClasses);
// Check if "foo" has been injected
Field foo = vanillaTarget.findField("foo");
assertNotNull(foo);
assertEquals(INT, foo.getType());
assertEquals(ACC_PUBLIC | ACC_STATIC, foo.getAccessFlags());
// Check if "foo2()V" has been injected
Method foo2 = vanillaTarget.findMethod("foo2");
assertNotNull(foo2);
assertEquals(new Signature("()V"), foo2.getDescriptor());
assertEquals(ACC_PUBLIC, foo2.getAccessFlags());
// Check if "ob_foo3(I)V" was copied
Method foo3 = vanillaTarget.findMethod("copy$foo3");
assertNotNull(foo3);
assertEquals(new Signature("(I)V"), foo3.getDescriptor());
assertEquals(ACC_PUBLIC, foo3.getAccessFlags());
// Check if "ob_foo3(I)V" was replaced
Method ob_foo3 = vanillaTarget.findMethod("ob_foo3");
assertNotNull(ob_foo3);
assertEquals(new Signature("(I)V"), ob_foo3.getDescriptor());
assertEquals(ob_foo3.getCode().getInstructions().getInstructions().stream().filter(i -> i instanceof LDC && ((LDC) i).getConstant().equals("replaced")).count(), 1);
// Check that the "foo4" field access in the new code body was mapped correctly
assertEquals(ob_foo3.getCode().getInstructions().getInstructions().stream().filter(i -> {
if (!(i instanceof GetStatic)) {
return false;
}
net.runelite.asm.pool.Field field = ((GetStatic) i).getField();
if (!field.getClazz().getName().equals("net/runelite/injector/VanillaTarget")) {
return false;
}
if (!field.getName().equals("ob_foo4")) {
return false;
}
return true;
}).count(), 1);
// Check that the "foo3()" call in the new code body was mapped to the copy
assertEquals(ob_foo3.getCode().getInstructions().getInstructions().stream().filter(i -> {
if (!(i instanceof InvokeVirtual)) {
return false;
}
net.runelite.asm.pool.Method method = ((InvokeVirtual) i).getMethod();
if (!method.getClazz().getName().equals("net/runelite/injector/VanillaTarget")) {
return false;
}
if (!method.getName().equals("copy$foo3")) {
return false;
}
return true;
}).count(), 1);
// Check if "foo5()V" was injected
Method foo5 = vanillaTarget.findMethod("foo5");
assertNotNull(foo5);
assertEquals(new Signature("()V"), foo5.getDescriptor());
assertEquals(ACC_PUBLIC, foo5.getAccessFlags());
// Check that the shadow "foo" field access was mapped correctly
assertEquals(foo5.getCode().getInstructions().getInstructions().stream().filter(i -> {
if (!(i instanceof GetStatic)) {
return false;
}
net.runelite.asm.pool.Field field = ((GetStatic) i).getField();
if (!field.getClazz().getName().equals("net/runelite/injector/VanillaTarget")) {
return false;
}
if (!field.getName().equals("foo")) {
return false;
}
return true;
}).count(), 1);
}
Aggregations