Alex Rivera | Logout

Change string constant in a compiled class

Asked 2012-05-21T08:45:30.180
15

I need to change a string constant in a deployed Java program, i.e. the value inside the compiled .class-files. It can be restarted, but not easily recompiled (though it's an inconvenient option if this question yields no answers). Is this possible?

Update: I just looked at the file with a hex editor and it looks like I can easily change the string there. Would that work, i.e. won't that invalidate some kind of signature of the file? The old and new string are both alphanumeric, and can be the same length if needed.

Update 2: I fixed it. Because the specific class I needed to change is very small and didn't change in the new version of the project, I could just compile that and take the new class from there. Still interested in an answer that doesn't involve compilation though, for educational purposes.

Edit
Report

1 Answer

8

If you have the sources for this class, then my approach is:

  • Get the JAR file
  • Get the source for the single class
  • Compile the source with the JAR on the classpath (that way, you don't have to compile anything else; it doesn't hurt that the JAR already contains the binary). You can use the latest Java version for this; just downgrade the compiler using -source and -target.
  • Replace the class file in the JAR with the new one using jar u or an Ant task

Example for an Ant task:

        <jar destfile="${jar}"
            compress="true" update="true" duplicate="preserve" index="true"
            manifest="tmp/META-INF/MANIFEST.MF"
        >
            <fileset dir="build/classes">
                <filter />
            </fileset>
            <zipfileset src="${origJar}">
                <exclude name="META-INF/*"/>
            </zipfileset>
        </jar>

Here I also update the manifest. Put the new classes first and then add all the files from the original JAR. duplicate="preserve" will make sure that the new code will not be overwritten.

If the code isn't signed, you can also try to replace the bytes if the new string has the exact same length as the old one. Java does some checks on the code but there is no checksum in the .class files.

You must preserve the length; otherwise the class loader will get confused.

answered 2012-05-21T09:02:55.623

Your Answer