Bytebuddy-截取java.net.ServerSocket构造函数
我正试图截获Bytebuddy-截取java.net.ServerSocket构造函数,java,bytecode,byte-buddy,Java,Bytecode,Byte Buddy,我正试图截获java.net.ServerSocket的两个方法和一个构造函数。 拦截这两个方法getLocalPort和getInetAddress效果很好。但是,不会触发应该处理构造函数ServerSocket(int)的类。我的仪器代码(在main项目中包含的另一个jar文件中): 包装仪表 public class Instrumenting { private static final String CLASS_NAME = "java.net.ServerSocket";
java.net.ServerSocket
的两个方法和一个构造函数。
拦截这两个方法getLocalPort
和getInetAddress
效果很好。但是,不会触发应该处理构造函数ServerSocket(int)
的类。我的仪器代码(在main项目中包含的另一个jar文件中):
包装仪表
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});
}
}
}
输出:
[Instrumentation] starting to instrument 'java.net.ServerSocket'
[Instrumentation] done
[GetLocalPortIntercept] Localport: 42
[GetInetAddressIntercept] InetAddress: /1.2.3.4
正如您所看到的,拦截
getLocalPort
和getInetAddress
工作正常。但是为什么构造函数没有被拦截?这是因为ServerSocket
接受int
而不是整数。但是,如果您尝试这样做,它将崩溃,因为JVM需要硬编码到任何构造函数中的超级方法调用。您需要在实际截获之前运行:SuperMethodCall.INSTANCE。然后(…)
,以使其工作
一般来说,我建议您对JVM类上的此类引导代理使用Advice
,您可以将代码内联到目标中。它会更健壮。您使用的构造函数接受int
是正确的。但是,如果我不添加SuperMethodCall.INSTANCE
,它不会崩溃。自从我将.constructor(ElementMatchers.takesArguments(1)和(ElementMatchers.takesArguments(Integer.class))
更改为.constructor(ElementMatchers.any())
,一切正常。。
[Instrumentation] starting to instrument 'java.net.ServerSocket'
[Instrumentation] done
[GetLocalPortIntercept] Localport: 42
[GetInetAddressIntercept] InetAddress: /1.2.3.4