用 ByteBuddy 重新定义 java.lang 类

Redefine java.lang classes with ByteBuddy

我正在尝试使用 ByteBuddy 在 java.lang 包(例如 String.class 或 Integer.class 上重新定义 classes,但没有成功。我的问题是这是否可能?

这是我在 java 代理中尝试的代码:

public static void premain(String agentArgs, Instrumentation inst) {
    new AgentBuilder.Default()
            .type(named("java.lang.String"))
            .transform((builder, typeDescription, classLoader) ->
                    builder.method(named("toString"))
                            .intercept(FixedValue.value("toString() got hacked!")))
            .with(AgentBuilder.Listener.StreamWriting.toSystemOut())
            .with(AgentBuilder.RedefinitionStrategy.REDEFINITION)
            .with(AgentBuilder.TypeStrategy.Default.REDEFINE)
            .installOn(inst);
}

当我检查日志的输出时,我看到的关于字符串 class 的内容是:

[Byte Buddy] IGNORE [[Ljava.lang.String; [null, null]
[Byte Buddy] COMPLETE [[Ljava.lang.String; [null, null]

这是否意味着 ByteBuddy 没有重新定义字符串 class?这可能吗?

非常感谢。

是的,字节好友可以重新定义任何 class,但默认情况下,bootstrap class 会被忽略。您可以通过定义自定义忽略匹配器或将其全部删除来覆盖此默认设置:

AgentBuilder agentBuilder = new AgentBuilder.Default().ignore(none());

但是,我强烈建议您不要乱用 bootstrap classes,尤其是 String class。许多代码对 toString class.

做出了强有力的假设

大多数 JVM 不允许您在重新定义 classes 时更改 class 文件格式,这就是您应该启用 .disableClassFormatChanges() 选项的原因。这样做,您就不能再添加方法或字段,此时您应该考虑使用 Advice class 而不是标准拦截器。