Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.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 ByteBuddy拦截的方法未被调用_Java_Hook_Byte Buddy - Fatal编程技术网

Java ByteBuddy拦截的方法未被调用

Java ByteBuddy拦截的方法未被调用,java,hook,byte-buddy,Java,Hook,Byte Buddy,private void orsc.orscaplet.draw()绘制视频游戏的每一帧。我们的目标是拦截draw()方法,这样我们就可以在当前绘制的帧上绘制,这样我们就可以显示用户通常看不到的信息 下面,我使用ByteBuddy创建orsc.orscaplet的一个新子类,然后截取draw()函数,使其正常调用draw(),并调用public void PaintCallback.paint() 视频游戏的main()位于orsc.OpenRSC内。因此,我们将使用带有截获方法的类加载器创建一

private void orsc.orscaplet.draw()
绘制视频游戏的每一帧。我们的目标是拦截
draw()
方法,这样我们就可以在当前绘制的帧上绘制,这样我们就可以显示用户通常看不到的信息

下面,我使用ByteBuddy创建
orsc.orscaplet
的一个新子类,然后截取
draw()
函数,使其正常调用
draw()
,并调用
public void PaintCallback.paint()

视频游戏的
main()
位于
orsc.OpenRSC
内。因此,我们将使用带有截获方法的类加载器创建一个新的
orsc.OpenRSC
对象:

        Class loadedMyClass = myLoader.loadClass("orsc.OpenRSC");
        Constructor constructor = loadedMyClass.getConstructor();
        Object myClassObject = constructor.newInstance();
        return myClassObject; //later on, we call orsc.OpenRSC.main() with this object.
但是,我没有收到任何调用
PaintCallback.paint()
。为什么我的截取不起作用?我有三个理论:

  • 尽管使用了
    myLoader
    类加载器,该类仍在其他地方加载。但是,我尝试过使用
    ByteBuddyAgent.install()
    ,并在
    .load(myLoader,ClassLoadingStrategy.fromInstalledAgent())中指定了它

  • 我应该尝试重新定义
    ,而不是执行
    子类
    ?如果是这样,如果我使用
    重定义
    截取
    ,我可以调用原始函数吗?如果是,怎么做?我尝试了很多不同的方法,结果我的轮子在泥里转得很厉害

  • 我应该做的不是
    子类
    重定义
    ,而是
    重基
    ?我尝试使用以下代码执行此操作,并从instrumentation库收到异常:

             new ByteBuddy().rebase(orsc.ORSCApplet.class)
                        .method(ElementMatchers.named("draw"))
                        .intercept(SuperMethodCall.INSTANCE.andThen(MethodCall.invoke(PaintCallback.class.getMethod("paint"))))
                        .make()
                        .load(myLoader, 
                                ClassReloadingStrategy.fromInstalledAgent());
    
     java.lang.IllegalStateException: Error invoking java.lang.instrument.Instrumentation#retransformClasses
         at net.bytebuddy.dynamic.loading.ClassReloadingStrategy$Dispatcher$ForJava6CapableVm.retransformClasses(ClassReloadingStrategy.java:503)
         at net.bytebuddy.dynamic.loading.ClassReloadingStrategy$Strategy$2.apply(ClassReloadingStrategy.java:568)
         at net.bytebuddy.dynamic.loading.ClassReloadingStrategy.load(ClassReloadingStrategy.java:225)
         at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:100)
         at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6292)
         at reflector.Reflector.injectCallbacksAndReturnClient(Reflector.java:319)
         at reflector.Reflector.createClient(Reflector.java:50)
         at bot.Main.main(Main.java:164)
     Caused by: java.lang.UnsupportedOperationException: class redefinition failed: attempted to add a method
         at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
         at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:167)
         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
         at java.base/java.lang.reflect.Method.invoke(Method.java:564)
         at net.bytebuddy.dynamic.loading.ClassReloadingStrategy$Dispatcher$ForJava6CapableVm.retransformClasses(ClassReloadingStrategy.java:495)
         ... 7 more
    

  • 创建子类时,必须确保该子类在创建时返回,通常是从某种工厂返回。否则,您的子类将存在,但永远不会被使用。我不清楚您是否在代码中这样做

    重定基可被视为子类化,其中原始类在其内部进行扩展,以避免从代理中进行子类化的限制,因为创建工厂通常比较困难。但是,这通常需要添加方法或字段,而在类已经加载时,即使使用Java代理,也不可能添加这些方法或字段。但是,在您的情况下,如果避免引用
    orsc.orscaplet.class
    ,则可以使用
    TypePool.Default
    创建描述,并将其提供给Byte Buddy。如果然后通过注入加载插入的类,它将位于原始类文件之前,并在应用程序中使用


    然而,最优雅的方法是使用重新定义,它可以应用于加载的类。通常,您会为此使用
    AgentBuilder
    。如果要向现有方法添加代码,最好使用
    建议,而不是此处的委托,因为建议会将代码添加到方法的开头和/或结尾。请确保使用
    DynamicType.Builder::visit
    将建议作为装饰应用,而不是常规的拦截。

    嘿,Rafael,谢谢你的回答,谢谢你制作了这么棒的库!
             new ByteBuddy().rebase(orsc.ORSCApplet.class)
                        .method(ElementMatchers.named("draw"))
                        .intercept(SuperMethodCall.INSTANCE.andThen(MethodCall.invoke(PaintCallback.class.getMethod("paint"))))
                        .make()
                        .load(myLoader, 
                                ClassReloadingStrategy.fromInstalledAgent());
    
     java.lang.IllegalStateException: Error invoking java.lang.instrument.Instrumentation#retransformClasses
         at net.bytebuddy.dynamic.loading.ClassReloadingStrategy$Dispatcher$ForJava6CapableVm.retransformClasses(ClassReloadingStrategy.java:503)
         at net.bytebuddy.dynamic.loading.ClassReloadingStrategy$Strategy$2.apply(ClassReloadingStrategy.java:568)
         at net.bytebuddy.dynamic.loading.ClassReloadingStrategy.load(ClassReloadingStrategy.java:225)
         at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:100)
         at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6292)
         at reflector.Reflector.injectCallbacksAndReturnClient(Reflector.java:319)
         at reflector.Reflector.createClient(Reflector.java:50)
         at bot.Main.main(Main.java:164)
     Caused by: java.lang.UnsupportedOperationException: class redefinition failed: attempted to add a method
         at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
         at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:167)
         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
         at java.base/java.lang.reflect.Method.invoke(Method.java:564)
         at net.bytebuddy.dynamic.loading.ClassReloadingStrategy$Dispatcher$ForJava6CapableVm.retransformClasses(ClassReloadingStrategy.java:495)
         ... 7 more