Search code examples
javasslbytecodejavassistjavaagents

Javassist reports fields are null after being initialized in constructor


Hey guys I'm attempting to intercept the load of sun.security.ssl.ServerHandshaker and add byte code to print a couple of the private fields.

Here is the code I'm attempting to add:

public static final String printCLIENT_RANDOM_CODE = 
    "System.out.println(\"this.clnt_random:\"+this.clnt_random);\n"
        + "System.out.println(\"this.session:\"+this.session);";

Here is the function that does the enhancement. classfileBuffer is the original byte code, className is the classname, and insertAfterJavaCode will be the above 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();
}

When it runs, however, I get this:

Attempting to enhance sun.security.ssl.ServerHandshaker...
this.clnt_random:null
this.session:null

Why is that? If you look at the source code those fields should be initialized by the end of the constructor. What gives?


Solution

  • The fields you mentioned aren't initialized in the constructor. If you look at the source code you linked and search for clnt_random for example, you'll find that it is only set in one place: the clientHello method. (clnt_random is defined in the base class Handshaker, but Handshaker does not initialize it anywhere either).

    Since clnt_random is an object type, it has initial value null, and it is not assigned a new value anywhere in the constructors, so it will still be null when your code is called.