简体   繁体   中英

Call superclass method from interceptor bytebuddy

We have an obfuscated class that we need to enhance with bytebuddy. We basically need to redefine one method. Subclassing seemed to not have worked (the code is not executed). Rebasing works but in our intercepted method we need to call the superclass (now talking superclass as in "inheritance" ) method.

class Parent {
  public void connect(){
  ...
  };
}

class WeNeedToHackThis extends Parent {
     public void connect(InetAddress addr){
       //... this is what we want to hack
     }
     public void connect(){
       this.connect(null);
       // this is getting called from interceptor :( which delegates to our hacked method
       // we need to call "real" superclass's (Parent) method instead
     }

}
...
Class<?> dynamic = new ByteBuddy()
            .with(TypeValidation.DISABLED)
            .rebase(commandBase, locator)
            .method(named("connect").and(takesArgument(0, InetAddress.class)))
            .intercept(MethodDelegation.to(Session3270ConnectMethod.class))
            .make()
            .load(Thread.currentThread().getContextClassLoader(), ClassLoadingStrategy.Default.INJECTION)
            .getLoaded();

//In our interceptor:
    public static void connect(InetAddress paramInetAddress,
            @Origin Method origin,
            @This Object self) throws SessionException {
        try {
            System.out.println("hi from hijacked");
            c.call();
            //HOW DO WE CALL SOMETHING LIKE super.connect()
            // we need to call Parent.connect(); 
            // but I am stuck at how to access superclass  code (new Parent().connect(). 
            // I cant access the Parent class method calls on this object
            // if I use @SuperCall or @This then I am getting already overriden version, I need to call the super (Parent's.class) version :(

        } catch (Exception e) {
            throw new RuntimeException(e);

        }
    }

If I understandyou correctly, you only want to intercept a method call if it is invoked from outside of your class but not from within.

This is a difficult thing to achieve. Byte Buddy allows you to add code to any class but even manually, this would be difficult to code out.

Your best chance is probably to add a thread local storage to mark such self-invocation and to detect it if the interceptor is hit again where you simply delegate to the super method without applying the interceptor logic.

public static void connect(InetAddress paramInetAddress,
            @Super Object parentObj, @This Object myself, @SuperCall Callable<?> call) throws SessionException {
        try {
            System.out.println("hi from hijacked");
            parentObj.getClass().getMethods();
            Field IMPL_LOOKUP = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
            IMPL_LOOKUP.setAccessible(true);
            MethodHandles.Lookup lkp = (MethodHandles.Lookup) IMPL_LOOKUP.get(null);
            MethodHandle h1 = lkp.findSpecial(b.class, "connect", MethodType.methodType(void.class), Session3270.class);
            h1.invoke(myself);
        } catch (Throwable e) {
            throw new RuntimeException(e);

        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM