Skip to content

Commit

Permalink
Merge pull request #259 from yrom/fix-signature-scheme-v3
Browse files Browse the repository at this point in the history
解决与最新apksigner(build-tools 28.0.x) 的兼容性问题
  • Loading branch information
achellies committed Feb 19, 2019
2 parents b950fae + 056359d commit be6421b
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ private ApkUtil() {
*/
public static final int APK_SIGNATURE_SCHEME_V2_BLOCK_ID = 0x7109871a;

/**
* The padding in APK SIG BLOCK (V3 scheme introduced)
* See https://android.googlesource.com/platform/tools/apksig/+/master/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java
*/
public static final int VERITY_PADDING_BLOCK_ID = 0x42726577;

public static final int ANDROID_COMMON_PAGE_ALIGNMENT_BYTES = 4096;


// Our Channel Block ID
public static final int APK_CHANNEL_BLOCK_ID = 0x71777777;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
class ApkSigningPayload {
private final int id;
private final ByteBuffer buffer;
private final int totalSize;

ApkSigningPayload(final int id, final ByteBuffer buffer) {
super();
Expand All @@ -15,6 +16,8 @@ class ApkSigningPayload {
throw new IllegalArgumentException("ByteBuffer byte order must be little endian");
}
this.buffer = buffer;
// assume buffer is not consumed
this.totalSize = 8 + 4 + buffer.remaining(); // size + id + value
}

public int getId() {
Expand All @@ -27,4 +30,11 @@ public byte[] getByteBuffer() {
return Arrays.copyOfRange(array, arrayOffset + buffer.position(),
arrayOffset + buffer.limit());
}

/**
* Total bytes of this block
*/
public int getTotalSize() {
return totalSize;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,35 @@ static void handleApkSigningBlock(final File apkFile, final ApkSigningBlockHandl
"No APK Signature Scheme v2 block in APK Signing Block");
}


final boolean needPadding = originIdValues.remove(ApkUtil.VERITY_PADDING_BLOCK_ID) != null;
final ApkSigningBlock apkSigningBlock = handler.handle(originIdValues);
// replace VERITY_PADDING_BLOCK with new one
if (needPadding) {
// uint64: size (excluding this field)
// repeated ID-value pairs:
// uint64: size (excluding this field)
// uint32: ID
// (size - 4) bytes: value
// (extra dummy ID-value for padding to make block size a multiple of 4096 bytes)
// uint64: size (same as the one above)
// uint128: magic

int blocksSize = 0;
for (ApkSigningPayload payload : apkSigningBlock.getPayloads()) {
blocksSize += payload.getTotalSize();
}

int resultSize = 8 + blocksSize + 8 + 16; // size(uint64) + pairs size + size(uint64) + magic(uint128)
if (resultSize % ApkUtil.ANDROID_COMMON_PAGE_ALIGNMENT_BYTES != 0) {
int padding = ApkUtil.ANDROID_COMMON_PAGE_ALIGNMENT_BYTES - 12 // size(uint64) + id(uint32)
- (resultSize % ApkUtil.ANDROID_COMMON_PAGE_ALIGNMENT_BYTES);
if (padding < 0) {
padding += ApkUtil.ANDROID_COMMON_PAGE_ALIGNMENT_BYTES;
}
final ByteBuffer dummy = ByteBuffer.allocate(padding).order(ByteOrder.LITTLE_ENDIAN);
apkSigningBlock.addPayload(new ApkSigningPayload(ApkUtil.VERITY_PADDING_BLOCK_ID,dummy));
}
}

if (apkSigningBlockOffset != 0 && centralDirStartOffset != 0) {

Expand Down

0 comments on commit be6421b

Please sign in to comment.