Skip to content

Commit

Permalink
Check apk before installation
Browse files Browse the repository at this point in the history
  • Loading branch information
ma1co committed Mar 27, 2018
1 parent e76675c commit ae8a86d
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 3 deletions.
2 changes: 1 addition & 1 deletion build.spec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import os, shutil, subprocess, sys

excludes = ['bz2', 'cffi', 'Crypto', 'doctest', 'ftplib', 'lzma', 'numpy', 'pickle', 'plistlib', 'py_compile', 'tarfile', 'tracemalloc']
excludes = ['apkutils.cert', 'bz2', 'cffi', 'Crypto', 'doctest', 'ftplib', 'lzma', 'numpy', 'pickle', 'plistlib', 'py_compile', 'tarfile', 'tracemalloc']
if sys.platform != 'win32':
excludes.append('pmca.usb.driver.windows')
if sys.platform != 'darwin':
Expand Down
34 changes: 34 additions & 0 deletions pmca/apk/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from apkutils.axml.axmlparser import AXML
from asn1crypto.cms import ContentInfo
from zipfile import ZipFile

class ApkParser:
def __init__(self, file):
self._file = ZipFile(file)

def getManifest(self):
return AXML(self._file.read('AndroidManifest.xml')).get_xml_obj()

def getPackageName(self):
return self.getManifest().documentElement.getAttribute('package')

def getVersionCode(self):
return int(self.getManifest().documentElement.getAttribute('android:versionCode'))

def getVersionName(self):
return self.getManifest().documentElement.getAttribute('android:versionName')

def getMinSdkVersion(self):
return int(self.getManifest().documentElement.getElementsByTagName('uses-sdk')[0].getAttribute('android:minSdkVersion'))

def _getCerts(self):
for info in self._file.infolist():
if info.filename.startswith('META-INF/') and info.filename.endswith('.RSA'):
for cert in ContentInfo.load(self._file.read(info))['content']['certificates']:
yield cert.dump()

def getCert(self):
certs = list(self._getCerts())
if len(certs) != 1:
raise Exception('Cannot read certificate')
return certs[0]
38 changes: 36 additions & 2 deletions pmca/commands/usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
input = raw_input

import config
from ..apk import *
from .. import appstore
from .. import firmware
from .. import installer
Expand Down Expand Up @@ -58,14 +59,22 @@ def installApp(dev, apkFile=None, appPackage=None, outFile=None, local=False):
"""Installs an app on the specified device."""
certFile = scriptRoot + '/certs/localtest.me.pem'
with ServerContext(LocalMarketServer(certFile, config.officialServer)) as server:
apkData = None
if apkFile:
server.setApk(apkFile.read())
apkData = apkFile.read()
elif appPackage:
print('Downloading apk')
apps = listApps(True)
if appPackage not in apps:
raise Exception('Unknown app: %s' % appPackage)
server.setApk(apps[appPackage].release.asset)
apkData = apps[appPackage].release.asset

if apkData:
print('Analyzing apk')
print('')
checkApk(io.BytesIO(apkData))
print('')
server.setApk(apkData)

print('Starting task')
xpdData = server.getXpd()
Expand Down Expand Up @@ -93,6 +102,31 @@ def installApp(dev, apkFile=None, appPackage=None, outFile=None, local=False):
return result


def checkApk(apkFile):
try:
apk = ApkParser(apkFile)

props = [
('Package', apk.getPackageName()),
('Version', apk.getVersionName()),
]
apk.getVersionCode()
for k, v in props:
print('%-9s%s' % (k + ': ', v))

sdk = apk.getMinSdkVersion()
if sdk > 10:
print('Warning: This app might not be compatible with the device (minSdkVersion = %d)' % sdk)

try:
apk.getCert()
except:
print('Warning: Cannot read apk certificate')

except:
print('Warning: Invalid apk file')


class UsbDriverList:
def __init__(self, *contexts):
self._contexts = contexts
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
apkutils
asn1crypto
certifi
comtypes==1.1.3-2
pycryptodomex
Expand Down

0 comments on commit ae8a86d

Please sign in to comment.