Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 字节码特定部分的修改_Java_Bytecode_Bytecode Manipulation - Fatal编程技术网

Java 字节码特定部分的修改

Java 字节码特定部分的修改,java,bytecode,bytecode-manipulation,Java,Bytecode,Bytecode Manipulation,如何修改字节码的特定部分以添加内容 我的意思是,我知道我要修改什么类、什么方法(或字段)和什么行号,但我想知道我将如何在类的特定行/字段修改字节码 假设我有一门课,GammaController 但是我想在不编辑文件的情况下,将GammaController.setScreengama()更改为不允许值超过100。我知道该方法位于第8行(我们现在将忽略包),并且必须在第9行检查是否超过100,将该方法的设置部分移动到第1行 假设我也知道将进行检查的字节码。我要做的是运行一个应用程序,目标是一个包

如何修改字节码的特定部分以添加内容

我的意思是,我知道我要修改什么类、什么方法(或字段)和什么行号,但我想知道我将如何在类的特定行/字段修改字节码

假设我有一门课,GammaController

但是我想在不编辑文件的情况下,将GammaController.setScreengama()更改为不允许值超过100。我知道该方法位于第8行(我们现在将忽略包),并且必须在第9行检查是否超过100,将该方法的设置部分移动到第1行

假设我也知道将进行检查的字节码。我要做的是运行一个应用程序,目标是一个包含GammaController.class的jar,并让应用程序使用字节码修改该类,该字节码检查该值以确保其不超过100。我该怎么做呢?

您需要使用或3.0/(取决于您的Java版本)。要执行我认为您想要执行的操作,您需要使用
ClassVisitor
并修改一些值(通过
VisitField
等)。然后需要重新加载该类

这是不平凡的,但是ASM人员提供了一些非常详细的文档。愉快的黑客攻击。

(或任何AOP库)在这里可能会有些用处。它允许您定义切入点,例如在调用特定方法时(或在其他事情中定义字段时)。然后可以应用advice,这是在连接点之前/之后执行的操作(连接点是应用切入点的地方)

比如说,

每当调用该方法时,应用验证gamma值是否小于100的建议。如果该值无效,则引发异常。如果有效,则继续正常操作


如果您真的想修改不属于切入点可以处理的类别的代码行,您可以使用@daviditarenco

建议的ASM库老实说,用自定义编译版本整体替换
GammaController.class
可能更容易,最好为
GammacController
创建一个包装类,并在
GammacController
类中设置新的业务逻辑,甚至扩展
GammacController
类。一个好的设计解决方案是破解第三方库的9001倍。我可能应该在问题中这样说,但GammaController纯粹是一个例子。实际情况是在每次更新时不必更新70多个钩子的情况下修改某些东西。当然,最大的障碍是你必须先学习字节码。通常情况下,您不能只插入额外的代码就期望它工作,尤其是在使用新的StackMap表时。您需要首先阅读JVM规范。此外,它还取决于您想要修改类的方式。如果您在运行时或以编程方式修改它们,ASM可能是最好的选择。如果你想手动操作,我建议你使用一个人性化的离线工具,比如我写的反汇编程序。自动操作就是这个计划。我知道如何在小部分阅读字节码,对于我计划做的简单事情,我对我所知道的一切都很满意。但是使用ASM并不需要我所看到的那么多知识。感谢您提供的信息,并将我引向ASM。我想ASM4是针对Java7的,所以我想我会使用它。谢谢你的回答,但我认为ASM是我要使用的,至少现在是这样。
public class GammaController {
    private int gamma = 60;

    public int getScreenGamma() {
        return gamma;
    }

    public void setScreenGamma(int gamma) {
        this.gamma = gamma;
    }
}