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;
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();

View File

@ -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;
}
}

View File

@ -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");
}

View File

@ -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<? extends InputSource> sourceList;
private ZipAligner zipAligner;
private ApkSignatureBlock apkSignatureBlock;
private APKLogger apkLogger;
public ApkWriter(File file, Collection<? extends InputSource> sourceList) throws IOException {
super(file);
@ -39,14 +43,21 @@ public class ApkWriter extends ZipFileOutput {
}
public void write()throws IOException {
List<OutputSource> 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<OutputSource> 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<OutputSource> 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<OutputSource> 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);
}
}
}