-
Notifications
You must be signed in to change notification settings - Fork 25.6k
improve support for bytecode patching signed jars #128613
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
0e4c087
1093646
58ca8d8
b7ea4e6
ee4def7
f0baf92
d6fb825
a973835
a4d9849
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,7 @@ | |
| import java.util.jar.JarEntry; | ||
| import java.util.jar.JarFile; | ||
| import java.util.jar.JarOutputStream; | ||
| import java.util.jar.Manifest; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| import static org.objectweb.asm.ClassWriter.COMPUTE_FRAMES; | ||
|
|
@@ -60,6 +61,10 @@ public String toString() { | |
| } | ||
| } | ||
|
|
||
| public static void patchJar(File inputJar, File outputJar, Collection<PatcherInfo> patchers) { | ||
| patchJar(inputJar, outputJar, patchers, false); | ||
| } | ||
|
|
||
| /** | ||
| * Patches the classes in the input JAR file, using the collection of patchers. Each patcher specifies a target class (its jar entry | ||
| * name) and the SHA256 digest on the class bytes. | ||
|
|
@@ -69,8 +74,11 @@ public String toString() { | |
| * @param inputFile the JAR file to patch | ||
| * @param outputFile the output (patched) JAR file | ||
| * @param patchers list of patcher info (classes to patch (jar entry name + optional SHA256 digest) and ASM visitor to transform them) | ||
| * @param unsignJar whether to remove class signatures from the JAR Manifest; set this to true when patching a signed JAR, | ||
| * otherwise the patched classes will fail to load at runtime due to mismatched signatures. | ||
| * @see <a href="https://docs.oracle.com/javase/tutorial/deployment/jar/intro.html">Understanding Signing and Verification</a> | ||
| */ | ||
| public static void patchJar(File inputFile, File outputFile, Collection<PatcherInfo> patchers) { | ||
| public static void patchJar(File inputFile, File outputFile, Collection<PatcherInfo> patchers, boolean unsignJar) { | ||
| var classPatchers = patchers.stream().collect(Collectors.toMap(PatcherInfo::jarEntryName, Function.identity())); | ||
| var mismatchedClasses = new ArrayList<MismatchInfo>(); | ||
| try (JarFile jarFile = new JarFile(inputFile); JarOutputStream jos = new JarOutputStream(new FileOutputStream(outputFile))) { | ||
|
|
@@ -101,9 +109,15 @@ public static void patchJar(File inputFile, File outputFile, Collection<PatcherI | |
| ); | ||
| } | ||
| } else { | ||
| // Read the entry's data and write it to the new JAR | ||
| try (InputStream is = jarFile.getInputStream(entry)) { | ||
| is.transferTo(jos); | ||
| if (unsignJar && entryName.equals("META-INF/MANIFEST.MF")) { | ||
| var manifest = new Manifest(jarFile.getInputStream(entry)); | ||
|
||
| manifest.getEntries().clear(); | ||
| manifest.write(jos); | ||
|
||
| } else if (unsignJar == false || entryName.matches("META-INF/.*\\.SF") == false) { | ||
|
||
| // Read the entry's data and write it to the new JAR | ||
| try (InputStream is = jarFile.getInputStream(entry)) { | ||
| is.transferTo(jos); | ||
| } | ||
| } | ||
| } | ||
| jos.closeEntry(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| pr: 128613 | ||
| summary: Improve support for bytecode patching signed jars | ||
| area: Infra/Core | ||
| type: enhancement | ||
| issues: [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the
unsignJarshould be the default behaviour since if there is a signature it will always be invalid after patching the jar. It also shouldn't impact existing usages of this method since they appear to not use signed jars (they work after patching).