gpt4 book ai didi

java - 阻止 objectweb asm 用 throw 替换无法访问的代码

转载 作者:行者123 更新时间:2023-11-29 04:23:53 26 4
gpt4 key购买 nike

已解决,此代码进行替换:https://gitlab.ow2.org/asm/asm/blob/master/asm/src/main/java/org/objectweb/asm/MethodWriter.java#L1382

解决方案是使用 ifeq(false) 来代替死代码

我正在尝试将一些无法访问的代码注入(inject)到使用 objectweb asm 的方法中。但是它一直用 throw 替换指令

例如我有这个方法:

public static boolean isTurkeyDay() {
iconst_1
ireturn
}

我尝试将其更改为:

public static boolean isTurkeyDay() {
goto L1
nop
nop
:L1
iconst_1
ireturn
}

通过运行它:

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
Label l1 = new Label();
mv.visitJumpInsn(Opcodes.GOTO, l1);
mv.visitInsn(Opcodes.NOP);
mv.visitInsn(Opcodes.NOP);
mv.visitLabel(l1);
return super(mv);
}

我的实际输出结果是

public static boolean isTurkeyDay() {
goto L1
nop
athrow
:L1
iconst_1
ireturn
}

有没有办法告诉 Objectweb 不要用 throw 替换我的指令?我想保留死代码。我错过了什么吗?

最佳答案

ASM 这样做的原因是需要生成堆栈映射帧。从历史上看,包含死字节码没有问题——它只会被验证者忽略。但是随着stack map验证的引入,非线性控制流的每一点都需要一个stack map frame,代码由验证者处理。

如果您为任意字节码生成堆栈映射,这会导致问题。例如,考虑以下字节码

goto LWHATEVER 
; dead code
iload_0
aload_0

没有可能使该字节码有效的堆栈映射,因为代码将寄存器 0 作为 int 和对象加载。对于推理验证,这没有问题,因为 validator 从一开始就不会处理死代码,但是对于堆栈映射 validator ,所有代码都在一次线性传递中处理,无论它是否可达。

因此,为了解决这个问题,ASM 只是用一系列 nop 后跟一个 athrow 来替换死代码。这确保了 a) 可以为它生成一个有效的堆栈帧(具体来说,堆栈上只有一个异常)和 b) 死代码不会跳到其他任何地方,这会进一步混淆堆栈映射验证者。这就是为什么在末尾有一个 throw 而不是只使用所有 nop 的原因。

至于 if false 的“解决方案”,如果它对您有用,那很好,但它不是 100% 的解决方案。它起作用的原因是因为 validator 忽略条件值并假定可以采用每个可能的分支。因此,您的代码被认为是实时的。然而,这样做的必然结果是它必须具有有效的类型和控制流,就像代码实际上是可访问的一样。同样,ASM 将看到它是实时代码,并只使用正常的类型检查过程来生成堆栈帧。但是,如果您尝试将无效的字节码放在 if false 分支下,您将收到错误消息,因为它被认为是实时的。

在方法中嵌入任意无用代码的唯一真正解决方案是首先不使用堆栈映射,这意味着将类文件版本设置为 50.0 或以下并告诉 ASM 不要生成堆栈映射。或者,您可以使用 Krakatau 汇编器,它可以让您对生成的字节码进行低级控制,但代价是不会自动生成堆栈帧。

关于java - 阻止 objectweb asm 用 throw 替换无法访问的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47461055/

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