Write signature blocks #33

This commit is contained in:
REAndroid 2023-04-25 19:14:17 +02:00
parent f8476916ad
commit c83645d82e
4 changed files with 74 additions and 10 deletions

View File

@ -16,6 +16,7 @@
package com.reandroid.apk; package com.reandroid.apk;
import com.reandroid.archive.APKArchive; import com.reandroid.archive.APKArchive;
import com.reandroid.archive2.block.ApkSignatureBlock;
import com.reandroid.arsc.chunk.TableBlock; import com.reandroid.arsc.chunk.TableBlock;
import com.reandroid.arsc.pool.TableStringPool; import com.reandroid.arsc.pool.TableStringPool;
import com.reandroid.arsc.pool.builder.StringPoolMerger; import com.reandroid.arsc.pool.builder.StringPoolMerger;
@ -48,12 +49,23 @@ public class ApkBundle {
base=getLargestTableModule(); base=getLargestTableModule();
} }
result.merge(base); result.merge(base);
ApkSignatureBlock signatureBlock = null;
for(ApkModule module:moduleList){ for(ApkModule module:moduleList){
ApkSignatureBlock asb = module.getApkSignatureBlock();
if(module==base){ if(module==base){
if(asb != null){
signatureBlock = asb;
}
continue; continue;
} }
if(signatureBlock == null){
signatureBlock = asb;
}
result.merge(module); result.merge(module);
} }
result.setApkSignatureBlock(signatureBlock);
if(result.hasTableBlock()){ if(result.hasTableBlock()){
TableBlock tableBlock=result.getTableBlock(); TableBlock tableBlock=result.getTableBlock();
tableBlock.sortPackages(); tableBlock.sortPackages();

View File

@ -17,6 +17,7 @@ package com.reandroid.apk;
import com.reandroid.archive.*; import com.reandroid.archive.*;
import com.reandroid.archive2.Archive; import com.reandroid.archive2.Archive;
import com.reandroid.archive2.block.ApkSignatureBlock;
import com.reandroid.archive2.writer.ApkWriter; import com.reandroid.archive2.writer.ApkWriter;
import com.reandroid.arsc.ApkFile; import com.reandroid.arsc.ApkFile;
import com.reandroid.arsc.array.PackageArray; import com.reandroid.arsc.array.PackageArray;
@ -55,12 +56,21 @@ public class ApkModule implements ApkFile {
private APKLogger apkLogger; private APKLogger apkLogger;
private Decoder mDecoder; private Decoder mDecoder;
private ApkType mApkType; private ApkType mApkType;
private ApkSignatureBlock apkSignatureBlock;
public ApkModule(String moduleName, APKArchive apkArchive){ public ApkModule(String moduleName, APKArchive apkArchive){
this.moduleName=moduleName; this.moduleName=moduleName;
this.apkArchive=apkArchive; this.apkArchive=apkArchive;
this.mUncompressedFiles=new UncompressedFiles(); this.mUncompressedFiles=new UncompressedFiles();
this.mUncompressedFiles.addPath(apkArchive); this.mUncompressedFiles.addPath(apkArchive);
} }
public ApkSignatureBlock getApkSignatureBlock() {
return apkSignatureBlock;
}
public void setApkSignatureBlock(ApkSignatureBlock apkSignatureBlock) {
this.apkSignatureBlock = apkSignatureBlock;
}
public String getSplit(){ public String getSplit(){
if(!hasAndroidManifestBlock()){ if(!hasAndroidManifestBlock()){
return null; return null;
@ -271,14 +281,10 @@ public class ApkModule implements ApkFile {
manifest.setSort(0); manifest.setSort(0);
} }
ApkWriter apkWriter = new ApkWriter(file, archive.listInputSources()); ApkWriter apkWriter = new ApkWriter(file, archive.listInputSources());
apkWriter.setAPKLogger(getApkLogger());
apkWriter.setApkSignatureBlock(getApkSignatureBlock());
apkWriter.write(); apkWriter.write();
apkWriter.close(); apkWriter.close();
/*
ZipSerializer serializer=new ZipSerializer(archive.listInputSources());
serializer.setWriteProgress(progress);
serializer.setWriteInterceptor(interceptor);
serializer.writeZip(file);
*/
} }
private void uncompressNonXmlResFiles() { private void uncompressNonXmlResFiles() {
for(ResFile resFile:listResFiles()){ for(ResFile resFile:listResFiles()){
@ -733,6 +739,8 @@ public class ApkModule implements ApkFile {
} }
public static ApkModule loadApkFile(File apkFile, String moduleName) throws IOException { public static ApkModule loadApkFile(File apkFile, String moduleName) throws IOException {
Archive archive = new Archive(apkFile); Archive archive = new Archive(apkFile);
return new ApkModule(moduleName, archive.createAPKArchive()); ApkModule apkModule = new ApkModule(moduleName, archive.createAPKArchive());
apkModule.setApkSignatureBlock(archive.getApkSignatureBlock());
return apkModule;
} }
} }

View File

@ -90,7 +90,7 @@ public class Archive {
return entryList; return entryList;
} }
public ApkSignatureBlock getApkSigBlock() { public ApkSignatureBlock getApkSignatureBlock() {
return apkSignatureBlock; return apkSignatureBlock;
} }
public EndRecord getEndRecord() { public EndRecord getEndRecord() {
@ -122,7 +122,7 @@ public class Archive {
} }
// for test // for test
public void writeSignatureData(File dir) throws IOException{ public void writeSignatureData(File dir) throws IOException{
ApkSignatureBlock apkSignatureBlock = getApkSigBlock(); ApkSignatureBlock apkSignatureBlock = getApkSignatureBlock();
if(apkSignatureBlock == null){ if(apkSignatureBlock == null){
throw new IOException("Does not have signature block"); throw new IOException("Does not have signature block");
} }

View File

@ -15,9 +15,11 @@
*/ */
package com.reandroid.archive2.writer; package com.reandroid.archive2.writer;
import com.reandroid.apk.APKLogger;
import com.reandroid.apk.RenamedInputSource; import com.reandroid.apk.RenamedInputSource;
import com.reandroid.archive.InputSource; import com.reandroid.archive.InputSource;
import com.reandroid.archive2.ZipSignature; import com.reandroid.archive2.ZipSignature;
import com.reandroid.archive2.block.ApkSignatureBlock;
import com.reandroid.archive2.block.EndRecord; import com.reandroid.archive2.block.EndRecord;
import com.reandroid.archive2.io.ArchiveEntrySource; import com.reandroid.archive2.io.ArchiveEntrySource;
import com.reandroid.archive2.io.ZipFileOutput; import com.reandroid.archive2.io.ZipFileOutput;
@ -31,6 +33,8 @@ import java.util.List;
public class ApkWriter extends ZipFileOutput { public class ApkWriter extends ZipFileOutput {
private final Collection<? extends InputSource> sourceList; private final Collection<? extends InputSource> sourceList;
private ZipAligner zipAligner; private ZipAligner zipAligner;
private ApkSignatureBlock apkSignatureBlock;
private APKLogger apkLogger;
public ApkWriter(File file, Collection<? extends InputSource> sourceList) throws IOException { public ApkWriter(File file, Collection<? extends InputSource> sourceList) throws IOException {
super(file); super(file);
@ -39,14 +43,21 @@ public class ApkWriter extends ZipFileOutput {
} }
public void write()throws IOException { public void write()throws IOException {
List<OutputSource> outputList = buildOutputEntry(); List<OutputSource> outputList = buildOutputEntry();
logMessage("Buffering compress changed files ...");
BufferFileInput buffer = writeBuffer(outputList); BufferFileInput buffer = writeBuffer(outputList);
buffer.unlock(); buffer.unlock();
align(outputList); align(outputList);
writeApk(outputList); writeApk(outputList);
writeCEH(outputList);
buffer.close(); buffer.close();
writeSignatureBlock();
writeCEH(outputList);
this.close(); this.close();
} }
public void setApkSignatureBlock(ApkSignatureBlock apkSignatureBlock) {
this.apkSignatureBlock = apkSignatureBlock;
}
public ZipAligner getZipAligner() { public ZipAligner getZipAligner() {
return zipAligner; return zipAligner;
} }
@ -55,6 +66,7 @@ public class ApkWriter extends ZipFileOutput {
} }
private void writeCEH(List<OutputSource> outputList) throws IOException{ private void writeCEH(List<OutputSource> outputList) throws IOException{
logMessage("Writing CEH ...");
EndRecord endRecord = new EndRecord(); EndRecord endRecord = new EndRecord();
endRecord.setSignature(ZipSignature.END_RECORD); endRecord.setSignature(ZipSignature.END_RECORD);
long offset = position(); long offset = position();
@ -69,10 +81,19 @@ public class ApkWriter extends ZipFileOutput {
endRecord.writeBytes(getOutputStream()); endRecord.writeBytes(getOutputStream());
} }
private void writeApk(List<OutputSource> outputList) throws IOException{ private void writeApk(List<OutputSource> outputList) throws IOException{
logMessage("Writing files: " + outputList.size());
for(OutputSource outputSource:outputList){ for(OutputSource outputSource:outputList){
outputSource.writeApk( this); 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<OutputSource> outputList) throws IOException { private BufferFileInput writeBuffer(List<OutputSource> outputList) throws IOException {
File bufferFile = getBufferFile(); File bufferFile = getBufferFile();
BufferFileOutput output = new BufferFileOutput(bufferFile); BufferFileOutput output = new BufferFileOutput(bufferFile);
@ -87,6 +108,7 @@ public class ApkWriter extends ZipFileOutput {
ZipAligner aligner = getZipAligner(); ZipAligner aligner = getZipAligner();
if(aligner!=null){ if(aligner!=null){
aligner.reset(); aligner.reset();
logMessage("Zip align ...");
} }
for(OutputSource outputSource:outputList){ for(OutputSource outputSource:outputList){
outputSource.align(aligner); outputSource.align(aligner);
@ -127,4 +149,26 @@ public class ApkWriter extends ZipFileOutput {
return new OutputSource(inputSource); 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);
}
}
} }