byte-buddy icon indicating copy to clipboard operation
byte-buddy copied to clipboard

Not able to intercept 'loadLibrary()' in some java versions

Open dmitry-bluerock opened this issue 3 months ago • 2 comments

Hello,

I'm trying to intercept an external library load in java. There is a public API in java: System.loadLibrary() and Runtime.loadLibrary(). However the next code works for java 8 and 11. But doesn't work for java 17, 21, 25:

        new AgentBuilder.Default()
                .disableClassFormatChanges()
                .with(RETRANSFORMATION)
                .ignore(none())
                .type(any())
                .transform((builder, type, classLoader, module, pd) -> builder.visit(
                        Advice.to(LoadLibraryAdvice.class)
                                .on(ElementMatchers.isMethod().and(named("loadLibrary")))))

LoadLibraryAdvice contains just debug output to confirm if it's working:

public class LoadLibraryAdvice {
    @Advice.OnMethodEnter
    static void onEnter(
            @Advice.Origin Method method,
            @Advice.AllArguments(typing = DYNAMIC) Object[] args) {
        System.out.println("intercepted: " + method.getDeclaringClass().getName() + "@" + method.getName());
        for (Object a : args)
            System.out.println(" > " + a.toString());
    }
}

On java versions 8 and 11 it works and I see debug output (including internal call to java.lang.ClassLoader.loadLibrary). On java versions 17, 21, 25 I don't see any output and also I don't see transformation debug log for System/Runtime/ClassLoader classes.

dmitry-bluerock avatar Oct 07 '25 07:10 dmitry-bluerock

I assume that the method call got intrinsified in some way and is excluded from instrumentation. Did you try adding a logger that shows you if the type is discovered?

raphw avatar Oct 07 '25 16:10 raphw

the method call got intrinsified in some way

I'm not familiar with it. Could you please elaborate more? just in case it's not some JNI/native method.

Did you try adding a logger that shows you if the type is discovered?

yes, if I add logging I see a lot (thousands?) of classes being check however I don't see System/Runtime/ClassLoader

Also if I narrow the type down and do more specific type:

-               .type(any())
+              .type(named("java.lang.System").or(named("java.lang.Runtime")))

then it works for java 17,21,25 (of course ClassLoader is being skipped) but it's better than nothing compare to type(any()) which sounds strange to me. Should more broad definition give less matches (in both cases ignore(none()) is being used)?

dmitry-bluerock avatar Oct 10 '25 09:10 dmitry-bluerock