Yes, what you can do is patch the JarVerifier.class file inside jce.jar. Jce.jar is part of your JRE/JDK (depends whether you have just the Runtime Environment or the Development Kit installed). This method is tedious and involved, but it’s the best way to ensure you don’t touch any other code besides the jar verification code.
For these steps you will need the JDK installed, as well as a hex editor.
On my Windows installation for example, jce.jar is located at C:\Program Files\Java\jdk1.8.0_77\jre\lib\jce.jar.
Once you’ve found it, open jce.jar in a zip file editor (e.g. WinZip, 7zip). Navigate to javax\crypto\ and extract JarVerifier.class to your Desktop or other desired location to work on it. Also, make a backup copy of this file!!
Now here comes the detective work. Open a terminal and cd to where you extracted JarVerifier.class. Run this command: javap -c JarVerifier.class
This will show you a reconstructed Java bytecode version of the code in the class file. You’ll see a method called void verify() throws ... JarException ....
In my version of the JRE, the code for verify() begins as follows:
aload_0
getfield #15
ifnonnull 17
new #20
etc...
The verify method works by using exceptions to tell the calling method if the given jar is not properly signed. If no exceptions are thrown, then it is assumed that everything is OK, and the JCE provider can be used. We can use this to our advantage by simply changing the first instruction of the verify() method to the op-code for return.
Pull up this webpage of Java bytecode instructions as a reference: https://en.m.wikipedia.org/wiki/Java_bytecode_instruction_listings. We want to find where exactly this sequence of instructions is inside our JarVerifier.class file, so we need to convert the bytecode printed out by javap earlier to hexadecimal numbers. We will then search for this string of numbers inside JarVerifier.class to find exactly where the verify() method is.
So.. using the Wikipedia page as reference, it goes like this:
- aload_0:
2A
- getfield #15:
B4 00 0F
- ifnonnull 17:
C7 <2 byte branch offset>
- new #20:
BB 00 14
It’s a little tedious to calculate the branch offset, and we don’t need it in our search.
Now, search for the following hex string of bytes: 2AB4000FC7. In my version of the JRE there is only one match. Verify that BB 00 14 is also present 2 bytes after C7, just to make sure this is really the verify() method.
Finally, the patch. The opcode for return is B1. Simply replace the 2A representing aload_0 with the value B1. In my version, this was at the offset 0x2938. Now, all verify() does is just return!
Save your file, exit, and run the above javap command on your new JarVerifier.class file to see the result of your change. You should see that the first instruction in verify() is a return.
Using your zip file editor from above, replace JarVerifier.class inside jce.jar with your modified version. Save the jar file if necessary.
That’s it! JCE jar verification has been disabled.