我正在开发一个项目,需要在连接套接字后立即将一些标头写入套接字输出流。
我想在低级别拦截,例如
java.net.Socket
及其连接函数public void connect(SocketAddress endpoint, int timeout)
。
变换函数如下所示
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;
}
我已经确认
java.net.Socket.connect()
被调用,但字节码似乎永远无法工作。我尝试在字符串中附加一些虚拟值,但仍然没有错误。
有趣的是,下面的内容适用于
java.net.SocksSocketImpl
。所以我无法弄清楚出了什么问题。
我可以在这里寻求帮助吗?
谢谢!
后来我自己解决了这个问题。
connect
中有多种java.net.Socket
重载方法。在上面的代码中,我没有检查参数和方法体。所以我得到了一个只有一个参数且没有方法体的抽象方法。将字节码注入没有主体的方法会导致错误。
我最终添加了对参数编号和类型以及主体的检查,并成功地检测了该方法。