mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-04-29 22:04:25 +02:00
Write signature blocks #33
This commit is contained in:
parent
f8476916ad
commit
c83645d82e
@ -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();
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user