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

how i use advice to match java.util.regex.Pattern

Open cor0ps opened this issue 1 year ago • 9 comments

this  is  I  want  matches  java.util.regex.Pattern
  new AgentBuilder.Default().type(ElementMatchers.nameMatches("java.util.regex.Pattern"))
                .transform(patternTransformer)

I  want  use   Advice 
   AgentBuilder.Transformer patternTransformer = (builder, typeDescription, classLoader, javaModule, protectionDomain) -> builder

                .method(ElementMatchers.nameMatches("matcher"))
                //委托
                .intercept(Advice.to(PatternAdvice.class));


PatternAdvice.class

public class PatternAdvice {


    @Advice.OnMethodEnter
    public static void MethodEnter(@Advice.Origin Method method, @Advice.AllArguments Object[] args) {

    }

}

first I add this agent.jar to instrumentation.appendToBootstrapClassLoaderSearch(new JarFile(xxx));

this is error

I use instrumentation.appendToSystemClassLoaderSearch it works,but not matches java.util.regex.Pattern ,how I solve it

cor0ps avatar Nov 24 '23 07:11 cor0ps

You want to use Advice as decorator via builder.visit(...). Then the code is inlined. Generally speaking, I recommend against intercepting such a central class, though, as Byte Buddy relies on it itself what can cause circularities.

raphw avatar Nov 24 '23 13:11 raphw

how can I solve this problem ,why i always not mathes java.util.regex but I can mathes java.lang.Runtime ....

cor0ps avatar Nov 25 '23 08:11 cor0ps

I find bytebuddy stacks, java.util.regex.Pattern always upper bytebuddy

at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$LegacyVmDispatcher.run(AgentBuilder.java:12507)
	at java.security.AccessController.doPrivileged(Native Method)
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doPrivileged(AgentBuilder.java)
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:12069)
	at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
	at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
	at java.util.regex.Pattern.intersection(Pattern.java:5273)
	at java.util.regex.Pattern.clazz(Pattern.java:2551)
	at java.util.regex.Pattern.sequence(Pattern.java:2077)
	at java.util.regex.Pattern.expr(Pattern.java:2010)
	at java.util.regex.Pattern.compile(Pattern.java:1702)
	at java.util.regex.Pattern.<init>(Pattern.java:1352)
	at java.util.regex.Pattern.compile(Pattern.java:1028)

cor0ps avatar Nov 25 '23 09:11 cor0ps

You'd have to avoid them manually, for example by checking the call site's stack and to suppress your modifications. Byte Buddy does not interfere with this as it is only applying your instrumentation.

raphw avatar Nov 25 '23 21:11 raphw

I'm really confused about this. I can't figure out why I can't intercept it java.util.regex.Pattern this class in boot loader 。

cor0ps avatar Nov 26 '23 10:11 cor0ps

You need to register an ignore matcher that allows for intercepting the boot loader. Check the ignore step in the builder API.

raphw avatar Dec 03 '23 15:12 raphw

Perhaps it's because the internal implementation of ElementMatchers.nameMatches(java.lang.String) further relies on java.util.regex.Pattern.
If you already have the specific class name, have you tried using ElementMatchers.named(java.lang.String) for matching instead?

dogourd avatar Dec 05 '23 12:12 dogourd

You need to register an ignore matcher that allows for intercepting the boot loader. Check the ignore step in the builder API.

Hi @raphw , I added the ignore matcher, however, I still can not intercept any classes from JDK like java.util.ArrayList. Would be great if you can give me some hints.

        install(arg, inst);
    }

    public static void agentmain(String arg, Instrumentation inst) throws IOException {
        install(arg, inst);
    }

    private static void install(String arg, Instrumentation inst) throws IOException {
        new AgentBuilder.Default()
                .ignore(none())
                .type(any().and(not(nameStartsWith("net.bytebuddy.")))
                        .and(not(nameStartsWith("de.scrum_master.bytebuddy.")))
                        .and(not(nameStartsWith("java.lang.invoke.BoundMethodHandle$Species_L")))
                        .and(not(nameStartsWith("com.sun.proxy.$Proxy")))
                        .and(not(named("java.lang.UnsupportedOperationException")))
                        .and(not(nameStartsWith("org.junit.")))
                        .and(not(nameStartsWith("org.objectweb.asm.")))
                        .and(not(nameStartsWith("com.intellij."))))
                .transform(new AgentBuilder.Transformer.ForAdvice().advice(ElementMatchers.isConstructor(), ConstructorInterceptor.class.getName()))
                .installOn(inst);
    }```

januslinhc avatar Jan 20 '24 09:01 januslinhc

You need to use with(RetransformationStrategy.RETRANSFORM) as those classes will already be loaded when your agent is installed. Use disableClassFormatChanges(), too, as retransformation is not capable of all forms of transformation.

raphw avatar Jan 23 '24 19:01 raphw