gpt4 book ai didi

java - 使用asm重构方法时的杂散指令

转载 作者:行者123 更新时间:2023-12-01 10:06:21 24 4
gpt4 key购买 nike

我正在使用asm来修改MethodNode的指令。我的代码从 methodNode.instructions 构造一个图。使用该图,我重新排列并删除了指令。然后,我使用该图为 MethodNode 生成新的指令列表。问题是指令仍然具有 .getNext() 的值,这会导致不再包含在图形中的杂散指令被添加到方法指令的末尾。当将 InsnList 转换为数组时,这也会导致 ArrayIndexOutOfBoundsException。

示例:

初始说明:

L0
ALOAD 1
LDC 1784196469
INVOKEVIRTUAL dq.c (I)I
ISTORE 2
ILOAD 2
IFNE L1
GOTO L2
L3
RETURN
L1
ALOAD 0
ALOAD 1
ILOAD 2
BIPUSH 15
INVOKEVIRTUAL ac.f (Ldq;IB)V
GOTO L0
L2
GOTO L3

图表更改后。这些是清除列表后添加到 methodNode.instructions 中的指令。

L0
ALOAD 1
LDC 1784196469
INVOKEVIRTUAL dq.c (I)I
ISTORE 2
ILOAD 2
IFNE L1
RETURN
L1
ALOAD 0
ALOAD 1
ILOAD 2
BIPUSH 15
INVOKEVIRTUAL ac.f (Ldq;IB)V
GOTO L0

当对最后一条指令调用 .getNext() 时,结果如下:

org.objectweb.asm.tree.LabelNode@7a0ac6e3

如您所见,最后添加的指令 (GOTO L0) 具有 .getNext() 的值

当这个MethodNode被保存然后反编译时,这就是结果。有一个杂散的 GOTO 语句指向不存在的标签。

L1 {
aload1
ldc 1784196469 (java.lang.Integer)
invokevirtual dq c((I)I);
istore2
iload2
ifne L2
return
}
L2 {
aload0 // reference to self
aload1
iload2
bipush 15
invokevirtual ac f((Ldq;IB)V);
goto L1
goto L3
}

如果我更改方法中的指令顺序,如何重用它们?这是一个错误还是我使用 asm 错误?

最佳答案

InsnListAbstractInsnNode 的链表。 AbstractInsnNode 的每个实例都有一个名为 next 的指针,它指向列表中的下一个节点。

当您重新排列列表中的节点时,您还需要处理这些指针。在您的情况下, GOTO L0 的节点最初指向 L2,并且由于其 next 指针在重新排列期间尚未更新,因此它仍然指向末尾的L2

似乎没有简单的解决方案来更新 next 指针。它没有设置方法。 clear方法没有做到这一点。 removeAll 方法不可见。

一些可能性可能是(i)使用 remove在重用之前从列表中删除所有节点;或 (ii) 为新列表构造新节点。

关于java - 使用asm重构方法时的杂散指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36438214/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com