List of usage examples for org.objectweb.asm Opcodes ALOAD
int ALOAD
To view the source code for org.objectweb.asm Opcodes ALOAD.
Click Source Link
From source file:Client.JClassPatcher.java
License:Open Source License
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); }//from www.j a v a 2 s .c o m } }
From source file:Client.JClassPatcher.java
License:Open Source License
private void patchApplet(ClassNode node) { Logger.Info("Patching applet (" + node.name + ".class)"); Iterator<MethodNode> methodNodeList = node.methods.iterator(); while (methodNodeList.hasNext()) { MethodNode methodNode = methodNodeList.next(); if (methodNode.name.equals("run") && methodNode.desc.equals("()V")) { // Mouse and keyboard listener hooks AbstractInsnNode findNode = methodNode.instructions.getFirst(); for (;;) { AbstractInsnNode next = findNode.getNext(); if (next == null) break; if (findNode.getOpcode() == Opcodes.ALOAD && next.getOpcode() == Opcodes.ALOAD) { AbstractInsnNode invokeNode = next.getNext(); MethodInsnNode invoke = (MethodInsnNode) invokeNode; methodNode.instructions.remove(next); methodNode.instructions.remove(invokeNode); if (invoke.name.equals("addMouseListener")) methodNode.instructions.insert(findNode, new FieldInsnNode(Opcodes.PUTSTATIC, "Game/MouseHandler", "listener_mouse", "Ljava/awt/event/MouseListener;")); else if (invoke.name.equals("addMouseMotionListener")) methodNode.instructions.insert(findNode, new FieldInsnNode(Opcodes.PUTSTATIC, "Game/MouseHandler", "listener_mouse_motion", "Ljava/awt/event/MouseMotionListener;")); else if (invoke.name.equals("addKeyListener")) methodNode.instructions.insert(findNode, new FieldInsnNode(Opcodes.PUTSTATIC, "Game/KeyboardHandler", "listener_key", "Ljava/awt/event/KeyListener;")); }// w w w . j av a2 s .c o m findNode = findNode.getNext(); } } } }
From source file:Client.JClassPatcher.java
License:Open Source License
private void patchClient(ClassNode node) { Logger.Info("Patching client (" + node.name + ".class)"); Iterator<MethodNode> methodNodeList = node.methods.iterator(); while (methodNodeList.hasNext()) { MethodNode methodNode = methodNodeList.next(); // I (I)V is where most of the interface is processed if (methodNode.name.equals("I") && methodNode.desc.equals("(I)V")) { // Show combat menu Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator(); while (insnNodeList.hasNext()) { AbstractInsnNode insnNode = insnNodeList.next(); if (insnNode.getOpcode() == Opcodes.BIPUSH) { IntInsnNode bipush = (IntInsnNode) insnNode; if (bipush.operand == -9) { AbstractInsnNode findNode = insnNode; while (findNode.getOpcode() != Opcodes.IF_ICMPEQ) findNode = findNode.getNext(); LabelNode label = ((JumpInsnNode) findNode).label; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Client/Settings", "COMBAT_MENU", "Z")); methodNode.instructions.insertBefore(insnNode, new JumpInsnNode(Opcodes.IFGT, label)); break; }//from w w w . j a v a2 s . co m } } } else if (methodNode.name.equals("J") && methodNode.desc.equals("(I)V")) { Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator(); while (insnNodeList.hasNext()) { AbstractInsnNode insnNode = insnNodeList.next(); // Chat command patch if (insnNode.getOpcode() == Opcodes.SIPUSH) { IntInsnNode call = (IntInsnNode) insnNode; if (call.operand == 627) { AbstractInsnNode jmpNode = insnNode; while (jmpNode.getOpcode() != Opcodes.IFEQ) jmpNode = jmpNode.getNext(); AbstractInsnNode insertNode = insnNode; while (insertNode.getOpcode() != Opcodes.INVOKEVIRTUAL) insertNode = insertNode.getPrevious(); JumpInsnNode jmp = (JumpInsnNode) jmpNode; methodNode.instructions.insert(insertNode, new VarInsnNode(Opcodes.ASTORE, 2)); methodNode.instructions.insert(insertNode, new MethodInsnNode(Opcodes.INVOKESTATIC, "Game/Client", "processChatCommand", "(Ljava/lang/String;)Ljava/lang/String;")); methodNode.instructions.insert(insertNode, new VarInsnNode(Opcodes.ALOAD, 2)); } } } } else if (methodNode.name.equals("h") && methodNode.desc.equals("(B)V")) { Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator(); while (insnNodeList.hasNext()) { AbstractInsnNode insnNode = insnNodeList.next(); // Private chat command patch if (insnNode.getOpcode() == Opcodes.GETFIELD) { FieldInsnNode field = (FieldInsnNode) insnNode; if (field.owner.equals("client") && field.name.equals("Ob") && insnNode.getPrevious().getPrevious().getOpcode() != Opcodes.INVOKEVIRTUAL) { insnNode = insnNode.getPrevious().getPrevious(); methodNode.instructions.insert(insnNode, new FieldInsnNode(Opcodes.PUTFIELD, "client", "Ob", "Ljava/lang/String;")); methodNode.instructions.insert(insnNode, new MethodInsnNode(Opcodes.INVOKESTATIC, "Game/Client", "processPrivateCommand", "(Ljava/lang/String;)Ljava/lang/String;")); methodNode.instructions.insert(insnNode, new FieldInsnNode(Opcodes.GETFIELD, "client", "Ob", "Ljava/lang/String;")); methodNode.instructions.insert(insnNode, new VarInsnNode(Opcodes.ALOAD, 0)); methodNode.instructions.insert(insnNode, new VarInsnNode(Opcodes.ALOAD, 0)); break; } } } } else if (methodNode.name.equals("a") && methodNode.desc.equals("(IIIIIIII)V")) { // Draw NPC hook AbstractInsnNode insnNode = methodNode.instructions.getLast(); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 8)); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 1)); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 7)); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 4)); methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "e", "Mb", "[Ljava/lang/String;")); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ALOAD, 0)); methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETFIELD, "client", "Tb", "[Lta;")); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 6)); methodNode.instructions.insertBefore(insnNode, new InsnNode(Opcodes.AALOAD)); methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETFIELD, "ta", "t", "I")); methodNode.instructions.insertBefore(insnNode, new InsnNode(Opcodes.AALOAD)); methodNode.instructions.insertBefore(insnNode, new MethodInsnNode(Opcodes.INVOKESTATIC, "Game/Client", "drawNPC", "(IIIILjava/lang/String;)V")); } else if (methodNode.name.equals("b") && methodNode.desc.equals("(IIIIIIII)V")) { // Draw Player hook AbstractInsnNode insnNode = methodNode.instructions.getLast(); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 5)); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 6)); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 2)); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 7)); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ALOAD, 0)); methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETFIELD, "client", "rg", "[Lta;")); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 8)); methodNode.instructions.insertBefore(insnNode, new InsnNode(Opcodes.AALOAD)); methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETFIELD, "ta", "C", "Ljava/lang/String;")); methodNode.instructions.insertBefore(insnNode, new MethodInsnNode(Opcodes.INVOKESTATIC, "Game/Client", "drawPlayer", "(IIIILjava/lang/String;)V")); } else if (methodNode.name.equals("b") && methodNode.desc.equals("(IIIIIII)V")) { // Draw Item hook // ILOAD 4 is item id AbstractInsnNode insnNode = methodNode.instructions.getLast(); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 3)); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 7)); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 5)); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 1)); methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ILOAD, 4)); methodNode.instructions.insertBefore(insnNode, new MethodInsnNode(Opcodes.INVOKESTATIC, "Game/Client", "drawItem", "(IIIII)V")); } else if (methodNode.name.equals("L") && methodNode.desc.equals("(I)V")) { Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator(); while (insnNodeList.hasNext()) { AbstractInsnNode insnNode = insnNodeList.next(); // Right click bounds fix if (insnNode.getOpcode() == Opcodes.SIPUSH) { IntInsnNode call = (IntInsnNode) insnNode; AbstractInsnNode nextNode = insnNode.getNext(); if (call.operand == 510) { call.operand = 512 - call.operand; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "width", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.ISUB)); } else if (call.operand == 315) { call.operand = 334 - call.operand; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "height_client", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.ISUB)); } else if (call.operand == -316) { call.operand = 334 - (call.operand * -1); methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "height_client", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.INEG)); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.ISUB)); } } } } else if (methodNode.name.equals("a") && methodNode.desc.equals("(ZZ)V")) { Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator(); while (insnNodeList.hasNext()) { AbstractInsnNode insnNode = insnNodeList.next(); // Friends chat mouse fix if (insnNode.getOpcode() == Opcodes.SIPUSH) { IntInsnNode call = (IntInsnNode) insnNode; if (call.operand == 489 || call.operand == 429) { call.operand = 512 - call.operand; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "width", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.ISUB)); } if (call.operand == -430) { call.operand = 512 - (call.operand * -1); methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "width", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.INEG)); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.ISUB)); } } } } else if (methodNode.name.equals("i") && methodNode.desc.equals("(I)V")) { AbstractInsnNode lastNode = methodNode.instructions.getLast().getPrevious(); // Send combat style option LabelNode label = new LabelNode(); methodNode.instructions.insert(lastNode, label); // Format methodNode.instructions.insert(lastNode, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "da", "b", "(I)V", false)); methodNode.instructions.insert(lastNode, new IntInsnNode(Opcodes.SIPUSH, 21294)); methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETFIELD, "client", "Jh", "Lda;")); methodNode.instructions.insert(lastNode, new VarInsnNode(Opcodes.ALOAD, 0)); // Write byte methodNode.instructions.insert(lastNode, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "ja", "c", "(II)V", false)); methodNode.instructions.insert(lastNode, new IntInsnNode(Opcodes.BIPUSH, -80)); methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETSTATIC, "Client/Settings", "COMBAT_STYLE", "I")); methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETFIELD, "da", "f", "Lja;")); methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETFIELD, "client", "Jh", "Lda;")); methodNode.instructions.insert(lastNode, new VarInsnNode(Opcodes.ALOAD, 0)); // Create Packet methodNode.instructions.insert(lastNode, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "da", "b", "(II)V", false)); methodNode.instructions.insert(lastNode, new InsnNode(Opcodes.ICONST_0)); methodNode.instructions.insert(lastNode, new IntInsnNode(Opcodes.BIPUSH, 29)); methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETFIELD, "client", "Jh", "Lda;")); methodNode.instructions.insert(lastNode, new VarInsnNode(Opcodes.ALOAD, 0)); // Skip combat packet if style is already controlled methodNode.instructions.insert(lastNode, new JumpInsnNode(Opcodes.IF_ICMPLE, label)); methodNode.instructions.insert(lastNode, new InsnNode(Opcodes.ICONST_0)); methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETSTATIC, "Client/Settings", "COMBAT_STYLE", "I")); // Client init_game methodNode.instructions.insert(lastNode, new MethodInsnNode(Opcodes.INVOKESTATIC, "Game/Client", "init_game", "()V", false)); } else if (methodNode.name.equals("o") && methodNode.desc.equals("(I)V")) { // Client.init_login patch AbstractInsnNode findNode = methodNode.instructions.getLast(); methodNode.instructions.insertBefore(findNode, new MethodInsnNode(Opcodes.INVOKESTATIC, "Game/Client", "init_login", "()V", false)); } else if (methodNode.name.equals("a") && methodNode.desc.equals("(B)V")) { Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator(); while (insnNodeList.hasNext()) { AbstractInsnNode insnNode = insnNodeList.next(); // Camera view distance crash fix if (insnNode.getOpcode() == Opcodes.SIPUSH) { IntInsnNode call = (IntInsnNode) insnNode; if (call.operand == 15000) { call.operand = 32767; } } } // Client.init patch AbstractInsnNode findNode = methodNode.instructions.getFirst(); methodNode.instructions.insertBefore(findNode, new VarInsnNode(Opcodes.ALOAD, 0)); methodNode.instructions.insertBefore(findNode, new FieldInsnNode(Opcodes.PUTSTATIC, "Game/Client", "instance", "Ljava/lang/Object;")); methodNode.instructions.insertBefore(findNode, new MethodInsnNode(Opcodes.INVOKESTATIC, "Game/Client", "init", "()V", false)); } else if (methodNode.name.equals("G") && methodNode.desc.equals("(I)V")) { // TODO: This can be shortened, I'll fix it another time // NPC Dialogue keyboard AbstractInsnNode lastNode = methodNode.instructions.getLast().getPrevious(); LabelNode label = new LabelNode(); methodNode.instructions.insert(lastNode, label); // Hide dialogue methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.PUTFIELD, "client", "Ph", "Z")); methodNode.instructions.insert(lastNode, new InsnNode(Opcodes.ICONST_0)); methodNode.instructions.insert(lastNode, new VarInsnNode(Opcodes.ALOAD, 0)); // Format methodNode.instructions.insert(lastNode, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "da", "b", "(I)V", false)); methodNode.instructions.insert(lastNode, new IntInsnNode(Opcodes.SIPUSH, 21294)); methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETFIELD, "client", "Jh", "Lda;")); methodNode.instructions.insert(lastNode, new VarInsnNode(Opcodes.ALOAD, 0)); // Write byte methodNode.instructions.insert(lastNode, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "ja", "c", "(II)V", false)); methodNode.instructions.insert(lastNode, new IntInsnNode(Opcodes.BIPUSH, 115)); methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/KeyboardHandler", "dialogue_option", "I")); methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETFIELD, "da", "f", "Lja;")); methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETFIELD, "client", "Jh", "Lda;")); methodNode.instructions.insert(lastNode, new VarInsnNode(Opcodes.ALOAD, 0)); // Create Packet methodNode.instructions.insert(lastNode, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "da", "b", "(II)V", false)); methodNode.instructions.insert(lastNode, new InsnNode(Opcodes.ICONST_0)); methodNode.instructions.insert(lastNode, new IntInsnNode(Opcodes.BIPUSH, 116)); methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETFIELD, "client", "Jh", "Lda;")); methodNode.instructions.insert(lastNode, new VarInsnNode(Opcodes.ALOAD, 0)); // Check if dialogue option is pressed methodNode.instructions.insert(lastNode, new JumpInsnNode(Opcodes.IF_ICMPGE, label)); // Menu option count methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETFIELD, "client", "Id", "I")); methodNode.instructions.insert(lastNode, new VarInsnNode(Opcodes.ALOAD, 0)); methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/KeyboardHandler", "dialogue_option", "I")); methodNode.instructions.insert(lastNode, new JumpInsnNode(Opcodes.IFLT, label)); methodNode.instructions.insert(lastNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/KeyboardHandler", "dialogue_option", "I")); } else if (methodNode.name.equals("f") && methodNode.desc.equals("(I)V")) { Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator(); while (insnNodeList.hasNext()) { AbstractInsnNode insnNode = insnNodeList.next(); // Hide Roof option if (insnNode.getOpcode() == Opcodes.GETFIELD) { FieldInsnNode field = (FieldInsnNode) insnNode; if (field.owner.equals("client") && field.name.equals("yj")) { AbstractInsnNode nextNode = insnNode.getNext(); if (nextNode.getOpcode() == Opcodes.IFNE) { LabelNode label = ((JumpInsnNode) nextNode).label; methodNode.instructions.insert(nextNode, new JumpInsnNode(Opcodes.IFGT, label)); methodNode.instructions.insert(nextNode, new FieldInsnNode(Opcodes.GETSTATIC, "Client/Settings", "HIDE_ROOFS", "Z")); } } } // Move wilderness skull if (insnNode.getOpcode() == Opcodes.SIPUSH) { IntInsnNode call = (IntInsnNode) insnNode; if (call.operand == 465 || call.operand == 453) { call.operand = 512 - call.operand; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "width", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.ISUB)); } } } } else if (methodNode.name.equals("a") && methodNode.desc.equals("(IIZ)Z")) { Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator(); while (insnNodeList.hasNext()) { AbstractInsnNode insnNode = insnNodeList.next(); // Move the load screen text dialogue if (insnNode.getOpcode() == Opcodes.SIPUSH) { IntInsnNode call = (IntInsnNode) insnNode; if (call.operand == 256) { call.operand = 2; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "width", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IDIV)); } else if (call.operand == 192) { call.operand = 2; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "height", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IADD)); methodNode.instructions.insert(insnNode, new IntInsnNode(Opcodes.SIPUSH, 19)); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IDIV)); } } } } else if (methodNode.name.equals("d") && methodNode.desc.equals("(B)V")) { Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator(); while (insnNodeList.hasNext()) { AbstractInsnNode insnNode = insnNodeList.next(); // Center logout dialogue if (insnNode.getOpcode() == Opcodes.SIPUSH || insnNode.getOpcode() == Opcodes.BIPUSH) { IntInsnNode call = (IntInsnNode) insnNode; if (call.operand == 256) { call.operand = 2; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "width", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IDIV)); } else if (call.operand == 173) { call.operand = 2; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "height", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IDIV)); } else if (call.operand == 126) { call.operand = 2; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "width", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.ISUB)); methodNode.instructions.insert(insnNode, new IntInsnNode(Opcodes.SIPUSH, 130)); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IDIV)); } else if (call.operand == 137) { call.operand = 2; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "height", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.ISUB)); methodNode.instructions.insert(insnNode, new IntInsnNode(Opcodes.SIPUSH, 36)); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IDIV)); } } } } else if (methodNode.name.equals("j") && methodNode.desc.equals("(I)V")) { Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator(); while (insnNodeList.hasNext()) { AbstractInsnNode insnNode = insnNodeList.next(); // Center welcome box if (insnNode.getOpcode() == Opcodes.SIPUSH || insnNode.getOpcode() == Opcodes.BIPUSH) { IntInsnNode call = (IntInsnNode) insnNode; if (call.operand == 256) { call.operand = 2; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "width", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IDIV)); } else if (call.operand == 167) { call.operand = 2; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "height", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.ISUB)); methodNode.instructions.insert(insnNode, new IntInsnNode(Opcodes.SIPUSH, 6)); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IDIV)); } else if (call.operand == 56) { call.operand = 2; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "width", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.ISUB)); methodNode.instructions.insert(insnNode, new IntInsnNode(Opcodes.SIPUSH, 200)); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IDIV)); } else if (call.operand == -87) { call.operand = 2; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "width", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.INEG)); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.ISUB)); methodNode.instructions.insert(insnNode, new IntInsnNode(Opcodes.SIPUSH, 169)); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IDIV)); } else if (call.operand == 426) { call.operand = 2; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "width", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IADD)); methodNode.instructions.insert(insnNode, new IntInsnNode(Opcodes.SIPUSH, 170)); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IDIV)); } else if (call.operand == 106) { call.operand = 2; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "width", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.ISUB)); methodNode.instructions.insert(insnNode, new IntInsnNode(Opcodes.SIPUSH, 150)); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IDIV)); } else if (call.operand == 406) { call.operand = 2; methodNode.instructions.insertBefore(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, "Game/Renderer", "width", "I")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IADD)); methodNode.instructions.insert(insnNode, new IntInsnNode(Opcodes.SIPUSH, 150)); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.IDIV)); } } } } else if (methodNode.name.equals("k") && methodNode.desc.equals("(B)V")) { Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator(); while (insnNodeList.hasNext()) { AbstractInsnNode insnNode = insnNodeList.next(); // Save settings from combat menu if (insnNode.getOpcode() == Opcodes.PUTFIELD) { FieldInsnNode field = (FieldInsnNode) insnNode; if (field.owner.equals("client") && field.name.equals("Fg")) { methodNode.instructions.insert(insnNode, new MethodInsnNode(Opcodes.INVOKESTATIC, "Client/Settings", "save", "()V", false)); methodNode.instructions.insert(insnNode, new FieldInsnNode(Opcodes.PUTSTATIC, "Client/Settings", "COMBAT_STYLE", "I")); methodNode.instructions.insert(insnNode, new FieldInsnNode(Opcodes.GETFIELD, "client", "Fg", "I")); methodNode.instructions.insert(insnNode, new VarInsnNode(Opcodes.ALOAD, 0)); } } } } else if (methodNode.name.equals("a") && methodNode.desc .equals("(ZLjava/lang/String;ILjava/lang/String;IILjava/lang/String;Ljava/lang/String;)V")) { AbstractInsnNode first = methodNode.instructions.getFirst(); methodNode.instructions.insertBefore(first, new VarInsnNode(Opcodes.ALOAD, 7)); methodNode.instructions.insertBefore(first, new VarInsnNode(Opcodes.ALOAD, 4)); methodNode.instructions.insertBefore(first, new VarInsnNode(Opcodes.ILOAD, 5)); methodNode.instructions.insertBefore(first, new MethodInsnNode(Opcodes.INVOKESTATIC, "Game/Client", "messageHook", "(Ljava/lang/String;Ljava/lang/String;I)V")); } } }
From source file:Client.JClassPatcher.java
License:Open Source License
private void patchRenderer(ClassNode node) { Logger.Info("Patching renderer (" + node.name + ".class)"); Iterator<MethodNode> methodNodeList = node.methods.iterator(); while (methodNodeList.hasNext()) { MethodNode methodNode = methodNodeList.next(); // Renderer present hook if (methodNode.desc.equals("(Ljava/awt/Graphics;III)V")) { AbstractInsnNode findNode = methodNode.instructions.getFirst(); FieldInsnNode imageNode = null; while (findNode.getOpcode() != Opcodes.POP) { findNode = findNode.getNext(); if (findNode == null) { Logger.Error("Unable to find present hook"); break; }/* ww w . j ava 2 s.c o m*/ } while (findNode.getOpcode() != Opcodes.INVOKESPECIAL) { if (findNode.getOpcode() == Opcodes.GETFIELD) imageNode = (FieldInsnNode) findNode; AbstractInsnNode prev = findNode.getPrevious(); methodNode.instructions.remove(findNode); findNode = prev; } methodNode.instructions.insert(findNode, new MethodInsnNode(Opcodes.INVOKESTATIC, "Game/Renderer", "present", "(Ljava/awt/Graphics;Ljava/awt/Image;)V", false)); methodNode.instructions.insert(findNode, new FieldInsnNode(Opcodes.GETFIELD, node.name, imageNode.name, imageNode.desc)); methodNode.instructions.insert(findNode, new VarInsnNode(Opcodes.ALOAD, 0)); methodNode.instructions.insert(findNode, new VarInsnNode(Opcodes.ALOAD, 1)); } else if (methodNode.name.equals("a") && methodNode.desc.equals("(IILjava/lang/String;IIBI)V")) { AbstractInsnNode start = methodNode.instructions.getFirst(); while (start != null) { if (start.getOpcode() == Opcodes.ALOAD && start.getNext().getOpcode() == Opcodes.ILOAD && start.getNext().getNext().getOpcode() == Opcodes.INVOKEVIRTUAL && start.getNext().getNext().getNext().getOpcode() == Opcodes.ISTORE) { break; } start = start.getNext(); } start = start.getPrevious(); LabelNode finishLabel = ((JumpInsnNode) start.getPrevious().getPrevious()).label; LabelNode failLabel = new LabelNode(); methodNode.instructions.insertBefore(start, new IntInsnNode(Opcodes.BIPUSH, 126)); methodNode.instructions.insertBefore(start, new VarInsnNode(Opcodes.ALOAD, 3)); methodNode.instructions.insertBefore(start, new VarInsnNode(Opcodes.ILOAD, 10)); methodNode.instructions.insertBefore(start, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C")); methodNode.instructions.insertBefore(start, new JumpInsnNode(Opcodes.IF_ICMPNE, failLabel)); methodNode.instructions.insertBefore(start, new VarInsnNode(Opcodes.ILOAD, 10)); methodNode.instructions.insertBefore(start, new InsnNode(Opcodes.ICONST_5)); methodNode.instructions.insertBefore(start, new InsnNode(Opcodes.IADD)); methodNode.instructions.insertBefore(start, new VarInsnNode(Opcodes.ALOAD, 3)); methodNode.instructions.insertBefore(start, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "length", "()I")); methodNode.instructions.insertBefore(start, new JumpInsnNode(Opcodes.IF_ICMPGE, failLabel)); methodNode.instructions.insertBefore(start, new IntInsnNode(Opcodes.BIPUSH, 126)); methodNode.instructions.insertBefore(start, new VarInsnNode(Opcodes.ALOAD, 3)); methodNode.instructions.insertBefore(start, new VarInsnNode(Opcodes.ILOAD, 10)); methodNode.instructions.insertBefore(start, new InsnNode(Opcodes.ICONST_5)); methodNode.instructions.insertBefore(start, new InsnNode(Opcodes.IADD)); methodNode.instructions.insertBefore(start, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C")); methodNode.instructions.insertBefore(start, new JumpInsnNode(Opcodes.IF_ICMPNE, failLabel)); methodNode.instructions.insertBefore(start, new VarInsnNode(Opcodes.ALOAD, 3)); methodNode.instructions.insertBefore(start, new VarInsnNode(Opcodes.ILOAD, 10)); methodNode.instructions.insertBefore(start, new InsnNode(Opcodes.ICONST_1)); methodNode.instructions.insertBefore(start, new InsnNode(Opcodes.IADD)); methodNode.instructions.insertBefore(start, new VarInsnNode(Opcodes.ILOAD, 10)); methodNode.instructions.insertBefore(start, new InsnNode(Opcodes.ICONST_5)); methodNode.instructions.insertBefore(start, new InsnNode(Opcodes.IADD)); methodNode.instructions.insertBefore(start, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "substring", "(II)Ljava/lang/String;")); methodNode.instructions.insertBefore(start, new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Integer", "parseInt", "(Ljava/lang/String;)I")); methodNode.instructions.insertBefore(start, new VarInsnNode(Opcodes.ISTORE, 4)); methodNode.instructions.insertBefore(start, new IincInsnNode(10, 5)); methodNode.instructions.insertBefore(start, new JumpInsnNode(Opcodes.GOTO, finishLabel)); methodNode.instructions.insertBefore(start, failLabel); } } }
From source file:Client.JClassPatcher.java
License:Open Source License
private void patchRandom(ClassNode node) { Logger.Info("Patching random (" + node.name + ".class)"); Iterator<MethodNode> methodNodeList = node.methods.iterator(); while (methodNodeList.hasNext()) { MethodNode methodNode = methodNodeList.next(); if (methodNode.name.equals("a")) { // System.out.println(methodNode.desc); if (methodNode.desc.equals("(ILtb;)V")) { Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator(); while (insnNodeList.hasNext()) { AbstractInsnNode insnNode = insnNodeList.next(); AbstractInsnNode nextNode = insnNode.getNext(); if (nextNode == null) break; if (insnNode.getOpcode() == Opcodes.ALOAD && nextNode.getOpcode() == Opcodes.ICONST_0) { VarInsnNode call = (VarInsnNode) insnNode; System.out.println("Patching validation..."); methodNode.instructions.insert(insnNode, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/util/Random", "nextBytes", "([B)V")); methodNode.instructions.insert(insnNode, new VarInsnNode(Opcodes.ALOAD, 2)); methodNode.instructions.insert(insnNode, new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/Random", "<init>", "()V")); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.DUP)); methodNode.instructions.insert(insnNode, new TypeInsnNode(Opcodes.NEW, "java/util/Random")); }/*from w w w. ja va 2 s. c o m*/ } } } } }
From source file:cn.annoreg.asm.DelegateGenerator.java
License:Open Source License
public static MethodVisitor generateStaticMethod(ClassVisitor parentClass, MethodVisitor parent, String className, String methodName, String desc, final Side side) { //This method is a little bit complicated. //We need to generate a delegate class implementing NetworkCallDelegate and a redirect //the code that originally generated here in parent, into the delegate class, //by returning a MethodVisitor under the ClassVisitor of the delegate class. //Besides, we should generate a call to NetworkCallManager into parent. //Above is the original method. Now it has a little bit change. To allow private call in //here, we need to generate the delegate method in this class instead of in a delegate class. //We make the delegate method public so that the delegate class can call it. //delegateName is a string used by both sides to identify a network-call delegate. final String delegateName = className + ":" + methodName + ":" + desc; final Type[] args = Type.getArgumentTypes(desc); final Type ret = Type.getReturnType(desc); //Check types for (Type t : args) { //TODO support these types if (!t.getDescriptor().startsWith("L") && !t.getDescriptor().startsWith("[")) { throw new RuntimeException("Unsupported argument type in network call. in method " + methodName + ", " + t.getDescriptor()); }/*from w w w . java 2 s . c o m*/ } if (!ret.equals(Type.VOID_TYPE)) { throw new RuntimeException( "Unsupported return value type in network call. " + "Only void is supported."); } //Generate call to NetworkCallManager in parent. parent.visitCode(); //First parameter parent.visitLdcInsn(delegateName); //Second parameter: object array pushIntegerConst(parent, args.length); //array size parent.visitTypeInsn(Opcodes.ANEWARRAY, Type.getInternalName(Object.class)); for (int i = 0; i < args.length; ++i) { parent.visitInsn(Opcodes.DUP); pushIntegerConst(parent, i); parent.visitVarInsn(Opcodes.ALOAD, i); parent.visitInsn(Opcodes.AASTORE); } //Call cn.annoreg.mc.network.NetworkCallManager.onNetworkCall parent.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(NetworkCallManager.class), "onNetworkCall", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class), Type.getType(Object[].class))); parent.visitInsn(Opcodes.RETURN); parent.visitMaxs(5, args.length); parent.visitEnd(); //Create delegate object. final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); final String delegateId = Integer.toString(delegateNextID++); final Type delegateClassType = Type.getType("cn/annoreg/asm/NetworkCallDelegate_" + delegateId); cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, delegateClassType.getInternalName(), null, Type.getInternalName(Object.class), new String[] { Type.getInternalName(NetworkCallDelegate.class) }); //package cn.annoreg.asm; //class NetworkCallDelegate_? implements NetworkCallDelegate { { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } //public NetworkCallDelegate_?() {} final String delegateFunctionName = methodName + "_delegate_" + delegateId; { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object[].class)), null, null); mv.visitCode(); for (int i = 0; i < args.length; ++i) { mv.visitVarInsn(Opcodes.ALOAD, 1); //0 is this pushIntegerConst(mv, i); mv.visitInsn(Opcodes.AALOAD); mv.visitTypeInsn(Opcodes.CHECKCAST, args[i].getInternalName()); } mv.visitMethodInsn(Opcodes.INVOKESTATIC, //delegateClassType.getInternalName(), //changed to original class className.replace('.', '/'), delegateFunctionName, desc); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(args.length + 2, 2); mv.visitEnd(); } //@Override public void invoke(Object[] args) { // xxxx.xxxx_delegated_xxx((Type0) args[0], (Type1) args[1], ...); //} //The returned MethodVisitor will visit the original version of the method, //including its annotation, where we can get StorageOptions. return new MethodVisitor(Opcodes.ASM4, parentClass.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, delegateFunctionName, desc, null, null)) { //Remember storage options for each argument StorageOption.Option[] options = new StorageOption.Option[args.length]; int targetIndex = -1; StorageOption.Target.RangeOption range = StorageOption.Target.RangeOption.SINGLE; double sendRange = -1; { for (int i = 0; i < options.length; ++i) { options[i] = StorageOption.Option.NULL; //set default value } } @Override public AnnotationVisitor visitParameterAnnotation(final int parameter, String desc, boolean visible) { Type type = Type.getType(desc); if (type.equals(Type.getType(StorageOption.Data.class))) { options[parameter] = StorageOption.Option.DATA; } else if (type.equals(Type.getType(StorageOption.Instance.class))) { //INSTANCE as defualt options[parameter] = StorageOption.Option.INSTANCE; //Change to NULLABLE_INSTANCE if nullable set to true return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { if (name.equals("nullable")) { if ((Boolean) value == true) { options[parameter] = StorageOption.Option.NULLABLE_INSTANCE; } } super.visit(name, value); } }; } else if (type.equals(Type.getType(StorageOption.Update.class))) { options[parameter] = StorageOption.Option.UPDATE; } else if (type.equals(Type.getType(StorageOption.Null.class))) { options[parameter] = StorageOption.Option.NULL; } else if (type.equals(Type.getType(StorageOption.Target.class))) { if (!args[parameter].equals(Type.getType(EntityPlayer.class))) { throw new RuntimeException("Target annotation can only be used on EntityPlayer."); } if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } options[parameter] = StorageOption.Option.INSTANCE; targetIndex = parameter; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visitEnum(String name, String desc, String value) { super.visitEnum(name, desc, value); range = StorageOption.Target.RangeOption.valueOf(value); } }; } else if (type.equals(Type.getType(StorageOption.RangedTarget.class))) { if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } range = null; targetIndex = parameter; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { super.visit(name, value); sendRange = (double) value; } }; } return super.visitParameterAnnotation(parameter, desc, visible); } @Override public void visitEnd() { super.visitEnd(); //This is the last method in the delegate class. //Finish the class and do the registration. cw.visitEnd(); try { Class<?> clazz = classLoader.defineClass(delegateClassType.getClassName(), cw.toByteArray()); NetworkCallDelegate delegateObj = (NetworkCallDelegate) clazz.newInstance(); if (side == Side.CLIENT) { NetworkCallManager.registerClientDelegateClass(delegateName, delegateObj, options, targetIndex, range, sendRange); } else { NetworkCallManager.registerServerDelegateClass(delegateName, delegateObj, options); } } catch (Throwable e) { throw new RuntimeException("Can not create delegate for network call.", e); } } }; //public static void delegated(Type0 arg0, Type1, arg1, ...) { // //Code generated by caller. //} //} }
From source file:cn.annoreg.asm.DelegateGenerator.java
License:Open Source License
public static MethodVisitor generateNonStaticMethod(ClassVisitor parentClass, MethodVisitor parent, String className, String methodName, String desc, final Side side) { //convert desc to a non-static method form String nonstaticDesc;/* ww w . j av a2s . c o m*/ { Type staticType = Type.getMethodType(desc); Type retType = staticType.getReturnType(); Type[] argsType = staticType.getArgumentTypes(); Type[] argsTypeWithThis = new Type[argsType.length + 1]; argsTypeWithThis[0] = Type.getType('L' + className.replace('.', '/') + ';'); System.arraycopy(argsType, 0, argsTypeWithThis, 1, argsType.length); nonstaticDesc = Type.getMethodDescriptor(retType, argsTypeWithThis); } //delegateName is a string used by both sides to identify a network-call delegate. final String delegateName = className + ":" + methodName + ":" + desc; final Type[] args = Type.getArgumentTypes(nonstaticDesc); final Type ret = Type.getReturnType(nonstaticDesc); //Check types for (Type t : args) { //TODO support these types if (!t.getDescriptor().startsWith("L") && !t.getDescriptor().startsWith("[")) { throw new RuntimeException("Unsupported argument type in network call. "); } } if (!ret.equals(Type.VOID_TYPE)) { throw new RuntimeException( "Unsupported return value type in network call. " + "Only void is supported."); } //Generate call to NetworkCallManager in parent. parent.visitCode(); //First parameter parent.visitLdcInsn(delegateName); //Second parameter: object array pushIntegerConst(parent, args.length); //this (0) has been included parent.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); for (int i = 0; i < args.length; ++i) { parent.visitInsn(Opcodes.DUP); pushIntegerConst(parent, i); parent.visitVarInsn(Opcodes.ALOAD, i); parent.visitInsn(Opcodes.AASTORE); } //Call cn.annoreg.mc.network.NetworkCallManager.onNetworkCall parent.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(NetworkCallManager.class), "onNetworkCall", "(Ljava/lang/String;[Ljava/lang/Object;)V"); parent.visitInsn(Opcodes.RETURN); parent.visitMaxs(5, args.length); parent.visitEnd(); //Create delegate object. final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); final String delegateId = Integer.toString(delegateNextID++); final Type delegateClassType = Type.getType("cn/annoreg/asm/NetworkCallDelegate_" + delegateId); cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, delegateClassType.getInternalName(), null, Type.getInternalName(Object.class), new String[] { Type.getInternalName(NetworkCallDelegate.class) }); //package cn.annoreg.asm; //class NetworkCallDelegate_? implements NetworkCallDelegate { { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } //public NetworkCallDelegate_?() {} final String delegateMethodName = methodName + "_delegate_" + delegateId; { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object[].class)), null, null); mv.visitCode(); //check if this is null mv.visitVarInsn(Opcodes.ALOAD, 1); //0 is this pushIntegerConst(mv, 0); mv.visitInsn(Opcodes.AALOAD); Label lblEnd = new Label(); mv.visitJumpInsn(Opcodes.IFNULL, lblEnd); for (int i = 0; i < args.length; ++i) { mv.visitVarInsn(Opcodes.ALOAD, 1); //0 is this pushIntegerConst(mv, i); mv.visitInsn(Opcodes.AALOAD); mv.visitTypeInsn(Opcodes.CHECKCAST, args[i].getInternalName()); } mv.visitMethodInsn(Opcodes.INVOKESTATIC, //delegateClassType.getInternalName(), className.replace('.', '/'), delegateMethodName, nonstaticDesc); mv.visitLabel(lblEnd); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(args.length + 2, 2); mv.visitEnd(); } //@Override public void invoke(Object[] args) { // delegated((Type0) args[0], (Type1) args[1], ...); //} //The returned MethodVisitor will visit the original version of the method, //including its annotation, where we can get StorageOptions. return new MethodVisitor(Opcodes.ASM4, parentClass.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, delegateMethodName, nonstaticDesc, null, null)) { //Remember storage options for each argument StorageOption.Option[] options = new StorageOption.Option[args.length]; int targetIndex = -1; double sendRange = -1; StorageOption.Target.RangeOption range = StorageOption.Target.RangeOption.SINGLE; { for (int i = 0; i < options.length; ++i) { options[i] = StorageOption.Option.NULL; //set default value } options[0] = StorageOption.Option.INSTANCE; } @Override public AnnotationVisitor visitParameterAnnotation(int parameter_in_func, String desc, boolean visible) { final int parameter = parameter_in_func + 1; //skip this Type type = Type.getType(desc); if (type.equals(Type.getType(StorageOption.Data.class))) { options[parameter] = StorageOption.Option.DATA; } else if (type.equals(Type.getType(StorageOption.Instance.class))) { //INSTANCE as defualt options[parameter] = StorageOption.Option.INSTANCE; //Change to NULLABLE_INSTANCE if nullable set to true return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { if (name.equals("nullable")) { if ((Boolean) value == true) { options[parameter] = StorageOption.Option.NULLABLE_INSTANCE; } } super.visit(name, value); } }; } else if (type.equals(Type.getType(StorageOption.Update.class))) { options[parameter] = StorageOption.Option.UPDATE; } else if (type.equals(Type.getType(StorageOption.Null.class))) { options[parameter] = StorageOption.Option.NULL; } else if (type.equals(Type.getType(StorageOption.Target.class))) { if (!args[parameter].equals(Type.getType(EntityPlayer.class))) { throw new RuntimeException("Target annotation can only be used on EntityPlayer."); } if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } options[parameter] = StorageOption.Option.INSTANCE; targetIndex = parameter; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visitEnum(String name, String desc, String value) { super.visitEnum(name, desc, value); range = StorageOption.Target.RangeOption.valueOf(value); } }; } else if (type.equals(Type.getType(StorageOption.RangedTarget.class))) { if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } targetIndex = parameter; range = null; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { super.visit(name, value); sendRange = (double) value; } }; } return super.visitParameterAnnotation(parameter, desc, visible); } //TODO this option (from annotation) @Override public void visitEnd() { super.visitEnd(); //This is the last method in the delegate class. //Finish the class and do the registration. cw.visitEnd(); try { Class<?> clazz = classLoader.defineClass(delegateClassType.getClassName(), cw.toByteArray()); NetworkCallDelegate delegateObj = (NetworkCallDelegate) clazz.newInstance(); if (side == Side.CLIENT) { NetworkCallManager.registerClientDelegateClass(delegateName, delegateObj, options, targetIndex, range, sendRange); } else { NetworkCallManager.registerServerDelegateClass(delegateName, delegateObj, options); } } catch (Throwable e) { throw new RuntimeException("Can not create delegate for network call.", e); } } }; //public static void delegated(Type0 arg0, Type1, arg1, ...) { // //Code generated by caller. //} //} }
From source file:co.cask.cdap.app.runtime.spark.SparkRunnerClassLoader.java
License:Apache License
/** * Define the akka.remote.Remoting by rewriting usages of scala.concurrent.ExecutionContext.Implicits.global * to Remoting.system().dispatcher() in the shutdown() method for fixing the Akka thread/permgen leak bug in * https://github.com/akka/akka/issues/17729 */// ww w .j a v a2 s . c om private Class<?> defineAkkaRemoting(String name, InputStream byteCodeStream) throws IOException, ClassNotFoundException { final Type dispatcherReturnType = determineAkkaDispatcherReturnType(); if (dispatcherReturnType == null) { LOG.warn("Failed to determine ActorSystem.dispatcher() return type. " + "No rewriting of akka.remote.Remoting class. ClassLoader leakage might happen in SDK."); return findClass(name); } ClassReader cr = new ClassReader(byteCodeStream); ClassWriter cw = new ClassWriter(0); cr.accept(new ClassVisitor(Opcodes.ASM5, cw) { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { // Call super so that the method signature is registered with the ClassWriter (parent) MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); // Only rewrite the shutdown() method if (!"shutdown".equals(name)) { return mv; } return new MethodVisitor(Opcodes.ASM5, mv) { @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { // Detect if it is making call "import scala.concurrent.ExecutionContext.Implicits.global", // which translate to Java code as // scala.concurrent.ExecutionContext$Implicits$.MODULE$.global() // hence as bytecode // GETSTATIC scala/concurrent/ExecutionContext$Implicits$.MODULE$ : // Lscala/concurrent/ExecutionContext$Implicits$; // INVOKEVIRTUAL scala/concurrent/ExecutionContext$Implicits$.global // ()Lscala/concurrent/ExecutionContextExecutor; if (opcode == Opcodes.INVOKEVIRTUAL && "global".equals(name) && "scala/concurrent/ExecutionContext$Implicits$".equals(owner) && Type.getMethodDescriptor(EXECUTION_CONTEXT_EXECUTOR_TYPE).equals(desc)) { // Discard the GETSTATIC result from the stack by popping it super.visitInsn(Opcodes.POP); // Make the call "import system.dispatch", which translate to Java code as // this.system().dispatcher() // hence as bytecode // ALOAD 0 (load this) // INVOKEVIRTUAL akka/remote/Remoting.system ()Lakka/actor/ExtendedActorSystem; // INVOKEVIRTUAL akka/actor/ExtendedActorSystem.dispatcher ()Lscala/concurrent/ExecutionContextExecutor; Type extendedActorSystemType = Type.getObjectType("akka/actor/ExtendedActorSystem"); super.visitVarInsn(Opcodes.ALOAD, 0); super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "akka/remote/Remoting", "system", Type.getMethodDescriptor(extendedActorSystemType), false); super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, extendedActorSystemType.getInternalName(), "dispatcher", Type.getMethodDescriptor(dispatcherReturnType), false); } else { // For other instructions, just call parent to deal with it super.visitMethodInsn(opcode, owner, name, desc, itf); } } }; } }, ClassReader.EXPAND_FRAMES); byte[] byteCode = cw.toByteArray(); return defineClass(name, byteCode, 0, byteCode.length); }
From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java
License:Open Source License
public void accept(MethodVisitor mv, boolean hasAnnotation) { db.log(LogLevel.INFO, "Instrumenting method %s#%s%s", className, mn.name, mn.desc); mv.visitAnnotation(ALREADY_INSTRUMENTED_DESC, true); final boolean handleProxyInvocations = HANDLE_PROXY_INVOCATIONS & hasSuspendableSuperCalls; mv.visitCode();/*from w w w .ja v a2 s.c o m*/ Label lMethodStart = new Label(); Label lMethodStart2 = new Label(); Label lMethodEnd = new Label(); Label lCatchSEE = new Label(); Label lCatchUTE = new Label(); Label lCatchAll = new Label(); Label[] lMethodCalls = new Label[numCodeBlocks - 1]; for (int i = 1; i < numCodeBlocks; i++) lMethodCalls[i - 1] = new Label(); mv.visitInsn(Opcodes.ACONST_NULL); mv.visitVarInsn(Opcodes.ASTORE, lvarInvocationReturnValue); // if (verifyInstrumentation) { // mv.visitInsn(Opcodes.ICONST_0); // mv.visitVarInsn(Opcodes.ISTORE, lvarSuspendableCalled); // } mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchSEE, EXCEPTION_NAME); if (handleProxyInvocations) mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchUTE, UNDECLARED_THROWABLE_NAME); // Prepare visitTryCatchBlocks for InvocationTargetException. // With reflective invocations, the SuspendExecution exception will be wrapped in InvocationTargetException. We need to catch it and unwrap it. // Note that the InvocationTargetException will be regenrated on every park, adding further overhead on top of the reflective call. // This must be done here, before all other visitTryCatchBlock, because the exception's handler // will be matched according to the order of in which visitTryCatchBlock has been called. Earlier calls take precedence. Label[][] refInvokeTryCatch = new Label[numCodeBlocks - 1][]; for (int i = 1; i < numCodeBlocks; i++) { FrameInfo fi = codeBlocks[i]; AbstractInsnNode in = mn.instructions.get(fi.endInstruction); if (mn.instructions.get(fi.endInstruction) instanceof MethodInsnNode) { MethodInsnNode min = (MethodInsnNode) in; if (isReflectInvocation(min.owner, min.name)) { Label[] ls = new Label[3]; for (int k = 0; k < 3; k++) ls[k] = new Label(); refInvokeTryCatch[i - 1] = ls; mv.visitTryCatchBlock(ls[0], ls[1], ls[2], "java/lang/reflect/InvocationTargetException"); } } } for (Object o : mn.tryCatchBlocks) { TryCatchBlockNode tcb = (TryCatchBlockNode) o; if (EXCEPTION_NAME.equals(tcb.type) && !hasAnnotation) // we allow catch of SuspendExecution in method annotated with @Suspendable. throw new UnableToInstrumentException("catch for SuspendExecution", className, mn.name, mn.desc); if (handleProxyInvocations && UNDECLARED_THROWABLE_NAME.equals(tcb.type)) // we allow catch of SuspendExecution in method annotated with @Suspendable. throw new UnableToInstrumentException("catch for UndeclaredThrowableException", className, mn.name, mn.desc); // if (INTERRUPTED_EXCEPTION_NAME.equals(tcb.type)) // throw new UnableToInstrumentException("catch for " + InterruptedException.class.getSimpleName(), className, mn.name, mn.desc); tcb.accept(mv); } if (mn.visibleParameterAnnotations != null) dumpParameterAnnotations(mv, mn.visibleParameterAnnotations, true); if (mn.invisibleParameterAnnotations != null) dumpParameterAnnotations(mv, mn.invisibleParameterAnnotations, false); if (mn.visibleAnnotations != null) { for (Object o : mn.visibleAnnotations) { AnnotationNode an = (AnnotationNode) o; an.accept(mv.visitAnnotation(an.desc, true)); } } mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchAll, null); mv.visitMethodInsn(Opcodes.INVOKESTATIC, STACK_NAME, "getStack", "()L" + STACK_NAME + ";"); mv.visitInsn(Opcodes.DUP); mv.visitVarInsn(Opcodes.ASTORE, lvarStack); // println(mv, "STACK: ", lvarStack); // dumpStack(mv); if (DUAL) { mv.visitJumpInsn(Opcodes.IFNULL, lMethodStart); mv.visitVarInsn(Opcodes.ALOAD, lvarStack); } emitStoreResumed(mv, true); // we'll assume we have been resumed mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "nextMethodEntry", "()I"); mv.visitTableSwitchInsn(1, numCodeBlocks - 1, lMethodStart2, lMethodCalls); mv.visitLabel(lMethodStart2); // the following code handles the case of an instrumented method called not as part of a suspendable code path // isFirstInStack will return false in that case. mv.visitVarInsn(Opcodes.ALOAD, lvarStack); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "isFirstInStackOrPushed", "()Z"); mv.visitJumpInsn(Opcodes.IFNE, lMethodStart); // if true mv.visitInsn(Opcodes.ACONST_NULL); mv.visitVarInsn(Opcodes.ASTORE, lvarStack); mv.visitLabel(lMethodStart); emitStoreResumed(mv, false); // no, we have not been resumed dumpCodeBlock(mv, 0, 0); for (int i = 1; i < numCodeBlocks; i++) { FrameInfo fi = codeBlocks[i]; MethodInsnNode min = (MethodInsnNode) (mn.instructions.get(fi.endInstruction)); if (isYieldMethod(min.owner, min.name)) { // special case - call to yield if (min.getOpcode() != Opcodes.INVOKESTATIC) throw new UnableToInstrumentException("invalid call to suspending method.", className, mn.name, mn.desc); final int numYieldArgs = TypeAnalyzer.getNumArguments(min.desc); final boolean yieldReturnsValue = (Type.getReturnType(min.desc) != Type.VOID_TYPE); emitStoreState(mv, i, fi, numYieldArgs); // we preserve the arguments for the call to yield on the operand stack emitStoreResumed(mv, false); // we have not been resumed // emitSuspendableCalled(mv); min.accept(mv); // we call the yield method if (yieldReturnsValue) mv.visitInsn(Opcodes.POP); // we ignore the returned value... mv.visitLabel(lMethodCalls[i - 1]); // we resume AFTER the call final Label afterPostRestore = new Label(); mv.visitVarInsn(Opcodes.ILOAD, lvarResumed); mv.visitJumpInsn(Opcodes.IFEQ, afterPostRestore); emitPostRestore(mv); mv.visitLabel(afterPostRestore); emitRestoreState(mv, i, fi, numYieldArgs); if (yieldReturnsValue) mv.visitVarInsn(Opcodes.ILOAD, lvarResumed); // ... and replace the returned value with the value of resumed dumpCodeBlock(mv, i, 1); // skip the call } else { final Label lbl = new Label(); if (DUAL) { mv.visitVarInsn(Opcodes.ALOAD, lvarStack); mv.visitJumpInsn(Opcodes.IFNULL, lbl); } // normal case - call to a suspendable method - resume before the call emitStoreState(mv, i, fi, 0); emitStoreResumed(mv, false); // we have not been resumed // emitPreemptionPoint(mv, PREEMPTION_CALL); mv.visitLabel(lMethodCalls[i - 1]); emitRestoreState(mv, i, fi, 0); if (DUAL) mv.visitLabel(lbl); if (isReflectInvocation(min.owner, min.name)) { // We catch the InvocationTargetException and unwrap it if it wraps a SuspendExecution exception. Label[] ls = refInvokeTryCatch[i - 1]; final Label startTry = ls[0]; final Label endTry = ls[1]; final Label startCatch = ls[2]; final Label endCatch = new Label(); final Label notSuspendExecution = new Label(); // mv.visitTryCatchBlock(startTry, endTry, startCatch, "java/lang/reflect/InvocationTargetException"); mv.visitLabel(startTry); // try { min.accept(mv); // method.invoke() mv.visitVarInsn(Opcodes.ASTORE, lvarInvocationReturnValue); // save return value mv.visitLabel(endTry); // } mv.visitJumpInsn(Opcodes.GOTO, endCatch); mv.visitLabel(startCatch); // catch(InvocationTargetException ex) { mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;"); mv.visitTypeInsn(Opcodes.INSTANCEOF, EXCEPTION_NAME); mv.visitJumpInsn(Opcodes.IFEQ, notSuspendExecution); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;"); mv.visitLabel(notSuspendExecution); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(endCatch); mv.visitVarInsn(Opcodes.ALOAD, lvarInvocationReturnValue); // restore return value dumpCodeBlock(mv, i, 1); // skip the call } else { // emitSuspendableCalled(mv); dumpCodeBlock(mv, i, 0); } } } mv.visitLabel(lMethodEnd); if (handleProxyInvocations) { mv.visitLabel(lCatchUTE); mv.visitInsn(Opcodes.DUP); // println(mv, "CTCH: "); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;"); // println(mv, "CAUSE: "); mv.visitTypeInsn(Opcodes.INSTANCEOF, EXCEPTION_NAME); mv.visitJumpInsn(Opcodes.IFEQ, lCatchAll); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;"); mv.visitJumpInsn(Opcodes.GOTO, lCatchSEE); } mv.visitLabel(lCatchAll); emitPopMethod(mv); mv.visitLabel(lCatchSEE); // println(mv, "THROW: "); mv.visitInsn(Opcodes.ATHROW); // rethrow shared between catchAll and catchSSE if (mn.localVariables != null) { for (Object o : mn.localVariables) ((LocalVariableNode) o).accept(mv); } mv.visitMaxs(mn.maxStack + ADD_OPERANDS, mn.maxLocals + NUM_LOCALS + additionalLocals); mv.visitEnd(); }
From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java
License:Open Source License
private void emitPopMethod(MethodVisitor mv) { // emitVerifyInstrumentation(mv); final Label lbl = new Label(); if (DUAL) {/* www . j av a2 s .com*/ mv.visitVarInsn(Opcodes.ALOAD, lvarStack); mv.visitJumpInsn(Opcodes.IFNULL, lbl); } mv.visitVarInsn(Opcodes.ALOAD, lvarStack); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "popMethod", "()V"); if (DUAL) mv.visitLabel(lbl); }