def androaxml_main(inp, outp=None, resource=None): ret_type = androconf.is_android(inp) if ret_type == "APK": a = apk.APK(inp) if resource: if resource not in a.files: print("The APK does not contain a file called '{}'".format( resource), file=sys.stderr) sys.exit(1) axml = AXMLPrinter(a.get_file(resource)).get_xml_obj() else: axml = a.get_android_manifest_xml() elif ".xml" in inp: axml = AXMLPrinter(read(inp)).get_xml_obj() else: print("Unknown file type") sys.exit(1) buff = etree.tostring(axml, pretty_print=True, encoding="utf-8") if outp: with open(outp, "wb") as fd: fd.write(buff) else: sys.stdout.write( highlight(buff.decode("UTF-8"), get_lexer_by_name("xml"), TerminalFormatter()))
def extractPermissions(apkFilename): try: a = AXMLPrinter(readManifest(apkFilename)) xml = a.get_xml_obj() permElements = xml.findall("uses-permission") perms = [] for perm in permElements: permstr = perm.get(PERM_NAME_ATTRIB_KEY) perms.append(permstr) return perms except: return []
def testAdaptiveIcon(self): # See https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive.html from androguard.core.bytecodes.apk import APK from androguard.core.bytecodes.axml import AXMLPrinter a = APK("examples/tests/com.android.example.text.styling.apk") self.assertEqual(a.get_app_icon(), "res/mipmap-anydpi-v26/ic_launcher.xml") x = AXMLPrinter(a.get_file(a.get_app_icon())).get_xml().decode("UTF-8") self.assertIn("adaptive-icon", x) # * ldpi (low) ~120dpi # * mdpi (medium) ~160dpi # * hdpi (high) ~240dpi # * xhdpi (extra-high) ~320dpi # * xxhdpi (extra-extra-high) ~480dpi # * xxxhdpi (extra-extra-extra-high) ~640dpi self.assertIsNone(a.get_app_icon(max_dpi=120)) # No LDPI icon self.assertIn("mdpi", a.get_app_icon(max_dpi=160)) self.assertIn("hdpi", a.get_app_icon(max_dpi=240)) self.assertIn("xhdpi", a.get_app_icon(max_dpi=320)) self.assertIn("xxhdpi", a.get_app_icon(max_dpi=480)) self.assertIn("xxxhdpi", a.get_app_icon(max_dpi=640)) self.assertIn(".png", a.get_app_icon(max_dpi=65533)) self.assertIn(".xml", a.get_app_icon(max_dpi=65534))
def _apk_analysis(self): """ Run analysis on the APK file. This method is usually called by __init__ except if skip_analysis is False. It will then parse the AndroidManifest.xml and set all fields in the APK class which can be extracted from the Manifest. """ for i in self.zip.namelist(): if i == "AndroidManifest.xml": self.axml[i] = AXMLPrinter(self.zip.read(i)) self.xml[i] = None raw_xml = self.axml[i].get_buff() if len(raw_xml) == 0: log.warning("AXML parsing failed, file is empty") else: try: if self.axml[i].is_packed(): log.warning("XML Seems to be packed, parsing is very likely to fail.") self.xml[i] = self.axml[i].get_xml_obj() except Exception as e: log.warning("reading AXML as XML failed: " + str(e)) if self.xml[i] is not None: self.package = self.xml[i].get("package") self.androidversion["Code"] = self.xml[i].get( NS_ANDROID + "versionCode") self.androidversion["Name"] = self.xml[i].get( NS_ANDROID + "versionName") for item in self.xml[i].findall('uses-permission'): self.permissions.append(item.get(NS_ANDROID + "name")) # getting details of the declared permissions for d_perm_item in self.xml[i].findall('permission'): d_perm_name = self._get_res_string_value(str( d_perm_item.get(NS_ANDROID + "name"))) d_perm_label = self._get_res_string_value(str( d_perm_item.get(NS_ANDROID + "label"))) d_perm_description = self._get_res_string_value(str( d_perm_item.get(NS_ANDROID + "description"))) d_perm_permissionGroup = self._get_res_string_value(str( d_perm_item.get(NS_ANDROID + "permissionGroup"))) d_perm_protectionLevel = self._get_res_string_value(str( d_perm_item.get(NS_ANDROID + "protectionLevel"))) d_perm_details = { "label": d_perm_label, "description": d_perm_description, "permissionGroup": d_perm_permissionGroup, "protectionLevel": d_perm_protectionLevel, } self.declared_permissions[d_perm_name] = d_perm_details self.valid_apk = True self.permission_module = androconf.load_api_specific_resource_module( "aosp_permissions", self.get_target_sdk_version())
def extractMetadata(self): # Get the compiler version manifest = self.readContent('META-INF/MANIFEST.MF') packer = re.findall(r'Created-By:\s+(.+)', manifest) if (len(packer) > 0): self.results['result']['metadata']['packer'] = packer[0].strip() # Get manifest data manifestBinary = self.readContent('AndroidManifest.xml', binaryMode=True) aPrinter = AXMLPrinter(manifestBinary) lxmlObject = aPrinter.get_xml_obj() for data in [ ['package', 'package'], ['compile-sdk-version', 'android:compileSdkVersion'], [ 'compile-sdk-version-codename', 'android:compileSdkVersionCodename' ], ['platform-build-version-code', 'platformBuildVersionCode'], ['platform-build-version-name', 'platformBuildVersionName'] ]: self.results['result']['metadata'][data[0]] = str( lxmlObject.get(data[1])) # Get data from compile certificate # It is difficult to obtain separately the properties of type text # in androguard. for certFilename in self.zipFiles: if (re.match(r'META-INF\/[a-zA-Z0-9\-_\.]+?\.RSA', certFilename)): certBinary = self.readContent(certFilename, binaryMode=True) pkcs7 = OpenSSL.crypto.load_pkcs7_data( OpenSSL.crypto.FILETYPE_ASN1, certBinary) cert = self.get_certificates(pkcs7)[0] issuer = cert.get_issuer() self.results['result']['metadata']['app-name'] = str( issuer.commonName) self.results['result']['metadata']['author'] = str( issuer.organizationName) break
def extractPermissionSample(apkFilename, features): #print(apkFilename) a = AXMLPrinter(readManifest(apkFilename)) xml = a.get_xml_obj() permElements = xml.findall("uses-permission") perms = [] for perm in permElements: permstr = perm.get(PERM_NAME_ATTRIB_KEY) perms.append(permstr) perms = cleanPermissions(perms) out_features = [] index = 0 for permission in features: if permission in perms: # could be slow out_features.append(1) #print(permission) else: out_features.append(0) index += 1 return out_features
def decode_manifest(xml_path, out_path): manifest = AXMLPrinter(read(xml_path)).get_xml_obj() buff = etree.tounicode(manifest, pretty_print=True) with open(out_path + '/{}/manifest.xml'.format(xml_path.split('/')[-2]), 'w') as f: f.write(buff)
apk_path = args.oem_dir / args.overlay apk = APK(apk_path.as_posix()) print(f"Opened {apk}") file = apk.get_file("res/xml/service_providers.xml") from xml.etree import ElementTree as ET """ NOTE: Use get_xml_obj to get an immutable representation of the tree Use get_xml to get a formatted string representation Use get_buff to get a oneline representation without formatting tokens ET keeps the formatting internally, and spits this out in `.write()`. Inserted elements are not formatted properly. """ et = ET.fromstring(AXMLPrinter(file).get_xml()) assert et.tag == "service_provider_sim_configs" mbn_paths = set() config_ids = set() for el in et: assert el.tag == "service_provider_sim_config" config_id = el.get("sim_config_id") config_ids.add(config_id) mcc, mnc = el.find("mcc"), el.find("mnc") if mcc is not None: mcc = mcc.text if mnc is not None: mnc = mnc.text
def parse_manifest(self, manifest_file, resource_file): information = [] apk_info = defaultdict(list) print "Parsing Resource XML" if resource_file is not None: self.resource_parser = arcParser = ARSCParser(resource_file) for p in arcParser.get_packages_names(): apk_info['packages'].append(p) for locale in arcParser.get_locales(p): for t in arcParser.get_types(p, locale): for x in arcParser.values[p][locale][t]: try: if t == "public": (type, value, id) = x if isinstance(value, unicode): value = unidecode(value) information.append( self.createData("main", "RESOURCE", RESOURCE_VALUE=value, RESOURCE_LOCALE=locale, RESOURCE_PACKAGE=p, RESOURCE_TYPE=t, RESOURCE_TYPE2=type, RESOURCE_ID=id)) elif len(x) == 2: (key, value) = x if isinstance(value, unicode): value = unidecode(value) information.append( self.createData("main", "RESOURCE", RESOURCE_VALUE=value, RESOURCE_LOCALE=locale, RESOURCE_PACKAGE=p, RESOURCE_TYPE=t, RESOURCE_KEY=key)) else: value = x[0] if isinstance(value, unicode): value = unidecode(value) information.append( self.createData("main", "RESOURCE", RESOURCE_VALUE=value, RESOURCE_LOCALE=locale, RESOURCE_PACKAGE=p, RESOURCE_TYPE=t)) except Exception as e: print x print e print "Parsing Manifest XML" xmlPrinter = AXMLPrinter(manifest_file) root = xmlPrinter.get_xml_obj() # Get Permissions for e in root.findall('uses-permission'): attributes = self.extract_all_attributes(e) information.append( self.createData( "main", "PERMISSION", **{ 'PERMISSION_' + k.upper(): v for k, v in attributes.items() })) for e in root.findall('uses-permission-sdk-23'): attributes = self.extract_all_attributes(e) information.append( self.createData( "main", "PERMISSION", **{ 'PERMISSION_' + k.upper(): v for k, v in attributes.items() })) for e in root.findall('uses-feature'): attributes = self.extract_all_attributes(e) information.append( self.createData( "main", "FEATURES", **{ 'FEATURES_' + k.upper(): v for k, v in attributes.items() })) app = root.find('application') attributes = self.extract_all_attributes(app) information.append( self.createData( "main", "APP", **{'APP_' + k.upper(): v for k, v in attributes.items()})) if app is not None: for e in app.findall('.//meta-data'): attributes = self.extract_all_attributes(e) information.append( self.createData( "main", "META", **{ 'META_' + k.upper(): v for k, v in attributes.items() })) # for e in app.findall('uses-library'): # attributes = self.extract_all_attributes(e) # information.append(self.createData("main", "APK-USES-LIB" ,**attributes)) for tagtype in ['activity', 'receiver', 'service']: for e in app.findall(tagtype): attributes = self.extract_all_attributes(e) information.append( self.createData( "main", tagtype.upper(), **{ tagtype.upper() + '_' + k.upper(): v for k, v in attributes.items() })) for intent in e.findall('intent-filter'): intentions = defaultdict(list) for e2 in intent.getchildren(): # print e2.tag attributes = self.extract_all_attributes( e2, prefix=e2.tag + ".") for k, v in attributes.iteritems(): intentions[tagtype.upper() + "_" + k].append(v) information.append( self.createData("main", tagtype.upper(), **intentions)) return information