我试图在一个类中注入两行代码。我曾经设法让它工作一次,但我无法让它再次工作。出于某种原因,无论我做什么,我都无法让代码在运行时运行,即使它应该成功注入。这是我的注射方法:
public byte[] patchBlockRotatedPillarASM(String name, byte[] bytes, boolean obfuscated)
{
String targetMethodName = "";
if(obfuscated == true)
{
targetMethodName ="a";
System.out.println("******** Using obfuscated method");
}
else
{
targetMethodName ="onBlockPlaced";
System.out.println("******** Using unobfuscated method");
}
//set up ASM class manipulation stuff. Consult the ASM docs for details
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytes);
classReader.accept(classNode, 0);
//Now we loop over all of the methods declared inside the Block class until we get to the targetMethodName "onBlockPlaced"
@SuppressWarnings("unchecked")
Iterator<MethodNode> methods = classNode.methods.iterator();
while(methods.hasNext())
{
MethodNode m = methods.next();
System.out.println("********* Method Name: "+m.name + " Desc:" + m.desc);
int fdiv_index = -1;
//Check if this is onBlockPlaced and it's method signature is (Lnet/minecraft/world/World;IIIIFFFI)I
if ((m.name.equals(targetMethodName) && m.desc.equals("(Lnet/minecraft/world/World;IIIIFFFI)I")))
{
System.out.println("********* Inside target method!");
AbstractInsnNode currentNode = null;
AbstractInsnNode targetNode = null;
@SuppressWarnings("unchecked")
Iterator<AbstractInsnNode> iter = m.instructions.iterator();
int index = -1;
//Loop over the instruction set and find the instruction 21 which does the line before the ILOAD
while (iter.hasNext())
{
index++;
currentNode = iter.next();
System.out.println("********* index : " + index + " currentNode.getOpcode() = " + currentNode.getOpcode());
System.out.println(currentNode);
//Found it! save the index location of instruction ILOAD and the node for this instruction
if (currentNode.getOpcode() == 21)
{
targetNode = currentNode;
fdiv_index = index;
}
}
System.out.println("********* fdiv_index should be 2 -> " + fdiv_index);
if (targetNode == null)
{
System.out.println("Did not find all necessary target nodes! ABANDON CLASS!");
return bytes;
}
if (fdiv_index == -1)
{
System.out.println("Did not find all necessary target nodes! ABANDON CLASS!");
return bytes;
}
InsnList toInject = new InsnList();
this.addPlaceEvent(toInject, m, targetNode);
/*toInject.add(new VarInsnNode(Opcodes.ALOAD, 0));//ALOAD 0
toInject.add(new VarInsnNode(Opcodes.ALOAD, 1));//ALOAD 1
toInject.add(new VarInsnNode(Opcodes.ILOAD, 2));//ILOAD 2
toInject.add(new VarInsnNode(Opcodes.ILOAD, 3));//ILOAD 3
toInject.add(new VarInsnNode(Opcodes.ILOAD, 4));//ILOAD 4
toInject.add(new VarInsnNode(Opcodes.ILOAD, 5));//ILOAD 5
toInject.add(new VarInsnNode(Opcodes.FLOAD, 6));//FLOAD 6
toInject.add(new VarInsnNode(Opcodes.FLOAD, 7));//FLOAD 7
toInject.add(new VarInsnNode(Opcodes.FLOAD, 8));//FLOAD 8
toInject.add(new VarInsnNode(Opcodes.ILOAD, 9));//ILOAD 9
toInject.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "net/minecraft/block/Block", "onBlockPlaced", "(Lnet/minecraft/world/World;IIIIFFFI)I"));//INVOKESPECIAL net/minecraft/block/Block.onBlockPlaced (Lnet/minecraft/world/World;IIIIFFFI)I
m.instructions.insert(toInject);*/
System.out.println("Patching Complete!");
break;
}
}
//ASM specific for cleaning up and returning the final bytes for JVM processing.
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
classNode.accept(writer);
return writer.toByteArray();
}
以下是我尝试注入的方法:
public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9)
{
int j1 = par9 & 3;
byte b0 = 0;
switch (par5)
{
case 0:
case 1:
b0 = 0;
break;
case 2:
case 3:
b0 = 8;
break;
case 4:
case 5:
b0 = 4;
}
return j1 | b0;
}
这是上述方法的字节码:
// access flags 0x1
public onBlockPlaced(Lnet/minecraft/world/World;IIIIFFFI)I
L0
LINENUMBER 33 L0
ILOAD 9
ICONST_3
IAND
ISTORE 10
L1
LINENUMBER 34 L1
ICONST_0
ISTORE 11
L2
LINENUMBER 36 L2
ILOAD 5
TABLESWITCH
0: L3
1: L3
2: L4
3: L4
4: L5
5: L5
default: L6
L3
LINENUMBER 40 L3
FRAME APPEND [I I]
ICONST_0
ISTORE 11
L7
LINENUMBER 41 L7
GOTO L6
L4
LINENUMBER 44 L4
FRAME SAME
BIPUSH 8
ISTORE 11
L8
LINENUMBER 45 L8
GOTO L6
L5
LINENUMBER 48 L5
FRAME SAME
ICONST_4
ISTORE 11
L6
LINENUMBER 51 L6
FRAME SAME
ILOAD 10
ILOAD 11
IOR
IRETURN
L9
LOCALVARIABLE this Lnet/minecraft/block/BlockRotatedPillar; L0 L9 0
LOCALVARIABLE par1World Lnet/minecraft/world/World; L0 L9 1
LOCALVARIABLE par2 I L0 L9 2
LOCALVARIABLE par3 I L0 L9 3
LOCALVARIABLE par4 I L0 L9 4
LOCALVARIABLE par5 I L0 L9 5
LOCALVARIABLE par6 F L0 L9 6
LOCALVARIABLE par7 F L0 L9 7
LOCALVARIABLE par8 F L0 L9 8
LOCALVARIABLE par9 I L0 L9 9
LOCALVARIABLE j1 I L1 L9 10
LOCALVARIABLE b0 B L2 L9 11
MAXSTACK = 2
MAXLOCALS = 12
我需要的行的说明:
public void addPlaceEvent(InsnList iList, MethodNode mNode, AbstractInsnNode tNode)
{
//LINENUMBER 87 L0 (possibly unneeded)
iList.add(new TypeInsnNode(Opcodes.NEW, "timeTraveler/mechanics/BlockPlaceEvent"));//NEW timeTraveler/mechanics/BlockPlaceEvent
iList.add(new InsnNode(Opcodes.DUP));//DUP
iList.add(new VarInsnNode(Opcodes.ALOAD, 0));//ALOAD 0
iList.add(new VarInsnNode(Opcodes.ILOAD, 2));//ILOAD 2
iList.add(new VarInsnNode(Opcodes.ILOAD, 3));//ILOAD 3
iList.add(new VarInsnNode(Opcodes.ILOAD, 4));//ILOAD 4
iList.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "timeTraveler/mechanics/BlockPlaceEvent", "<init>", "(Lnet/minecraft/block/Block;III)V"));//INVOKESPECIAL timeTraveler/mechanics/BlockPlaceEvent.<init> (Lnet/minecraft/block/Block;III)V
iList.add(new VarInsnNode(Opcodes.ASTORE, 5));//ASTORE 5
//L1 (possibly unneeded)
//LINENUMBER 88 L1 (possibly unneeded)
iList.add(new FieldInsnNode(Opcodes.GETSTATIC, "net/minecraftforge/common/MinecraftForge", "EVENT_BUS", "Lnet/minecraftforge/event/EventBus;"));//GETSTATIC net/minecraftforge/common/MinecraftForge.EVENT_BUS : Lnet/minecraftforge/event/EventBus;
iList.add(new VarInsnNode(Opcodes.ALOAD, 5));//ALOAD 5
iList.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "net/minecraftforge/event/EventBus", "post", "(Lnet/minecraftforge/event/Event;)Z"));//INVOKEVIRTUAL net/minecraftforge/event/EventBus.post (Lnet/minecraftforge/event/Event;)Z
mNode.instructions.insert(tNode, iList);
//POP (possibly unneeded)
//L2 (possibly unneeded)
}
}
有关如何解决此问题的任何想法?