@Override public MethodTransformer[] getMethodTransformers() { MethodTransformer loadWorldTransformer = new MethodTransformer() { public String getMethodName() {return CoreLoader.isObfuscated ? "a" : "loadWorld";} public String getDescName() {return "(L" + (CoreLoader.isObfuscated ? "bnq" : Type.getInternalName(WorldClient.class)) + ";Ljava/lang/String;)V";} public void transform(ClassNode classNode, MethodNode method, boolean obfuscated) { CLTLog.info("Found method: " + method.name + " " + method.desc); CLTLog.info("begining at start of method " + getMethodName()); //TransformerUtil.onWorldLoad(WorldClient worldClientIn) InsnList toInsert = new InsnList(); toInsert.add(new VarInsnNode(ALOAD, 1)); //worldClientIn toInsert.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(TransformerUtil.class), "onWorldLoad", "(L" + Type.getInternalName(WorldClient.class) + ";)V", false)); method.instructions.insertBefore(method.instructions.getFirst(), toInsert); } }; return new MethodTransformer[] {loadWorldTransformer}; }
@Override public void visit(LoadConst.Str node) { // use byte strings? if (context.compilerSettings.byteStrings()) { if (context.compilerSettings.constCaching()) { il.add(loadCachedConst(node.value())); } else { il.add(newByteString(node.value())); } } else { // java.lang.String il.add(new LdcInsnNode(node.value())); } il.add(new VarInsnNode(ASTORE, slot(node.dest()))); }
@Override public void visit(UnOp node) { if (node.op() == UnOp.Op.NOT) { il.add(new VarInsnNode(ALOAD, slot(node.arg()))); il.add(ConversionMethods.booleanValueOf()); il.add(new InsnNode(ICONST_1)); il.add(new InsnNode(IXOR)); il.add(BoxedPrimitivesMethods.box(Type.BOOLEAN_TYPE, Type.getType(Boolean.class))); } else { ResumptionPoint rp = newResumptionPoint(); il.add(rp.save()); il.add(loadExecutionContext()); il.add(new VarInsnNode(ALOAD, slot(node.arg()))); il.add(DispatchMethods.dynamic(dispatchMethodName(node.op()), 1)); il.add(rp.resume()); il.add(retrieve_0()); } il.add(new VarInsnNode(ASTORE, slot(node.dest()))); }
@Override public void visit(Branch.Condition.Nil cond) { assert (destLabel != null); il.add(new VarInsnNode(ALOAD, slot(cond.addr()))); if (!isSub() || resolver.isLocalLabel(destLabel)) { // local jump il.add(new JumpInsnNode(IFNULL, l(destLabel))); } else { // non-local jump LabelNode l_nojump = new LabelNode(); il.add(new JumpInsnNode(IFNONNULL, l_nojump)); il.add(_nonLocalGoto(destLabel)); il.add(l_nojump); il.add(new FrameNode(F_SAME, 0, null, 0, null)); } }
@Override public void visit(Branch.Condition.Bool cond) { assert (destLabel != null); il.add(new VarInsnNode(ALOAD, slot(cond.addr()))); il.add(ConversionMethods.booleanValueOf()); if (!isSub() || resolver.isLocalLabel(destLabel)) { // local jump il.add(new JumpInsnNode(cond.expected() ? IFNE : IFEQ, l(destLabel))); } else { // non-local jump LabelNode l_nojump = new LabelNode(); il.add(new JumpInsnNode(cond.expected() ? IFEQ : IFNE, l_nojump)); il.add(_nonLocalGoto(destLabel)); il.add(l_nojump); il.add(new FrameNode(F_SAME, 0, null, 0, null)); } }
@Override public void visit(Branch.Condition.NumLoopEnd cond) { assert (destLabel != null); il.add(new VarInsnNode(ALOAD, slot(cond.var()))); il.add(new TypeInsnNode(CHECKCAST, Type.getInternalName(Number.class))); il.add(new VarInsnNode(ALOAD, slot(cond.limit()))); il.add(new TypeInsnNode(CHECKCAST, Type.getInternalName(Number.class))); il.add(new VarInsnNode(ALOAD, slot(cond.step()))); il.add(new TypeInsnNode(CHECKCAST, Type.getInternalName(Number.class))); il.add(DispatchMethods.continueLoop()); if (!isSub() || resolver.isLocalLabel(destLabel)) { // local jump il.add(new JumpInsnNode(IFEQ, l(destLabel))); } else { // non-local jump LabelNode l_nojump = new LabelNode(); il.add(new JumpInsnNode(IFNE, l_nojump)); il.add(_nonLocalGoto(destLabel)); il.add(l_nojump); il.add(new FrameNode(F_SAME, 0, null, 0, null)); } }
public RunMethod.ClosureFieldInstance toClosureFieldInstance() { assert (this.isClosed()); FieldNode fieldNode = instanceFieldNode(); InsnList il = new InsnList(); il.add(new VarInsnNode(ALOAD, 0)); il.add(instantiationInsns()); il.add(new FieldInsnNode( PUTFIELD, context.thisClassType().getInternalName(), instanceFieldName(), instanceType().getDescriptor())); return new RunMethod.ClosureFieldInstance(instanceFieldNode(), il); }
private InsnList fetchInstanceInsns() { InsnList il = new InsnList(); if (this.isClosed()) { if (this.isPure()) { il.add(new FieldInsnNode( GETSTATIC, instanceType().getInternalName(), ASMBytecodeEmitter.instanceFieldName(), instanceType().getDescriptor())); } else { il.add(new VarInsnNode(ALOAD, 0)); il.add(new FieldInsnNode( GETFIELD, context.thisClassType().getInternalName(), instanceFieldName(), instanceType().getDescriptor())); } } else { il.add(instantiationInsns()); } return il; }
private InsnList dispatchTable(List<LabelNode> extLabels, List<LabelNode> resumptionLabels, LabelNode errorStateLabel) { InsnList il = new InsnList(); assert (!extLabels.isEmpty()); ArrayList<LabelNode> labels = new ArrayList<>(); labels.addAll(extLabels); labels.addAll(resumptionLabels); LabelNode[] labelArray = labels.toArray(new LabelNode[labels.size()]); int min = 1 - extLabels.size(); int max = resumptionLabels.size(); il.add(new VarInsnNode(ILOAD, LV_RESUME)); il.add(new TableSwitchInsnNode(min, max, errorStateLabel, labelArray)); return il; }
InsnList createSnapshot() { InsnList il = new InsnList(); il.add(new VarInsnNode(ALOAD, 0)); // this il.add(new VarInsnNode(ALOAD, 0)); il.add(new VarInsnNode(ILOAD, LV_RESUME)); if (context.isVararg()) { il.add(new VarInsnNode(ALOAD, LV_VARARGS)); } for (int i = 0; i < numOfRegisters(); i++) { il.add(new VarInsnNode(ALOAD, slotOffset() + i)); } il.add(snapshotMethodInvokeInsn()); return il; }
@Override public MethodTransformer[] getMethodTransformers() { MethodTransformer transformLoadWorld = new MethodTransformer() { @Override public MethodName getName() { return Names.Minecraft_loadWorld; } @Override public void transform(ClassNode classNode, MethodNode method, boolean obfuscated) { CLTLog.info("Found method: " + method.name + " " + method.desc); CLTLog.info("begining at start of method " + getName().all()); InsnList toInsert = new InsnList(); toInsert.add(new VarInsnNode(ALOAD, 1)); //worldClientIn toInsert.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(RenderUtil.class), "onWorldLoad", "(L" + Type.getInternalName(WorldClient.class) + ";)V", false)); method.instructions.insertBefore(method.instructions.getFirst(), toInsert); } }; return new MethodTransformer[] {transformLoadWorld}; }
@Override public void transform(ClassNode clazz, MethodNode method, InsnMatcher matcher) { method.tryCatchBlocks.clear(); method.localVariables.clear(); method.instructions.clear(); /* this.loginHandlerList.put(SteamIdAsString, loginHandler); */ method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); method.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, "com/wurmonline/server/steam/SteamHandler", "loginHandlerList", "Ljava/util/Map;")); method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 2)); method.instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true)); method.instructions.add(new InsnNode(Opcodes.POP)); /* return true; */ method.instructions.add(new InsnNode(Opcodes.ICONST_1)); method.instructions.add(new InsnNode(Opcodes.IRETURN)); }
@Override public void transform(ClassNode clazz, MethodNode method, InsnMatcher matcher) { AbstractInsnNode[] match = Iterators.getOnlyElement(matcher.match("BIPUSH ISTORE", m -> { IntInsnNode push = (IntInsnNode) m[0]; if (push.operand != 50) { return false; } VarInsnNode store = (VarInsnNode) m[1]; LocalVariableNode node = AsmUtils.getLocalVariable(method, store.var, store); return node != null && node.name.equals("resource") && node.desc.equals("I"); })); method.instructions.remove(match[0]); method.instructions.remove(match[1]); }
public static void establishCallback(ClassNode cn, MethodNode mn) { if (!mn.desc.startsWith("()")) { MethodNode blank = new MethodNode(); Method method = new Method(mn.name, mn.desc); GeneratorAdapter adapter = new GeneratorAdapter(mn.access, method, blank); adapter.visitCode(); adapter.push(cn.name + "." + mn.name + " " + mn.desc); adapter.loadArgArray(); adapter.invokeStatic(Type.getType(CallFactory.class), new Method("testInvoke", "(Ljava/lang/String;[Ljava/lang/Object;)V")); for (AbstractInsnNode ain : mn.instructions.toArray()) { if (ain instanceof VarInsnNode) { mn.instructions.insertBefore(ain, blank.instructions); return; } } } }
@Override public void patchMethod(MethodNode methodNode, ClassNode classNode, boolean obfuscated) { AbstractInsnNode insert = ASMUtil.findFirstInstruction(methodNode, Opcodes.DSTORE, 5); if (insert == null) return; InsnList insnList = new InsnList(); insnList.add(new VarInsnNode(Opcodes.ALOAD, 0)); insnList.add(new FieldInsnNode(Opcodes.GETFIELD, obfuscated ? "nh" : "net/minecraft/network/NetHandlerPlayServer", obfuscated ? "b" : "playerEntity", obfuscated ? "Lmw;" : "Lnet/minecraft/entity/player/EntityPlayerMP;")); insnList.add(new VarInsnNode(Opcodes.DLOAD, 5)); insnList.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "com/techjar/vivecraftforge/util/ASMDelegator", "playerEntityReachDistance", obfuscated ? "(Lyz;D)D" : "(Lnet/minecraft/entity/player/EntityPlayer;D)D", false)); insnList.add(new VarInsnNode(Opcodes.DSTORE, 5)); methodNode.instructions.insert(insert, insnList); VivecraftForgeLog.debug("Inserted delegate method call."); AbstractInsnNode removeInsn = ASMUtil.findFirstInstruction(methodNode, Opcodes.LDC, 9.0D); if (removeInsn != null) { int remove = methodNode.instructions.indexOf(removeInsn); for (int i = 0; i < 2; i++) { methodNode.instructions.remove(methodNode.instructions.get(remove)); } VivecraftForgeLog.debug("Removed variable assignment."); } else { VivecraftForgeLog.debug("Variable assignment not found."); } }
@Override public ClassVisitor patch(String className, ClassVisitor delegate) throws Exception { return new FindingVisitor( delegate, new VarInsnNode(ALOAD, 4), new LdcInsnNode(7000L), new MethodInsnNode(INVOKEVIRTUAL, "java/lang/Thread", "join", "(J)V", false) ) { @Override public void handle(InsnList nodes, MethodVisitor visitor) { visitor.visitVarInsn(ALOAD, 4); visitor.visitFieldInsn(GETSTATIC, "org/squiddev/cctweaks/lua/Config$Computer", "computerThreadTimeout", "I"); visitor.visitInsn(I2L); visitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Thread", "join", "(J)V", false); } }.onMethod("run").once().mustFind(); }
private void convertVarLoadInsn(VarInsnNode insn) { int op = insn.getOpcode(); boolean dword = op == LLOAD || op == DLOAD; StackFrame frame = getFrame(insn); Operand[] out = frame.out(); Operand opr; if (out == null) { opr = new Operand(insn, getLocal(insn.var)); frame.out(opr); } else { opr = out[0]; } if (dword) pushDual(opr); else push(opr); }
private void convertVarStoreInsn(VarInsnNode insn) { int op = insn.getOpcode(); boolean dword = op == LSTORE || op == DSTORE; StackFrame frame = getFrame(insn); Operand opr = dword ? popDual() : pop(); Local local = getLocal(insn.var); if (!units.containsKey(insn)) { DefinitionStmt as = Jimple.v().newAssignStmt(local, opr.stackOrValue()); opr.addBox(as.getRightOpBox()); frame.boxes(as.getRightOpBox()); frame.in(opr); setUnit(insn, as); } else { frame.mergeIn(opr); } assignReadOps(local); }
public static boolean insnEqual(AbstractInsnNode node1, AbstractInsnNode node2) { if (node1.getType() != node2.getType()) { return false; } else if (node1.getOpcode() != node2.getOpcode()) { return false; } switch (node2.getType()) { case VAR_INSN: return varInsnEqual((VarInsnNode) node1, (VarInsnNode) node2); case TYPE_INSN: return typeInsnEqual((TypeInsnNode) node1, (TypeInsnNode) node2); case FIELD_INSN: return fieldInsnEqual((FieldInsnNode) node1, (FieldInsnNode) node2); case METHOD_INSN: return methodInsnEqual((MethodInsnNode) node1, (MethodInsnNode) node2); case LDC_INSN: return ldcInsnEqual((LdcInsnNode) node1, (LdcInsnNode) node2); case IINC_INSN: return iincInsnEqual((IincInsnNode) node1, (IincInsnNode) node2); case INT_INSN: return intInsnEqual((IntInsnNode) node1, (IntInsnNode) node2); default: return true; } }
private byte[] transformPlayer(byte[] bytes) { ClassNode clazz = ASMHelper.createClassNode(bytes); MethodNode method = ASMHelper.findMethod(clazz, ASMNames.MD_PLAYER_UPDATE); InsnList needle = new InsnList(); needle.add(new VarInsnNode(Opcodes.ALOAD, 0)); needle.add(ASMHelper.getFieldInsnNode(Opcodes.GETFIELD, ASMNames.FD_PLAYER_WORLD_OBJ)); needle.add(ASMHelper.getMethodInsnNode(Opcodes.INVOKEVIRTUAL, ASMNames.MD_WORLD_IS_DAY, false)); LabelNode l2 = new LabelNode(); needle.add(new JumpInsnNode(Opcodes.IFEQ, l2)); AbstractInsnNode insertPoint = ASMHelper.findFirstNodeFromNeedle(method.instructions, needle); method.instructions.remove(insertPoint.getNext().getNext()); method.instructions.set(insertPoint.getNext(), ASMHelper.getMethodInsnNode(Opcodes.INVOKESTATIC, ASMNames.MD_RM_HELPER_SLEEP_PLAEYR, false)); return ASMHelper.createBytes(clazz, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); }
@Override public byte[] transform(String name, String transformedName, byte[] basicClass) { ClassReader reader = new ClassReader(basicClass); ClassNode node = new ClassNode(ASM5); reader.accept(node, 0); node.methods.removeIf(m -> !m.name.equals("<init>")); node.methods.stream() .map(m -> m.instructions) .peek(InsnList::clear) .peek(l -> l.add(new VarInsnNode(ALOAD, 0))) .peek(l -> l.add(new MethodInsnNode(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false))) .forEach(l -> l.add(new InsnNode(RETURN))); node.interfaces.clear(); node.superName = "java/lang/Object"; node.innerClasses.clear(); ClassWriter writer = ASMHelper.newClassWriter(0); node.accept(writer); return writer.toByteArray(); }
private void patchMenu(ClassNode node) { Logger.Info("Patching menu (" + node.name + ".class)"); Iterator<MethodNode> methodNodeList = node.methods.iterator(); while (methodNodeList.hasNext()) { MethodNode methodNode = methodNodeList.next(); // Menu swap hook if (methodNode.name.equals("e") && methodNode.desc.equals("(II)V")) { AbstractInsnNode first = methodNode.instructions.getFirst(); LabelNode label = new LabelNode(); methodNode.instructions.insertBefore(first, new VarInsnNode(Opcodes.ALOAD, 0)); methodNode.instructions.insertBefore(first, new MethodInsnNode(Opcodes.INVOKESTATIC, "Game/Menu", "switchList", "(Ljava/lang/Object;)Z")); methodNode.instructions.insertBefore(first, new JumpInsnNode(Opcodes.IFGT, label)); methodNode.instructions.insertBefore(first, new InsnNode(Opcodes.RETURN)); methodNode.instructions.insertBefore(first, label); } } }
@Override public boolean transform(ClassNode classNode, String transformedName) { boolean transformed = false; MethodNode createEntityByName = this.getMethod(classNode, "createEntityByName", String.class, World.class, Entity.class); MethodNode createEntityByID = this.getMethod(classNode, "createEntityByID", int.class, World.class, Entity.class); MethodNode createEntityFromNBT = this.getMethod(classNode, "createEntityFromNBT", NBTTagCompound.class, World.class, Entity.class); Instruction createEntityInstruction = this.instruction() .var(ALOAD, 1) .method(INVOKESTATIC, BlockSystemHooks.class, "getMainWorld", World.class, World.class) .var(ASTORE, 1); Predicate<AbstractInsnNode> createEntityNode = node -> node.getOpcode() == ASTORE && ((VarInsnNode) node).var == 2; if (createEntityByName != null) { this.insertAfter(createEntityByName, createEntityNode, createEntityInstruction.build(), false); transformed = true; } if (createEntityByID != null) { this.insertAfter(createEntityByID, createEntityNode, createEntityInstruction.build(), false); transformed = true; } if (createEntityFromNBT != null) { this.insertAfter(createEntityFromNBT, createEntityNode, createEntityInstruction.build(), false); transformed = true; } return transformed; }
public static void loadNode(ListIterator<AbstractInsnNode> iterator, String paramType, int index) { //(Ljava/lang/String;IDCBSJZF)V if ("I".equals(paramType) || "C".equals(paramType) || "B".equals(paramType) || "S".equals(paramType) || "Z".equals(paramType) ) { iterator.add(new VarInsnNode(Opcodes.ILOAD, index)); } else if ("J".equals(paramType)) { iterator.add(new VarInsnNode(Opcodes.LLOAD, index)); } else if ("F".equals(paramType)) { iterator.add(new VarInsnNode(Opcodes.FLOAD, index)); } else if ("D".equals(paramType)) { iterator.add(new VarInsnNode(Opcodes.DLOAD, index)); } else { iterator.add(new VarInsnNode(Opcodes.ALOAD, index)); } }
private void injectFormatSymbol( MethodNode method, int index ) { TextFormattingLog.info( "Injecting at index " + index ); InsnList list = new InsnList(); list.add( new TypeInsnNode( NEW, "java/lang/StringBuilder" ) ); list.add( new InsnNode( DUP ) ); list.add( new LdcInsnNode( "Adding format symbol to allowed characters list..." ) ); list.add( new MethodInsnNode( INVOKESTATIC, "com/spacechase0/minecraft/textformatting/TextFormattingLog", "info", "(Ljava/lang/String;)V" ) ); list.add( new VarInsnNode( ALOAD, 0 ) ); list.add( new MethodInsnNode( INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V" ) ); list.add( new FieldInsnNode( GETSTATIC, "com/spacechase0/minecraft/textformatting/ColorData", "formatSymbol", "Ljava/lang/String;" ) ); list.add( new MethodInsnNode( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;" ) ); list.add( new MethodInsnNode( INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;" ) ); list.add( new VarInsnNode( ASTORE, 0 ) ); method.instructions.insertBefore( method.instructions.get( index ), list ); }
@Override public InsnList build(MethodContext context) { Type[] argumentTypes = context.getArgumentTypes(); int[] arguments = context.getArguments(); InsnList insnList = new InsnList(); insnList.add(new LdcInsnNode(arguments.length)); insnList.add(new TypeInsnNode(Opcodes.ANEWARRAY, Type.getInternalName(Object.class))); for (int i = 0; i < arguments.length; i++) { insnList.add(new InsnNode(DUP)); insnList.add(new LdcInsnNode(i)); int index = arguments[i]; Type type = argumentTypes[i]; insnList.add(new VarInsnNode(type.getOpcode(ILOAD), index)); insnList.add(new BoxPrimitives(type).build(context)); insnList.add(new InsnNode(AASTORE)); } return insnList; }
private AbstractInsnNode skipCheckCastBackwards(AbstractInsnNode node) { // skip possible (?) ALOAD 0 if not static if (! this.isStatic && (node instanceof VarInsnNode) && (node.getOpcode() == ALOAD) && (((VarInsnNode) node).var == 0)) { node = node.getPrevious(); } // skip possible check cast if ((node instanceof TypeInsnNode) && (node.getOpcode() == CHECKCAST)) { node = node.getPrevious(); } // skip possible (?) ALOAD 0 if not static if (! this.isStatic && (node instanceof VarInsnNode) && (node.getOpcode() == ALOAD) && (((VarInsnNode) node).var == 0)) { node = node.getPrevious(); } return node; }
@Test public void insertMultipleNodes() { MethodNode mthdNode = new MethodNode(); MethodEditor editor = createMethodEditor1(mthdNode); editor.setInsertMode(); boolean result = editor.apply(editor.newInstructionBuilder() .varInsn(VarInsnOpcodes.ALOAD, 0) .methodInsn(MethodInsnOpcodes.INVOKEVIRTUAL, "A", "A.a", "()J")); assertEquals(true, result); assertEquals(2, editor.getCursor()); assertEquals(11, getMethodNode(editor).instructions.size()); assertTrue(getMethodNode(editor).instructions.get(0) instanceof VarInsnNode); assertTrue(getMethodNode(editor).instructions.get(1) instanceof MethodInsnNode); assertTrue(getMethodNode(editor).instructions.get(2) instanceof LabelNode); }
public boolean isCompatible(VarInsnNode varInsnNode) { VarCode varCode; if (AsmUtils.isLoadCode(varInsnNode.getOpcode())) { if (AsmUtils.isLoadCode(this.getOpcode())) { return false; } return ((StoreCode) this).isCompatible(new LoadCode(varInsnNode)); } else if (AsmUtils.isStoreCode(varInsnNode.getOpcode())) { if (AsmUtils.isStoreCode(this.getOpcode())) { return false; } return ((LoadCode) this).isCompatible(new StoreCode(varInsnNode)); } else { throw new AnalyzeError("Unexpected VarInsnNode Opcode!"); } }
private void transformAddPrefix(ClassNode cnode) { ObfMapping mapping = new ObfMapping("net/minecraftforge/fml/common/registry/GameData", "addPrefix", "(Ljava/lang/String;)Ljava/lang/String;"); MethodNode method = ASMHelper.findMethod(mapping, cnode); if (method == null) { throw new IllegalStateException("[NOVA] Lookup " + mapping + " failed!"); } Game.logger().info("Transforming method {}", method.name); @SuppressWarnings("unchecked") JumpInsnNode prev = (JumpInsnNode) method.instructions.get(49); InsnList list = new InsnList(); list.add(new VarInsnNode(ALOAD, 4)); list.add(new MethodInsnNode(INVOKESTATIC, "nova/core/wrapper/mc/forge/v18/asm/StaticForwarder", "isNovaPrefix", "(Ljava/lang/String;)Z", false)); list.add(new JumpInsnNode(IFNE, prev.label)); method.instructions.insert(prev, list); Game.logger().info("Injected instruction to method: {}", method.name); }
public static boolean insnEqual(AbstractInsnNode node1, AbstractInsnNode node2) { if (node1.getOpcode() != node2.getOpcode()) { return false; } switch (node2.getType()) { case VAR_INSN: return varInsnEqual((VarInsnNode) node1, (VarInsnNode) node2); case TYPE_INSN: return typeInsnEqual((TypeInsnNode) node1, (TypeInsnNode) node2); case FIELD_INSN: return fieldInsnEqual((FieldInsnNode) node1, (FieldInsnNode) node2); case METHOD_INSN: return methodInsnEqual((MethodInsnNode) node1, (MethodInsnNode) node2); case LDC_INSN: return ldcInsnEqual((LdcInsnNode) node1, (LdcInsnNode) node2); case IINC_INSN: return iincInsnEqual((IincInsnNode) node1, (IincInsnNode) node2); case INT_INSN: return intInsnEqual((IntInsnNode) node1, (IntInsnNode) node2); default: return true; } }
private void hookSendMessage(ClassNode cn) { Pattern p = new PatternBuilder() .add(new InstructionElement(INVOKESTATIC), new AnyElement(), new LdcElement(new LdcInsnNode("Chat")), new InstructionElement(INVOKEVIRTUAL), new InstructionElement(POP)) .build(); for (MethodNode mn : cn.methods) { if (!p.contains(mn.instructions)) continue; int offset = p.getOffset(mn.instructions) - 9; // steal JumpInsnNode jin = (JumpInsnNode) mn.instructions.get(offset - 1); InsnList inject = new InsnList(); inject.add(new VarInsnNode(ALOAD, 2)); inject.add(new MethodInsnNode(INVOKESTATIC, "me/themallard/bitmmo/impl/plugin/chathook/ChatHookManager", "onChatMessage", "(Ljava/lang/String;)Z", false)); inject.add(new JumpInsnNode(IFNE, jin.label)); // inject.add(new InsnNode(POP)); mn.instructions.insertBefore(mn.instructions.get(offset), inject); } }
/*** * * * @param fn * @param inst * @param dsi */ private void writeValue(String owner, FieldNode fn, InsnList inst, PdxSItem dsi) { String desc = new StringBuffer("(Ljava/lang/String;").append(fn.desc) .append(")Lcom/gemstone/gemfire/pdx/PdxWriter;").toString(); inst.add(new VarInsnNode(ALOAD, 1)); inst.add(new LdcInsnNode(fn.name)); inst.add(new VarInsnNode(ALOAD, 0)); inst.add(new FieldInsnNode(GETFIELD, owner, fn.name, fn.desc)); // add INVOKEVIRTUAL method if (PdxConstants.TYPE_BYTECODE_BYTE_B.equals(fn.desc)) // data type ->byte inst.add(AsmHelper.newMethodInsnNode(INVOKEVIRTUAL, PdxConstants.TYPE_BYTECODE_BYTE, "byteValue", fn.desc, false)); else if (PdxConstants.TYPE_BYTECODE_BOOL_Z.equals(fn.desc)) // data type -> // boolean inst.add(AsmHelper.newMethodInsnNode(INVOKEVIRTUAL, PdxConstants.TYPE_BYTECODE_BOOL, "booleanValue", fn.desc, false)); inst.add(AsmHelper.newMethodInsnNode(INVOKEINTERFACE, PdxConstants.PDX_WRITER_VALUE, dsi.toMethod, desc, true)); inst.add(new InsnNode(POP)); }
@Test public void insertMultipleNodesInEmptyMethod() { MethodNode mthdNode = new MethodNode(); MethodEditor editor = createMethodEditor(mthdNode); editor.setInsertMode(); boolean result = editor.apply(editor.newInstructionBuilder() .varInsn(VarInsnOpcodes.ALOAD, 0) .methodInsn(MethodInsnOpcodes.INVOKEVIRTUAL, "A", "A.a", "()J")); assertEquals(true, result); assertEquals(2, editor.getCursor()); assertEquals(2, getMethodNode(editor).instructions.size()); assertTrue(getMethodNode(editor).instructions.get(0) instanceof VarInsnNode); assertTrue(getMethodNode(editor).instructions.get(1) instanceof MethodInsnNode); }
private void addMapperValueMethod(ClassNode domain, ClassNode mapper) { if (DomainMojoHelper.log().isDebugEnabled()) DomainMojoHelper.log().debug("Add mapperValue(IDataSource)V method..."); MethodNode mn = new MethodNode(ACC_PUBLIC, "mapperValue", "(Lgemlite/core/internal/domain/IDataSource;)L" + domain.name + ";", null, null); InsnList insn = mn.instructions; insn.add(new TypeInsnNode(NEW, domain.name)); insn.add(new InsnNode(DUP)); insn.add(AsmHelper.newMethodInsnNode(INVOKESPECIAL, domain.name, "<init>", "()V", false)); insn.add(new VarInsnNode(ASTORE, 2)); insn.add(new VarInsnNode(ALOAD, 0)); insn.add(new VarInsnNode(ALOAD, 1)); insn.add(new VarInsnNode(ALOAD, 2)); insn.add(AsmHelper.newMethodInsnNode(INVOKEVIRTUAL, mapper.name, "mapperValue", "(Lgemlite/core/internal/domain/IDataSource;L" + domain.name + ";)L" + domain.name + ";", false)); insn.add(new InsnNode(POP)); insn.add(new VarInsnNode(ALOAD, 2)); insn.add(new InsnNode(ARETURN)); mapper.methods.add(mn); if (DomainMojoHelper.log().isDebugEnabled()) DomainMojoHelper.log().debug("Add mapperValue(IDataSource)V method done."); }
private void addValue2KeySimple(ClassNode domain, ClassNode mapper, FieldNode key) { if (DomainMojoHelper.log().isDebugEnabled()) DomainMojoHelper.log().debug("Add value2key(V)K method, key field:" + key.name); String s1 = key.name.substring(0, 1); String s2 = key.name.substring(1); String getMethod = "get" + s1.toUpperCase() + s2; String fullDesc = AsmHelper.toFullName(key.desc); MethodNode mn = new MethodNode(ACC_PUBLIC, "value2Key", "(L" + domain.name + ";)" + fullDesc, null, null); InsnList insn = mn.instructions; insn.add(new VarInsnNode(ALOAD, 1)); insn.add(AsmHelper.newMethodInsnNode(INVOKEVIRTUAL, domain.name, getMethod, "()" + key.desc, false)); AsmHelper.addTypeConvert(insn, key.desc); insn.add(new InsnNode(ARETURN)); mapper.methods.add(mn); if (DomainMojoHelper.log().isDebugEnabled()) DomainMojoHelper.log().debug("Add value2key(V)K method, key field:" + key.name + " done."); }
private void addInvocationStartedHook(int implVarIndex, LabelNode labelNode) { if ((access & ACC_STATIC) == 0) { instructions.insertBefore(labelNode, new VarInsnNode(ALOAD, implVarIndex)); instructions.insertBefore(labelNode, new VarInsnNode(ALOAD, 0)); instructions.insertBefore(labelNode, new LdcInsnNode(name)); instructions.insertBefore(labelNode, new LdcInsnNode(desc)); instructions.insertBefore(labelNode, new MethodInsnNode(INVOKEVIRTUAL, "org/jephyr/continuation/easyflow/ContinuationImpl", "invocationStarted", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V", false)); } else { instructions.insertBefore(labelNode, new VarInsnNode(ALOAD, implVarIndex)); instructions.insertBefore(labelNode, new LdcInsnNode(Type.getType('L' + owner + ';'))); instructions.insertBefore(labelNode, new LdcInsnNode(name)); instructions.insertBefore(labelNode, new LdcInsnNode(desc)); instructions.insertBefore(labelNode, new MethodInsnNode(INVOKEVIRTUAL, "org/jephyr/continuation/easyflow/ContinuationImpl", "staticInvocationStarted", "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)V", false)); } updateMaxStack(4); }
private void injectProcessInterceptor( MethodNode method, String parent, String realName, String methodParam ) { SpaceCoreLog.fine( "Injecting at beginning of method...." ); String realParent = ObfuscationUtils.asmify( parent ); String realClass = ObfuscationUtils.asmify( realName ); InsnList instructions = new InsnList(); instructions.add( new VarInsnNode( ALOAD, 1 ) ); instructions.add( new VarInsnNode( ALOAD, 0 ) ); instructions.add( new TypeInsnNode( CHECKCAST, realParent ) ); instructions.add( new MethodInsnNode( INVOKESTATIC, "com/spacechase0/minecraft/spacecore/network/PacketInterceptor", "intercept", "(L" + methodParam + ";L" + realParent + ";)V" ) ); //System.out.println( methodParam+" "+realClass ); method.instructions.insertBefore( method.instructions.get( 0 ), instructions ); }
private void injectSendInterceptor( MethodNode method, String parent, String methodParam ) { SpaceCoreLog.fine( "Injecting at beginning of method...." ); String realParent = ObfuscationUtils.asmify( parent ); //String realClass = ObfuscationUtils.asmify( realName ); InsnList instructions = new InsnList(); instructions.add( new VarInsnNode( ALOAD, 0 ) ); instructions.add( new VarInsnNode( ALOAD, 1 ) ); instructions.add( new TypeInsnNode( CHECKCAST, realParent ) ); instructions.add( new MethodInsnNode( INVOKESTATIC, "com/spacechase0/minecraft/spacecore/network/PacketInterceptor", "intercept", "(L" + realParent + ";L" + methodParam + ";)V" ) ); //System.out.println( methodParam+" "+realClass ); method.instructions.insertBefore( method.instructions.get( 0 ), instructions ); }
private int addMethodParametersVariable(InsnList il) { il.add(TreeInstructions.getPushInstruction(this.methodArguments.length)); il.add(new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Object")); int methodParametersIndex = getFistAvailablePosition(); il.add(new VarInsnNode(Opcodes.ASTORE, methodParametersIndex)); this.mn.maxLocals++; for (int i = 0; i < this.methodArguments.length; i++) { il.add(new VarInsnNode(Opcodes.ALOAD, methodParametersIndex)); il.add(TreeInstructions.getPushInstruction(i)); il.add(TreeInstructions.getLoadInst(methodArguments[i], getArgumentPosition(i))); MethodInsnNode mNode = TreeInstructions .getWrapperContructionInst(methodArguments[i]); if (mNode != null) { il.add(mNode); } il.add(new InsnNode(Opcodes.AASTORE)); } return methodParametersIndex; }