Bytebuddy-拦截java.net.ServerSocket构造函数 [英] Bytebuddy - Intercept java.net.ServerSocket constructor

查看:181
本文介绍了Bytebuddy-拦截java.net.ServerSocket构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Iam试图拦截 java.net.ServerSocket 的两个方法和一个构造函数.拦截两个方法 getLocalPort getInetAddress 可以正常工作.但是,不会触发应处理构造方法 ServerSocket(int)的类.我要检测的代码(在包含在mainproject中的另一个jar文件中):

Iam Trying to Intercept two methods and one constructor of java.net.ServerSocket. Intercepting the two methods getLocalPort and getInetAddress works fine. However, the class which should handle the constructor ServerSocket(int) is not triggered. My code to instrument (inside a different jar-file which is included to the mainproject):

包装检测;

public class Instrumenting {

    private static final String CLASS_NAME = "java.net.ServerSocket";

    public static void instrument(Instrumentation instrumentation) throws Exception {
        System.out.println("[Instrumenting] starting to instrument '" + CLASS_NAME + "'");

        instrumentation.appendToBootstrapClassLoaderSearch(new JarFile("C:\\Users\\Moritz\\Instrumenting\\dist\\Instrumenting.jar"));

        File temp = Files.createTempDirectory("tmp").toFile();
        ClassInjector.UsingInstrumentation.of(temp, ClassInjector.UsingInstrumentation.Target.BOOTSTRAP, instrumentation).inject(Collections.singletonMap(
            new TypeDescription.ForLoadedType(GetLocalPortIntercept.class),
            ClassFileLocator.ForClassLoader.read(GetLocalPortIntercept.class)));


        new AgentBuilder.Default()
                .ignore(ElementMatchers.none())
                .with(new AgentBuilder.InjectionStrategy.UsingInstrumentation(instrumentation, temp))
                .type(ElementMatchers.named(CLASS_NAME))

                .transform((DynamicType.Builder<?> builder, TypeDescription td, ClassLoader cl, JavaModule jm) -> 
                        builder
                                .method(ElementMatchers.named("getLocalPort"))
                                .intercept(MethodDelegation.to(GetLocalPortIntercept.class))

                                .method(ElementMatchers.named("getInetAddress"))
                                .intercept(MethodDelegation.to(GetInetAddressIntercept.class))

                                .constructor(ElementMatchers.takesArguments(1).and(ElementMatchers.takesArguments(Integer.class)))
                                .intercept(MethodDelegation.to(ServerSocketIntercept.class))
                ).installOn(instrumentation);

        System.out.println("[Instrumenting] done");
    }

    public static class ServerSocketIntercept {

        public static void intercept(int port) throws Exception {
            System.out.println("[ServerSocketIntercept] port: " + port);
        }

    }

    public static class GetLocalPortIntercept {

        public static int intercept() throws Exception {
            System.out.println("[GetLocalPortIntercept]");

            return 42;
        }

    }

    public static class GetInetAddressIntercept {

        public static InetAddress intercept() throws Exception {
            System.out.println("[GetInetAddressIntercept]");

            return InetAddress.getByAddress(new byte[] {1, 2, 3 ,4});
        }

    }
}

其计算方式:

import instrumenting.Instrumenting;

...


public class Main {

    public static void premain(String agentArgs, Instrumentation instrumentation) throws Exception {
        Instrumenting.instrument(instrumentation);
    }

    public static void main(String[] args) throws MalformedURLException, IOException {
        ServerSocket serverSocket = new ServerSocket(12345);
        System.out.println("Localport: " + serverSocket.getLocalPort());
        System.out.println("InetAddress: " + serverSocket.getInetAddress());
    }
}

输出:

[Instrumentation] starting to instrument 'java.net.ServerSocket'
[Instrumentation] done 
[GetLocalPortIntercept] Localport: 42
[GetInetAddressIntercept] InetAddress: /1.2.3.4

如您所见,

拦截 getLocalPort getInetAddress 可以正常工作.但是为什么构造函数没有被拦截?

Intercepting getLocalPort and getInetAddress works fine as you can see. But why is the constructor not intercepted?

推荐答案

这是因为 ServerSocket 接受 int 而不是 Integer .但是,如果您尝试此操作,则会崩溃,因为JVM需要将超级方法调用硬编码到任何构造函数中.您需要先运行: SuperMethodCall.INSTANCE.andThen(...),然后才能进行实际拦截.

It's because ServerSocket accepts an int and not an Integer. It would however crash if you tried this since the JVM requires a super method call hard-coded into any constructor. You'd need to run: SuperMethodCall.INSTANCE.andThen(...) before your actual intercept to make it work.

通常,我建议您对JVM类上的此类引导代理使用 Advice ,您可以在其中将代码内联到目标中.这样会更健壮.

In general, I'd recommend you to use Advice for such bootstrap agents on JVM classes where you can inline code into a target. It would be more robust.

这篇关于Bytebuddy-拦截java.net.ServerSocket构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆