mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-04-29 22:04:25 +02:00
update signature block PADDING
This commit is contained in:
parent
f0c2ebb97d
commit
6e73da3326
@ -120,12 +120,4 @@ public class Archive {
|
||||
String name = archiveEntry.getName().replace('/', File.separatorChar);
|
||||
return new File(dir, name);
|
||||
}
|
||||
// for test
|
||||
public void writeSignatureData(File dir) throws IOException{
|
||||
ApkSignatureBlock apkSignatureBlock = getApkSignatureBlock();
|
||||
if(apkSignatureBlock == null){
|
||||
throw new IOException("Does not have signature block");
|
||||
}
|
||||
apkSignatureBlock.writeSignatureData(dir);
|
||||
}
|
||||
}
|
||||
|
@ -16,21 +16,61 @@
|
||||
package com.reandroid.archive2.block;
|
||||
|
||||
|
||||
import com.reandroid.archive2.block.pad.SchemePadding;
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class ApkSignatureBlock extends LengthPrefixedList<SignatureInfo> {
|
||||
public class ApkSignatureBlock extends LengthPrefixedList<SignatureInfo>
|
||||
implements Comparator<SignatureInfo> {
|
||||
public ApkSignatureBlock(SignatureFooter signatureFooter){
|
||||
super(true);
|
||||
setBottomBlock(signatureFooter);
|
||||
}
|
||||
public ApkSignatureBlock(){
|
||||
this(new SignatureFooter());
|
||||
}
|
||||
public List<SignatureInfo> getSignatures(){
|
||||
return super.getElements();
|
||||
}
|
||||
public int countSignatures(){
|
||||
return super.getElementsCount();
|
||||
}
|
||||
public void sortSignatures(){
|
||||
sort(this);
|
||||
}
|
||||
public void updatePadding(){
|
||||
SchemePadding schemePadding = getOrCreateSchemePadding();
|
||||
schemePadding.setPadding(0);
|
||||
sortSignatures();
|
||||
refresh();
|
||||
int size = countBytes();
|
||||
int alignment = 4096;
|
||||
int padding = (alignment - (size % alignment)) % alignment;
|
||||
schemePadding.setPadding(padding);
|
||||
refresh();
|
||||
}
|
||||
private SchemePadding getOrCreateSchemePadding(){
|
||||
SignatureInfo signatureInfo = getSignature(SignatureId.PADDING);
|
||||
if(signatureInfo == null){
|
||||
signatureInfo = new SignatureInfo();
|
||||
signatureInfo.setId(SignatureId.PADDING);
|
||||
signatureInfo.setSignatureScheme(new SchemePadding());
|
||||
add(signatureInfo);
|
||||
}
|
||||
SignatureScheme scheme = signatureInfo.getSignatureScheme();
|
||||
if(!(scheme instanceof SchemePadding)){
|
||||
scheme = new SchemePadding();
|
||||
signatureInfo.setSignatureScheme(scheme);
|
||||
}
|
||||
return (SchemePadding) scheme;
|
||||
}
|
||||
public SignatureInfo getSignature(SignatureId signatureId){
|
||||
for(SignatureInfo signatureInfo:getSignatures()){
|
||||
if(signatureInfo.getId().equals(signatureId)){
|
||||
@ -53,26 +93,69 @@ public class ApkSignatureBlock extends LengthPrefixedList<SignatureInfo> {
|
||||
super.onRefreshed();
|
||||
footer.setSignatureSize(getDataSize());
|
||||
}
|
||||
// for test
|
||||
public void writeSignatureData(File dir) throws IOException{
|
||||
for(SignatureInfo signatureInfo:getElements()){
|
||||
signatureInfo.writeToDir(dir);
|
||||
|
||||
public void writeRaw(File file) throws IOException{
|
||||
refresh();
|
||||
File dir = file.getParentFile();
|
||||
if(dir != null && !dir.exists()){
|
||||
dir.mkdirs();
|
||||
}
|
||||
FileOutputStream outputStream = new FileOutputStream(file);
|
||||
writeBytes(outputStream);
|
||||
outputStream.close();
|
||||
}
|
||||
public List<File> writeSplitRawToDirectory(File dir) throws IOException{
|
||||
refresh();
|
||||
List<SignatureInfo> signatureInfoList = getElements();
|
||||
List<File> writtenFiles = new ArrayList<>(signatureInfoList.size());
|
||||
for(SignatureInfo signatureInfo:signatureInfoList){
|
||||
File file = signatureInfo.writeRawToDirectory(dir);
|
||||
writtenFiles.add(file);
|
||||
}
|
||||
return writtenFiles;
|
||||
}
|
||||
public void read(File file) throws IOException {
|
||||
super.readBytes(new BlockReader(file));
|
||||
}
|
||||
public void scanSplitFiles(File dir) throws IOException {
|
||||
if(!dir.isDirectory()){
|
||||
throw new IOException("No such directory");
|
||||
}
|
||||
FileFilter filter = new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
if(!file.isFile()){
|
||||
return false;
|
||||
}
|
||||
String name = file.getName().toLowerCase();
|
||||
return name.endsWith(SignatureId.FILE_EXT_RAW);
|
||||
}
|
||||
};
|
||||
File[] files = dir.listFiles(filter);
|
||||
if(files == null){
|
||||
return;
|
||||
}
|
||||
for(File file:files){
|
||||
addSplitRaw(file);
|
||||
}
|
||||
sortSignatures();
|
||||
}
|
||||
public SignatureInfo addSplitRaw(File signatureInfoFile) throws IOException {
|
||||
SignatureInfo signatureInfo = new SignatureInfo();
|
||||
signatureInfo.read(signatureInfoFile);
|
||||
add(signatureInfo);
|
||||
return signatureInfo;
|
||||
}
|
||||
@Override
|
||||
public int compare(SignatureInfo info1, SignatureInfo info2) {
|
||||
if(SignatureId.PADDING.equals(info1.getId())){
|
||||
return 0;
|
||||
}
|
||||
if(SignatureId.PADDING.equals(info2.getId())){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static final long CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES = 1024 * 1024;
|
||||
public static final int ANDROID_COMMON_PAGE_ALIGNMENT_BYTES = 4096;
|
||||
|
||||
private static final byte[] APK_SIGNING_BLOCK_MAGIC = new byte[] {
|
||||
0x41, 0x50, 0x4b, 0x20, 0x53, 0x69, 0x67, 0x20,
|
||||
0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x34, 0x32,
|
||||
};
|
||||
|
||||
public static final int VERSION_SOURCE_STAMP = 0;
|
||||
public static final int VERSION_JAR_SIGNATURE_SCHEME = 1;
|
||||
public static final int VERSION_APK_SIGNATURE_SCHEME_V2 = 2;
|
||||
public static final int VERSION_APK_SIGNATURE_SCHEME_V3 = 3;
|
||||
public static final int VERSION_APK_SIGNATURE_SCHEME_V31 = 31;
|
||||
public static final int VERSION_APK_SIGNATURE_SCHEME_V4 = 4;
|
||||
|
||||
public static final String FILE_EXT = ".signature.block.bin";
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import com.reandroid.arsc.item.IntegerItem;
|
||||
import com.reandroid.arsc.item.LongItem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class LengthPrefixedList<T extends Block> extends FixedBlockContainer
|
||||
@ -75,6 +76,9 @@ public abstract class LengthPrefixedList<T extends Block> extends FixedBlockCont
|
||||
public boolean remove(T element){
|
||||
return this.elements.remove(element);
|
||||
}
|
||||
public void sort(Comparator<T> comparator){
|
||||
this.elements.sort(comparator);
|
||||
}
|
||||
@Override
|
||||
public void onReadBytes(BlockReader reader) throws IOException{
|
||||
if(!reader.isAvailable()){
|
||||
|
@ -35,9 +35,9 @@ public class SignatureId {
|
||||
}
|
||||
public String toFileName() {
|
||||
if (this.name != null) {
|
||||
return name + FILE_EXTENSION;
|
||||
return name + FILE_EXT_RAW;
|
||||
}
|
||||
return String.format("0x%08x", id) + FILE_EXTENSION;
|
||||
return String.format("0x%08x", id) + FILE_EXT_RAW;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
@ -66,7 +66,7 @@ public class SignatureId {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
String ext = FILE_EXTENSION;
|
||||
String ext = FILE_EXT_RAW;
|
||||
if (name.endsWith(ext)) {
|
||||
name = name.substring(0, name.length() - ext.length());
|
||||
}
|
||||
@ -105,5 +105,5 @@ public class SignatureId {
|
||||
V2, V3, V31, STAMP_V1, STAMP_V2, PADDING, NULL
|
||||
};
|
||||
|
||||
private static final String FILE_EXTENSION = ".bin";
|
||||
public static final String FILE_EXT_RAW = ".signature.info.bin";
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.item.IntegerItem;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
@ -87,8 +88,7 @@ public class SignatureInfo extends LengthPrefixedBlock implements BlockLoad {
|
||||
}
|
||||
schemeContainer.setItem(scheme);
|
||||
}
|
||||
// for test
|
||||
public void writeData(File file) throws IOException{
|
||||
public void writeRaw(File file) throws IOException{
|
||||
File dir = file.getParentFile();
|
||||
if(dir != null && !dir.exists()){
|
||||
dir.mkdirs();
|
||||
@ -97,12 +97,15 @@ public class SignatureInfo extends LengthPrefixedBlock implements BlockLoad {
|
||||
writeBytes(outputStream);
|
||||
outputStream.close();
|
||||
}
|
||||
// for test
|
||||
public File writeToDir(File dir) throws IOException{
|
||||
File file = new File(dir, getId().toFileName());
|
||||
writeData(file);
|
||||
public File writeRawToDirectory(File dir) throws IOException{
|
||||
String name = getIndex() + "_" + getId().toFileName();
|
||||
File file = new File(dir, name);
|
||||
writeRaw(file);
|
||||
return file;
|
||||
}
|
||||
public void read(File file) throws IOException {
|
||||
super.readBytes(new BlockReader(file));
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return getId() + ", scheme: " + getSignatureScheme();
|
||||
|
@ -30,6 +30,19 @@ public class SchemePadding extends SignatureScheme {
|
||||
this.byteArray = new ByteArray();
|
||||
addChild(this.byteArray);
|
||||
}
|
||||
public int getPadding(){
|
||||
return byteArray.size();
|
||||
}
|
||||
public void setPadding(int padding){
|
||||
byteArray.setSize(padding);
|
||||
}
|
||||
public byte[] getPaddingBytes() {
|
||||
return byteArray.getBytes();
|
||||
}
|
||||
public void setPadding(byte[] bytes){
|
||||
byteArray.set(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReadBytes(BlockReader reader) throws IOException{
|
||||
SignatureInfo signatureInfo = getSignatureInfo();
|
||||
@ -37,4 +50,8 @@ public class SchemePadding extends SignatureScheme {
|
||||
byteArray.setSize(size);
|
||||
super.onReadBytes(reader);
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
return "padding = " + getPadding();
|
||||
}
|
||||
}
|
||||
|
@ -99,13 +99,13 @@ public class ApkWriter extends ZipFileOutput {
|
||||
logMessage("Writing signature block ...");
|
||||
long offset = position();
|
||||
int alignment = 4096;
|
||||
int padding = (int) ((alignment - (offset % alignment)) % alignment);
|
||||
int filesPadding = (int) ((alignment - (offset % alignment)) % alignment);
|
||||
OutputStream outputStream = getOutputStream();
|
||||
if(padding > 0){
|
||||
outputStream.write(new byte[padding]);
|
||||
if(filesPadding > 0){
|
||||
outputStream.write(new byte[filesPadding]);
|
||||
}
|
||||
signatureBlock.refresh();
|
||||
logVerbose("padding = " + padding + ", signatures = " + signatureBlock.countBytes());
|
||||
logMessage("files padding = " + filesPadding);
|
||||
signatureBlock.updatePadding();
|
||||
signatureBlock.writeBytes(outputStream);
|
||||
}
|
||||
private BufferFileInput writeBuffer(List<OutputSource> outputList) throws IOException {
|
||||
|
Loading…
x
Reference in New Issue
Block a user