30 lines
1.2 KiB
Python
30 lines
1.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Checks the dex inside an APK the way Dalvik's dexopt does at install time:
|
|
format version, file size, Adler-32 checksum, SHA-1 signature, and no post-035 sections.
|
|
usage: check_dex.py app.apk"""
|
|
import hashlib
|
|
import struct
|
|
import sys
|
|
import zipfile
|
|
import zlib
|
|
|
|
d = zipfile.ZipFile(sys.argv[1]).read("classes.dex")
|
|
problems = []
|
|
if d[:8] != b"dex\n035\x00":
|
|
problems.append("dex version %r (Android 2.3 needs 035)" % d[:8])
|
|
if struct.unpack("<I", d[32:36])[0] != len(d):
|
|
problems.append("file_size field wrong")
|
|
if zlib.adler32(d[12:]) & 0xFFFFFFFF != struct.unpack("<I", d[8:12])[0]:
|
|
problems.append("Adler-32 checksum wrong")
|
|
if hashlib.sha1(d[32:]).digest() != d[12:32]:
|
|
problems.append("SHA-1 signature wrong")
|
|
map_off = struct.unpack("<I", d[52:56])[0]
|
|
for i in range(struct.unpack("<I", d[map_off:map_off + 4])[0]):
|
|
t = struct.unpack("<H", d[map_off + 4 + i * 12:map_off + 6 + i * 12])[0]
|
|
if t in (7, 8):
|
|
problems.append("contains call_site/method_handle sections (needs Android 8+)")
|
|
for p in problems:
|
|
print("DEX PROBLEM:", p)
|
|
print("classes.dex: %d bytes, %s" % (len(d), "OK" if not problems else "REJECTED"))
|
|
sys.exit(1 if problems else 0)
|