Support get apk sign v2 info (#40)

This commit is contained in:
Ketal 2022-02-23 22:13:27 +08:00 committed by GitHub
parent a6f381920d
commit 1096ba6658
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 74 additions and 0 deletions

View File

@ -1,6 +1,12 @@
package org.lsposed.patch.util;
import java.io.InputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.security.cert.Certificate;
import java.util.Enumeration;
import java.util.jar.JarEntry;
@ -10,6 +16,8 @@ import java.util.jar.JarFile;
* Created by Wind
*/
public class ApkSignatureHelper {
private static final byte[] APK_V2_MAGIC = {'A', 'P', 'K', ' ', 'S', 'i', 'g', ' ',
'B', 'l', 'o', 'c', 'k', ' ', '4', '2'};
private static char[] toChars(byte[] mSignature) {
byte[] sig = mSignature;
@ -39,6 +47,14 @@ public class ApkSignatureHelper {
}
public static String getApkSignInfo(String apkFilePath) {
try {
return getApkSignV2(apkFilePath);
} catch (Exception e) {
return getApkSignV1(apkFilePath);
}
}
public static String getApkSignV1(String apkFilePath) {
byte[] readBuffer = new byte[8192];
Certificate[] certs = null;
try {
@ -77,4 +93,62 @@ public class ApkSignatureHelper {
}
return null;
}
private static String getApkSignV2(String apkFilePath) throws IOException {
try (RandomAccessFile apk = new RandomAccessFile(apkFilePath, "r")) {
ByteBuffer buffer = ByteBuffer.allocate(0x10);
buffer.order(ByteOrder.LITTLE_ENDIAN);
apk.seek(apk.length() - 0x6);
apk.readFully(buffer.array(), 0x0, 0x6);
int offset = buffer.getInt();
if (buffer.getShort() != 0) {
throw new UnsupportedEncodingException("no zip");
}
apk.seek(offset - 0x10);
apk.readFully(buffer.array(), 0x0, 0x10);
if (!Arrays.equals(buffer.array(), APK_V2_MAGIC)) {
throw new UnsupportedEncodingException("no apk v2");
}
// Read and compare size fields
apk.seek(offset - 0x18);
apk.readFully(buffer.array(), 0x0, 0x8);
buffer.rewind();
int size = (int) buffer.getLong();
ByteBuffer block = ByteBuffer.allocate(size + 0x8);
block.order(ByteOrder.LITTLE_ENDIAN);
apk.seek(offset - block.capacity());
apk.readFully(block.array(), 0x0, block.capacity());
if (size != block.getLong()) {
throw new UnsupportedEncodingException("no apk v2");
}
while (block.remaining() > 24) {
size = (int) block.getLong();
if (block.getInt() == 0x7109871a) {
// signer-sequence length, signer length, signed data length
block.position(block.position() + 12);
size = block.getInt(); // digests-sequence length
// digests, certificates length
block.position(block.position() + size + 0x4);
size = block.getInt(); // certificate length
break;
} else {
block.position(block.position() + size - 0x4);
}
}
byte[] certificate = new byte[size];
block.get(certificate);
return new String(toChars(certificate));
}
}
}