diff --git a/patch/src/main/java/org/lsposed/patch/LSPatch.java b/patch/src/main/java/org/lsposed/patch/LSPatch.java index a685a19..e4c0cc3 100644 --- a/patch/src/main/java/org/lsposed/patch/LSPatch.java +++ b/patch/src/main/java/org/lsposed/patch/LSPatch.java @@ -288,7 +288,6 @@ public class LSPatch { new SigningExtension(SigningOptions.builder() .setMinSdkVersion(27) .setV1SigningEnabled(v1) - // Don't know why it crashes !! .setV2SigningEnabled(v2) .setCertificates((X509Certificate[]) entry.getCertificateChain()) .setKey(entry.getPrivateKey()) @@ -297,13 +296,11 @@ public class LSPatch { throw new PatchError("Failed to sign apk: " + e.getMessage()); } - dstZFile.update(); - FileUtils.copyFile(tmpApk, outputFile); - System.out.println("Done. Output APK: " + outputFile.getAbsolutePath()); } finally { try { - tmpApk.delete(); + outputFile.delete(); + FileUtils.moveFile(tmpApk, outputFile); } catch (Throwable ignored) { } } diff --git a/patch/src/main/java/org/lsposed/patch/util/NestedZipLink.java b/patch/src/main/java/org/lsposed/patch/util/NestedZipLink.java index 4f99ba5..f7ad57f 100644 --- a/patch/src/main/java/org/lsposed/patch/util/NestedZipLink.java +++ b/patch/src/main/java/org/lsposed/patch/util/NestedZipLink.java @@ -6,11 +6,11 @@ import com.android.tools.build.apkzlib.zip.StoredEntry; import com.android.tools.build.apkzlib.zip.ZFile; import com.android.tools.build.apkzlib.zip.ZFileExtension; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.HashSet; +import java.util.Map; import java.util.Set; public class NestedZipLink extends ZFileExtension { @@ -54,14 +54,7 @@ public class NestedZipLink extends ZFileExtension { deleteDirectoryAndEocd.setAccessible(true); deleteDirectoryAndEocd.invoke(zFile); appendEntries(); - Method computeCentralDirectory = ZFile.class.getDeclaredMethod("computeCentralDirectory"); - computeCentralDirectory.setAccessible(true); - computeCentralDirectory.invoke(zFile); - Method computeEocd = ZFile.class.getDeclaredMethod("computeEocd"); - computeEocd.setAccessible(true); - computeEocd.invoke(zFile); } catch (Exception e) { - e.printStackTrace(); var ex = new IOException("Error when writing link entries"); ex.addSuppressed(e); throw ex; @@ -69,39 +62,44 @@ public class NestedZipLink extends ZFileExtension { written = true; } - private void appendEntries() throws IOException { + private void appendEntries() throws Exception { + Field field_entry_file = StoredEntry.class.getDeclaredField("file"); + field_entry_file.setAccessible(true); + + Field field_entries = ZFile.class.getDeclaredField("entries"); + field_entries.setAccessible(true); + + Field field_cdh_file = CentralDirectoryHeader.class.getDeclaredField("file"); + field_cdh_file.setAccessible(true); + + Field field_offset = CentralDirectoryHeader.class.getDeclaredField("offset"); + field_offset.setAccessible(true); + + Method makeFree = Class.forName("com.android.tools.build.apkzlib.zip.FileUseMapEntry") + .getDeclaredMethod("makeUsed", long.class, long.class, Object.class); + makeFree.setAccessible(true); + + Method computeCentralDirectory = ZFile.class.getDeclaredMethod("computeCentralDirectory"); + computeCentralDirectory.setAccessible(true); + + Method computeEocd = ZFile.class.getDeclaredMethod("computeEocd"); + computeEocd.setAccessible(true); + + var entries = (Map) field_entries.get(zFile); for (var nestedZip : nestedZips) { long nestedZipOffset = nestedZip.entry.getCentralDirectoryHeader().getOffset(); for (var link : nestedZip.links) { var entry = nestedZip.zip.get(link); if (entry == null) throw new IOException("Entry " + link + " does not exist in nested zip"); CentralDirectoryHeader cdh = entry.getCentralDirectoryHeader(); - CentralDirectoryHeader clonedCdh; - - try { - Method clone = CentralDirectoryHeader.class.getDeclaredMethod("clone"); - clone.setAccessible(true); - clonedCdh = (CentralDirectoryHeader) clone.invoke(cdh); - - zFile.add(link, new ByteArrayInputStream(new byte[0])); - StoredEntry newEntry = zFile.get(link); - - Field field_file = CentralDirectoryHeader.class.getDeclaredField("file"); - field_file.setAccessible(true); - field_file.set(clonedCdh, zFile); - - Field field_offset = CentralDirectoryHeader.class.getDeclaredField("offset"); - field_offset.setAccessible(true); - - field_offset.set(clonedCdh, nestedZipOffset + cdh.getOffset() + nestedZip.entry.getLocalHeaderSize()); - - Field field_cdh = StoredEntry.class.getDeclaredField("cdh"); - field_cdh.setAccessible(true); - field_cdh.set(newEntry, clonedCdh); - } catch (Exception e) { - e.printStackTrace(); - } + field_entry_file.set(entry, zFile); + field_cdh_file.set(cdh, zFile); + field_offset.set(cdh, nestedZipOffset + cdh.getOffset() + nestedZip.entry.getLocalHeaderSize()); + var newFileUseMapEntry = makeFree.invoke(null, 0, 1, entry); + entries.put(link, newFileUseMapEntry); } } + computeCentralDirectory.invoke(zFile); + computeEocd.invoke(zFile); } } \ No newline at end of file