Reputation: 23
I am working on a project where I need to write some header to the socket output stream right after the socket is connected.
I want to intercept at low level such as java.net.Socket
and its connect function public void connect(SocketAddress endpoint, int timeout)
.
The transform function looks like below
public static byte[] transform(final ClassLoader loader, final String className, final byte[] classFileBuffer) {
loader.loadClass(...);
final ClassPool classPool = ClassPool.getDefault();
classPool.appendClassPath(new LoaderClassPath(loader));
classPool.appendSystemPath();
classPool.importPackage(...)
final CtClass ctClass = classPool.makeClass(new ByteArrayInputStream(classFileBuffer));
if (className.equals("java/net/Socket")) {
final CtMethod method = ctClass.getDeclaredMethod("connect");
final String s = "System.out.println(\"I am in Socket.connect!\");";
method.insertAfter(s);
return ctClass.toBytecode();
}
return classFileBuffer;
}
I have confirmed that java.net.Socket.connect()
is called but the byte code seems to never work. I tried having some dummy in the string appended and still no error.
Interesting thing is that below works for java.net.SocksSocketImpl
. So I cannot figure out what is wrong.
Can I please get some help here?
Thanks!
Upvotes: 1
Views: 73
Reputation: 23
I figured out the problem myself later. There are multiple connect
overloading methods in java.net.Socket
. In my code above I did not check the parameters and method body. So I got an abstract method with one parameter and no method body. Injecting byte code to method without body will lead to an error.
I ended up by adding check on parameter numbers and types plus body and succeeded in instrumenting the method.
Upvotes: 0