From c83645d82ea88f68a97126aada6dccb97bf5fbee Mon Sep 17 00:00:00 2001 From: REAndroid Date: Tue, 25 Apr 2023 19:14:17 +0200 Subject: [PATCH] Write signature blocks #33 --- .../java/com/reandroid/apk/ApkBundle.java | 12 +++++ .../java/com/reandroid/apk/ApkModule.java | 22 ++++++--- .../java/com/reandroid/archive2/Archive.java | 4 +- .../reandroid/archive2/writer/ApkWriter.java | 46 ++++++++++++++++++- 4 files changed, 74 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/reandroid/apk/ApkBundle.java b/src/main/java/com/reandroid/apk/ApkBundle.java index 3e2bc81..6e99cb8 100644 --- a/src/main/java/com/reandroid/apk/ApkBundle.java +++ b/src/main/java/com/reandroid/apk/ApkBundle.java @@ -16,6 +16,7 @@ package com.reandroid.apk; import com.reandroid.archive.APKArchive; +import com.reandroid.archive2.block.ApkSignatureBlock; import com.reandroid.arsc.chunk.TableBlock; import com.reandroid.arsc.pool.TableStringPool; import com.reandroid.arsc.pool.builder.StringPoolMerger; @@ -48,12 +49,23 @@ public class ApkBundle { base=getLargestTableModule(); } result.merge(base); + ApkSignatureBlock signatureBlock = null; for(ApkModule module:moduleList){ + ApkSignatureBlock asb = module.getApkSignatureBlock(); if(module==base){ + if(asb != null){ + signatureBlock = asb; + } continue; } + if(signatureBlock == null){ + signatureBlock = asb; + } result.merge(module); } + + result.setApkSignatureBlock(signatureBlock); + if(result.hasTableBlock()){ TableBlock tableBlock=result.getTableBlock(); tableBlock.sortPackages(); diff --git a/src/main/java/com/reandroid/apk/ApkModule.java b/src/main/java/com/reandroid/apk/ApkModule.java index 17f2b30..ab1d8a2 100644 --- a/src/main/java/com/reandroid/apk/ApkModule.java +++ b/src/main/java/com/reandroid/apk/ApkModule.java @@ -17,6 +17,7 @@ package com.reandroid.apk; import com.reandroid.archive.*; import com.reandroid.archive2.Archive; +import com.reandroid.archive2.block.ApkSignatureBlock; import com.reandroid.archive2.writer.ApkWriter; import com.reandroid.arsc.ApkFile; import com.reandroid.arsc.array.PackageArray; @@ -55,12 +56,21 @@ public class ApkModule implements ApkFile { private APKLogger apkLogger; private Decoder mDecoder; private ApkType mApkType; + private ApkSignatureBlock apkSignatureBlock; public ApkModule(String moduleName, APKArchive apkArchive){ this.moduleName=moduleName; this.apkArchive=apkArchive; this.mUncompressedFiles=new UncompressedFiles(); this.mUncompressedFiles.addPath(apkArchive); } + + public ApkSignatureBlock getApkSignatureBlock() { + return apkSignatureBlock; + } + public void setApkSignatureBlock(ApkSignatureBlock apkSignatureBlock) { + this.apkSignatureBlock = apkSignatureBlock; + } + public String getSplit(){ if(!hasAndroidManifestBlock()){ return null; @@ -271,14 +281,10 @@ public class ApkModule implements ApkFile { manifest.setSort(0); } ApkWriter apkWriter = new ApkWriter(file, archive.listInputSources()); + apkWriter.setAPKLogger(getApkLogger()); + apkWriter.setApkSignatureBlock(getApkSignatureBlock()); apkWriter.write(); apkWriter.close(); - /* - ZipSerializer serializer=new ZipSerializer(archive.listInputSources()); - serializer.setWriteProgress(progress); - serializer.setWriteInterceptor(interceptor); - serializer.writeZip(file); - */ } private void uncompressNonXmlResFiles() { for(ResFile resFile:listResFiles()){ @@ -733,6 +739,8 @@ public class ApkModule implements ApkFile { } public static ApkModule loadApkFile(File apkFile, String moduleName) throws IOException { Archive archive = new Archive(apkFile); - return new ApkModule(moduleName, archive.createAPKArchive()); + ApkModule apkModule = new ApkModule(moduleName, archive.createAPKArchive()); + apkModule.setApkSignatureBlock(archive.getApkSignatureBlock()); + return apkModule; } } diff --git a/src/main/java/com/reandroid/archive2/Archive.java b/src/main/java/com/reandroid/archive2/Archive.java index 3af1760..425f3cb 100644 --- a/src/main/java/com/reandroid/archive2/Archive.java +++ b/src/main/java/com/reandroid/archive2/Archive.java @@ -90,7 +90,7 @@ public class Archive { return entryList; } - public ApkSignatureBlock getApkSigBlock() { + public ApkSignatureBlock getApkSignatureBlock() { return apkSignatureBlock; } public EndRecord getEndRecord() { @@ -122,7 +122,7 @@ public class Archive { } // for test public void writeSignatureData(File dir) throws IOException{ - ApkSignatureBlock apkSignatureBlock = getApkSigBlock(); + ApkSignatureBlock apkSignatureBlock = getApkSignatureBlock(); if(apkSignatureBlock == null){ throw new IOException("Does not have signature block"); } diff --git a/src/main/java/com/reandroid/archive2/writer/ApkWriter.java b/src/main/java/com/reandroid/archive2/writer/ApkWriter.java index 6e1a61f..7840450 100644 --- a/src/main/java/com/reandroid/archive2/writer/ApkWriter.java +++ b/src/main/java/com/reandroid/archive2/writer/ApkWriter.java @@ -15,9 +15,11 @@ */ package com.reandroid.archive2.writer; +import com.reandroid.apk.APKLogger; import com.reandroid.apk.RenamedInputSource; import com.reandroid.archive.InputSource; import com.reandroid.archive2.ZipSignature; +import com.reandroid.archive2.block.ApkSignatureBlock; import com.reandroid.archive2.block.EndRecord; import com.reandroid.archive2.io.ArchiveEntrySource; import com.reandroid.archive2.io.ZipFileOutput; @@ -31,6 +33,8 @@ import java.util.List; public class ApkWriter extends ZipFileOutput { private final Collection sourceList; private ZipAligner zipAligner; + private ApkSignatureBlock apkSignatureBlock; + private APKLogger apkLogger; public ApkWriter(File file, Collection sourceList) throws IOException { super(file); @@ -39,14 +43,21 @@ public class ApkWriter extends ZipFileOutput { } public void write()throws IOException { List outputList = buildOutputEntry(); + logMessage("Buffering compress changed files ..."); BufferFileInput buffer = writeBuffer(outputList); buffer.unlock(); align(outputList); writeApk(outputList); - writeCEH(outputList); buffer.close(); + + writeSignatureBlock(); + + writeCEH(outputList); this.close(); } + public void setApkSignatureBlock(ApkSignatureBlock apkSignatureBlock) { + this.apkSignatureBlock = apkSignatureBlock; + } public ZipAligner getZipAligner() { return zipAligner; } @@ -55,6 +66,7 @@ public class ApkWriter extends ZipFileOutput { } private void writeCEH(List outputList) throws IOException{ + logMessage("Writing CEH ..."); EndRecord endRecord = new EndRecord(); endRecord.setSignature(ZipSignature.END_RECORD); long offset = position(); @@ -69,10 +81,19 @@ public class ApkWriter extends ZipFileOutput { endRecord.writeBytes(getOutputStream()); } private void writeApk(List outputList) throws IOException{ + logMessage("Writing files: " + outputList.size()); for(OutputSource outputSource:outputList){ outputSource.writeApk( this); } } + private void writeSignatureBlock() throws IOException { + ApkSignatureBlock signatureBlock = this.apkSignatureBlock; + if(signatureBlock == null){ + return; + } + logMessage("Writing signature block ..."); + signatureBlock.writeBytes(getOutputStream()); + } private BufferFileInput writeBuffer(List outputList) throws IOException { File bufferFile = getBufferFile(); BufferFileOutput output = new BufferFileOutput(bufferFile); @@ -87,6 +108,7 @@ public class ApkWriter extends ZipFileOutput { ZipAligner aligner = getZipAligner(); if(aligner!=null){ aligner.reset(); + logMessage("Zip align ..."); } for(OutputSource outputSource:outputList){ outputSource.align(aligner); @@ -127,4 +149,26 @@ public class ApkWriter extends ZipFileOutput { return new OutputSource(inputSource); } + APKLogger getApkLogger(){ + return apkLogger; + } + public void setAPKLogger(APKLogger logger) { + this.apkLogger = logger; + } + private void logMessage(String msg) { + if(apkLogger!=null){ + apkLogger.logMessage(msg); + } + } + private void logError(String msg, Throwable tr) { + if(apkLogger!=null){ + apkLogger.logError(msg, tr); + } + } + private void logVerbose(String msg) { + if(apkLogger!=null){ + apkLogger.logVerbose(msg); + } + } + }