java - 通过 Java ASM 调用私有(private)方法

标签 java methods invoke java-bytecode-asm

我想在不使用反射的情况下调用私有(private)方法:是否可以使用 ASM Hook 私有(private) native 方法并调用它?

最佳答案

挑战在于不生成调用 private 的类。方法通过 ASM 或类似的字节码生成工具。挑战是在不被验证者拒绝的情况下将字节码放入 JVM。
对于 OpenJDK/HotSpot,有 sun.misc.Unsafe有方法defineAnonymousClass(Class<?>, byte[], Object[])它用于生成访问器类,例如实现功能接口(interface)和调用 private 的运行时类持有 lambda 表达式主体的合成方法。
你可以使用它来加载你的字节码,使用 private方法的声明类作为第一个参数,以使该方法可访问。另一方面,JRE 自己的用例意味着您甚至不需要自己生成这样的字节码:

MethodHandles.Lookup l = MethodHandles.privateLookupIn(Class.class, MethodHandles.lookup());
MethodHandle target = l.findSpecial(Class.class, "getDeclaredFields0",
    MethodType.methodType(Field[].class, boolean.class), Class.class);
BiFunction<Class<?>,Boolean,Field[]> a = (BiFunction)LambdaMetafactory.metafactory(
    l, "apply", MethodType.methodType(BiFunction.class), target.type().generic(),
    target, target.type().changeParameterType(1, Boolean.class))
    .getTarget().invokeExact();
然后,您可以调用,例如a.apply(Class.class, false)这将调用 getDeclaredFields0没有反射。privateLookupIn是一种 Java 9 方法,如果您使用非模块化代码或提供必要的 --add-opens JVM 启动时的选项,打开 java.base到你的模块。会有一个关于反射访问的警告,好吧,注意到这种访问“将在 future 的版本中被拒绝”是正确的。无论如何,How to hide warning "Illegal reflective access" in java 9 without JVM argument?可能很有趣。
对于 Java 8,您需要侵入 Lookup类以获取适当的查找实例。 This answer显示一个解决方案,here是另一种方法。

关于java - 通过 Java ASM 调用私有(private)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60283268/

相关文章:

c# - 我写了有趣的 Linq 代码,但我不知道它如何工作或为什么工作

c# - .net 中的 Invoke() 有什么用?

java - Podio API - Java - 将文件附加到现有项目

java - BLAS.dgemm方法多线程计算误差

java - Spark Java API如何计算总工资

c++ - std::unordered_map::insert与std::unordered_map::operator []

java - 当我们不传递任何命令行参数时,为什么不会出现错误?

java - 为什么我们实际上使用 getter 和 setter?

java - 计算退房价格

java - Mule:如何将Java/Spring bean的方法调用结果分配给流变量