0

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);

        }
    }
kosta5
  • 1,129
  • 3
  • 14
  • 36
  • Ok, I see its not that clear :) --> "How to call 'connect()' method of class Parent.class (which is parent class that class WeNeedToHackThis inherits from - basically we need to execute: 'super.connect()' inside interceptor) – kosta5 Jul 12 '17 at 05:34

2 Answers2

0

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.

Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192
  • Actually I think I still fail at proper wording... Anyway I was able to resolve it - see my answer for calling parent class below (used method delegation from reflection). So I joined reflection & bytebuddy and achieved what was needed. Thanks for an awesome lib tho! – kosta5 Jul 13 '17 at 11:00
  • Ah, have you tried to have the Super object be of type Parent? That way you can call the method directly! – Rafael Winterhalter Jul 13 '17 at 13:59
  • I did and this is what I ended with java.lang.IllegalStateException: size = 0 at net.bytebuddy.matcher.FilterableList$AbstractBase.getOnly(FilterableList.java:108) at net.bytebuddy.implementation.auxiliary.TypeProxy$ForSuperMethodByConstructor.apply(TypeProxy.java:424) at net.bytebuddy.implementation.bind.MethodDelegationBinder$ParameterBinding$Anonymous.apply(MethodDelegationBinder.java:222) ... – kosta5 Jul 13 '17 at 15:06
  • Could you create a reproduction and submit it as a bug via GitHub? – Rafael Winterhalter Jul 13 '17 at 20:41
0
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);

        }
    }
kosta5
  • 1,129
  • 3
  • 14
  • 36