From 11d46072ab4495b53e49059a9285779bd76ff0b9 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 18 Sep 2018 15:59:49 +0200 Subject: [PATCH] use androguard primitives to speed up finding debuggable flag androguard parses the whole APK before handing the instance back, this uses the primitives to just find the value, then stop parsing. #557 --- fdroidserver/common.py | 24 +++++++++++++++++++----- tests/common.TestCase | 15 ++++++++++++++- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 53c4d41a..084f982f 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2073,11 +2073,25 @@ def is_apk_and_debuggable_aapt(apkfile): def is_apk_and_debuggable_androguard(apkfile): - apkobject = _get_androguard_APK(apkfile) - if apkobject.is_valid_APK(): - debuggable = apkobject.get_element("application", "debuggable") - if debuggable == 'true': - return True + """Parse only from the APK""" + from androguard.core.bytecodes.axml import AXMLParser, format_value, START_TAG + with ZipFile(apkfile) as apk: + with apk.open('AndroidManifest.xml') as manifest: + axml = AXMLParser(manifest.read()) + while axml.is_valid(): + _type = next(axml) + if _type == START_TAG and axml.getName() == 'application': + for i in range(0, axml.getAttributeCount()): + name = axml.getAttributeName(i) + if name == 'debuggable': + _type = axml.getAttributeValueType(i) + _data = axml.getAttributeValueData(i) + value = format_value(_type, _data, lambda _: axml.getAttributeValue(i)) + if value == 'true': + return True + else: + return False + break return False diff --git a/tests/common.TestCase b/tests/common.TestCase index 841da524..125f0961 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -131,7 +131,7 @@ class CommonTest(unittest.TestCase): fdroidserver.common._add_java_paths_to_config(pathlist, config) self.assertEqual(config['java_paths']['8'], choice[1:]) - def testIsApkDebuggable(self): + def test_is_apk_and_debuggable(self): config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config @@ -150,6 +150,13 @@ class CommonTest(unittest.TestCase): debuggable = fdroidserver.common.is_apk_and_debuggable(apkfile) self.assertTrue(debuggable, "debuggable APK state was not properly parsed!") + if 'aapt' in config: + self.assertTrue(fdroidserver.common.is_apk_and_debuggable_aapt(apkfile), + 'aapt parsing missed !') + if fdroidserver.common.use_androguard(): + self.assertTrue(fdroidserver.common.is_apk_and_debuggable_androguard(apkfile), + 'androguard missed !') + # these are set NOT debuggable testfiles = [] testfiles.append(os.path.join(self.basedir, 'urzip-release.apk')) @@ -158,6 +165,12 @@ class CommonTest(unittest.TestCase): debuggable = fdroidserver.common.is_apk_and_debuggable(apkfile) self.assertFalse(debuggable, "debuggable APK state was not properly parsed!") + if 'aapt' in config: + self.assertFalse(fdroidserver.common.is_apk_and_debuggable_aapt(apkfile), + 'aapt parsing missed !') + if fdroidserver.common.use_androguard(): + self.assertFalse(fdroidserver.common.is_apk_and_debuggable_androguard(apkfile), + 'androguard missed !') def test_is_valid_package_name(self): for name in ["cafebabe",