#!/usr/bin/python # -*- coding: utf-8 -*- from manifest import AndroidManifest from db import PermsDataBase from panel import PermsPanel from pychrysalide import Plugin from xml.dom import minidom import re import zipfile class AndroPerms(Plugin): """List all permissions given to an APK files.""" def init(self, ref): """Initialize the plugin.""" self._panel = PermsPanel() return True def get_action(self): """Register the plugin for given actions.""" return Plugin.PGA_DISASS_PROCESS def execute_on_binary(self, binary, action): """Process once a binary is disassembled.""" zf = zipfile.ZipFile(binary.get_filename()) f = zf.open('AndroidManifest.xml', 'r') data = f.read() f.closed manifest = AndroidManifest(data) xml = minidom.parseString(manifest.getXML()) # print # print "Permissions for ", binary.get_filename(), " :" # print "-------------" # print plist = [] for p in xml.getElementsByTagName("uses-permission"): plist.append(p.getAttribute("android:name")) # print p.getAttribute("android:name") # print db = PermsDataBase() db.filter_permissions(plist) fmt = binary.get_format() instrs = binary.get_instructions() buf = binary.disassembled_buffer pfn = re.compile('<.* ([^ ]*)\(') for i in instrs: if i.keyword.startswith("invoke"): line = buf.find_line_by_addr(i.address) text = line.get_text() name = pfn.search(text) if name != None: resolved = fmt.resolve_relative_routine(i.address) if resolved == None: reladdr = "0x%08x" % i.address else: reladdr = "<%s()+0x%x>" % (resolved[0], resolved[1]) db.check_call(i.address, name.group(1), reladdr) self._panel.memorize_permissions(binary, db.get_used_permissions())