嘿伙计们,我正在尝试拦截sun.security.ssl.ServerHandshaker
的负载并添加字节码以打印几个私有字段。
这是我尝试添加的代码:
public static final String printCLIENT_RANDOM_CODE =
"System.out.println("this.clnt_random:"+this.clnt_random);n"
+ "System.out.println("this.session:"+this.session);";
这是执行增强的功能。 classfileBuffer
是原始字节码,className
是类名,insertAfterJavaCode
将是上面的printCLIENT_RANDOM_CODE
private byte[] instrument(byte[] classfileBuffer, String className, String insertAfterJavaCode) throws Exception {
System.out.println("Attempting to enhance " + className + "...");
ClassPool cp = ClassPool.getDefault();
cp.insertClassPath(new ByteArrayClassPath(className, classfileBuffer));
CtClass cc = cp.get(className);
CtConstructor[] declaredConstructors = cc.getDeclaredConstructors();
for (CtConstructor con : declaredConstructors) {
con.insertAfter(insertAfterJavaCode);
}
return cc.toBytecode();
}
但是,当它运行时,我得到这个:
Attempting to enhance sun.security.ssl.ServerHandshaker...
this.clnt_random:null
this.session:null
为什么?如果您查看源代码,这些字段应该在构造函数的末尾初始化。什么给?
您提到的字段未在构造函数中初始化。例如,如果您查看链接的源代码并搜索clnt_random
,您会发现它只设置在一个地方:clientHello
方法。(clnt_random
在基类Handshaker
中定义,但Handshaker
也没有在任何地方初始化它)。
由于clnt_random
是一个对象类型,因此它具有初始值 null,并且不会在构造函数中的任何位置为其分配新值,因此在调用代码时它仍将为 null。
你不会在源代码中找到任何内容。这是Java安全管理器在这里启动。
由于您没有提供自己的安全管理器实例,因此提供了默认值。缺省 Java 安全管理器由 ${JAVA_HOME}/jre/lib/security/java.security
配置。在此文件中,您将找到以下行:
...
# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.,
com.sun.xml.internal.,
...
这就是您的异常的来源。
安全经理是一件好事。不同的沙箱需要不同的安全管理器。例如,有一个用于安全运行小程序的管理器。