-
-
Save vvb2060/8436e7f516eae2c58472b61709749241 to your computer and use it in GitHub Desktop.
SimpleApkV2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.nio.ByteBuffer; | |
import java.nio.ByteOrder; | |
import java.nio.channels.FileChannel; | |
import java.nio.file.Path; | |
import java.nio.file.Paths; | |
import java.nio.file.StandardOpenOption; | |
import java.util.Arrays; | |
public class SimpleApkV2 { | |
private SimpleApkV2() { | |
} | |
private static abstract class ApkV2Parser { | |
private final Path sourceDir; | |
ApkV2Parser(String sourceDir) { | |
this.sourceDir = Paths.get(sourceDir); | |
parse(); | |
} | |
private void parse() { | |
final byte[] apkSignV2 = {'A', 'P', 'K', ' ', 'S', 'i', 'g', ' ', | |
'B', 'l', 'o', 'c', 'k', ' ', '4', '2'}; | |
try (var channel = FileChannel.open(sourceDir, StandardOpenOption.READ)) { | |
int apkSize = (int) channel.size(); | |
var apk = channel.map(FileChannel.MapMode.READ_ONLY, 0, apkSize); | |
apk.order(ByteOrder.LITTLE_ENDIAN); | |
int offset; | |
for (int i = 0; ; i++) { | |
if (apk.getShort(apkSize - 0x2 - i) == i) { | |
if (apk.getInt(apkSize - 0x16 - i) == 0x6054b50) { | |
offset = apk.getInt(apkSize - 0x6 - i); | |
break; | |
} | |
} | |
if (i == 0xffff) { | |
System.out.println("invalid APK format"); | |
return; | |
} | |
} | |
var buffer = new byte[0x10]; | |
apk.position(offset - 0x10); | |
apk.get(buffer); | |
if (!Arrays.equals(apkSignV2, buffer)) { | |
System.out.println("APK Sig Block 42"); | |
return; | |
} | |
int blockSize = (int) apk.getLong(offset - 0x18); | |
apk.position(offset - blockSize - 0x8); | |
if (blockSize != apk.getLong()) { | |
System.out.println("invalid APK sig block"); | |
return; | |
} | |
while (apk.remaining() > apkSize - offset + 0x18) { | |
int size = (int) apk.getLong(); | |
int id = apk.getInt(); | |
int newPosition = apk.position() + size - 0x4; | |
handle(id, size, apk); | |
apk.position(newPosition); | |
} | |
if (apk.remaining() != apkSize - offset + 0x18) { | |
System.out.println("have more data"); | |
} | |
} catch (IOException e) { | |
System.out.println(e.getMessage()); | |
} | |
} | |
protected abstract void handle(int id, int size, ByteBuffer block); | |
} | |
public static void main(String[] args) { | |
new DummyParser(args[0]); | |
} | |
private static class DummyParser extends ApkV2Parser { | |
DummyParser(String sourceDir) { | |
super(sourceDir); | |
} | |
@Override | |
protected void handle(int id, int size, ByteBuffer block) { | |
switch (id) { | |
default -> | |
System.out.println("id: 0x" + Integer.toHexString(id) + "(unknown), size: " + size); | |
case 0x7109871a -> | |
System.out.println("id: 0x" + Integer.toHexString(id) + "(signature scheme v2), size: " + size); | |
case 0xf05368c0 -> | |
System.out.println("id: 0x" + Integer.toHexString(id) + "(signature scheme v3), size: " + size); | |
case 0x1b93ad61 -> | |
System.out.println("id: 0x" + Integer.toHexString(id) + "(signature scheme v3.1), size: " + size); | |
case 0x2b09189e -> | |
System.out.println("id: 0x" + Integer.toHexString(id) + "(source stamp V1), size: " + size); | |
case 0x6dff800d -> | |
System.out.println("id: 0x" + Integer.toHexString(id) + "(source stamp V2), size: " + size); | |
case 0x2146444e -> | |
System.out.println("id: 0x" + Integer.toHexString(id) + "(play store security metadata), " + size); | |
case 0x504b4453 -> | |
System.out.println("id: 0x" + Integer.toHexString(id) + "(dependencies metadata), size: " + size); | |
case 0x42726577 -> | |
System.out.println("id: 0x" + Integer.toHexString(id) + "(padding), size: " + size); | |
case 0x71777777 -> { | |
byte[] bytes = new byte[size - 0x4]; | |
block.get(bytes, 0, bytes.length); | |
String channel = new String(bytes); | |
System.out.println("id: 0x" + Integer.toHexString(id) + "(meituan channel), " + channel); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment