diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2012-12-18 22:44:24 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2012-12-18 22:44:24 (GMT) |
commit | f4dbbab3190d13e61f125eea51a0ecec2ab9e897 (patch) | |
tree | 2362579b428c363e2cca94e0fa89b1e39b7a50e7 /plugins/python/androperms | |
parent | 64e09a6c3e39785975b5322973ed83734cedb82e (diff) |
Created a proper panel for the Android permissions in the editor.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@305 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'plugins/python/androperms')
-rw-r--r-- | plugins/python/androperms/Makefile.am | 1 | ||||
-rw-r--r-- | plugins/python/androperms/androperms.py | 91 | ||||
-rw-r--r-- | plugins/python/androperms/db.py | 94 | ||||
-rw-r--r-- | plugins/python/androperms/panel.py | 121 |
4 files changed, 197 insertions, 110 deletions
diff --git a/plugins/python/androperms/Makefile.am b/plugins/python/androperms/Makefile.am index c9c8430..b1a1e4e 100644 --- a/plugins/python/androperms/Makefile.am +++ b/plugins/python/androperms/Makefile.am @@ -6,6 +6,7 @@ androperms_DATA = \ android.png \ androperms.db \ androperms.py \ + db.py \ defs.py \ manifest.py \ panel.py \ diff --git a/plugins/python/androperms/androperms.py b/plugins/python/androperms/androperms.py index 569558a..18443fc 100644 --- a/plugins/python/androperms/androperms.py +++ b/plugins/python/androperms/androperms.py @@ -2,18 +2,25 @@ # -*- coding: utf-8 -*- from manifest import AndroidManifest +from db import PermsDataBase from panel import PermsPanel from pychrysalide import Plugin -from pychrysalide.gui.panels import PanelItem from xml.dom import minidom -import gtk +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.""" @@ -33,36 +40,26 @@ class AndroPerms(Plugin): manifest = AndroidManifest(data) xml = minidom.parseString(manifest.getXML()) - print - print "Permissions for ", binary.get_filename(), " :" - print "-------------" - print + # 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 - - - - panel = PermsPanel() + # print p.getAttribute("android:name") - self._build_panel_item() - - - - panel.filter_permissions(plist) + # print + db = PermsDataBase() + db.filter_permissions(plist) instrs = binary.get_instructions() buffer = binary.disassembled_buffer - - - + pfn = re.compile('<.* ([^ ]*)\(') for i in instrs: @@ -71,52 +68,12 @@ class AndroPerms(Plugin): line = buffer.find_line_by_addr(i.address) text = line.get_text() - panel.check_call(i.address, text) - - - - - - panel.fill_tree(self._store) - self._tree.expand_all() - - - - def _build_panel_item(self): - - self._scrolled_window = gtk.ScrolledWindow() - self._scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self._scrolled_window.show() - - self._tree = gtk.TreeView() - self._tree.set_headers_visible(False) - self._tree.show() - self._scrolled_window.add_with_viewport(self._tree) - - locations = gtk.TreeViewColumn() - self._tree.append_column(locations) - - cell = gtk.CellRendererPixbuf() - locations.pack_start(cell, False) - locations.add_attribute(cell, 'pixbuf', 0) - - cell = gtk.CellRendererText() - locations.pack_start(cell, False) - locations.add_attribute(cell, 'text', 1) - - functions = gtk.TreeViewColumn() - self._tree.append_column(functions) - - cell = gtk.CellRendererPixbuf() - functions.pack_start(cell, False) - functions.add_attribute(cell, 'pixbuf', 2) + #print "check %s" % text - cell = gtk.CellRendererText() - functions.pack_start(cell, True) - functions.add_attribute(cell, 'text', 3) + name = pfn.search(text) - self._store = gtk.TreeStore(gtk.gdk.Pixbuf, str, gtk.gdk.Pixbuf, str) - self._tree.set_model(self._store) + if name != None: + #print " --> ", name.group(1) + db.check_call(i.address, name.group(1)) - pi = PanelItem('Permissions', 'Permissions', self._scrolled_window, 'SE') - pi.dock() + self._panel.memorize_permissions(binary, db.get_used_permissions()) diff --git a/plugins/python/androperms/db.py b/plugins/python/androperms/db.py new file mode 100644 index 0000000..625d400 --- /dev/null +++ b/plugins/python/androperms/db.py @@ -0,0 +1,94 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import os + + +class PermsDataBase: + """Display all permissions found in the Manifest.""" + + def __init__(self): + + self._perms = { } + self._used = { } + + self._load_all_definitions() + + + def _load_all_definitions(self): + """Load the database in memory.""" + + with open(os.path.dirname(__file__) + '/androperms.db', 'r') as f: + + for line in f.readlines(): + + perm = line.strip("\n").split("\t") + + for p in perm[1].split(" "): + + if not p.startswith("android.permission."): + continue + + if p not in self._perms: + self._perms[p] = [] + + call = perm[0].split("(")[0] + + if call not in self._perms[p]: + self._perms[p].append(call) + + + def filter_permissions(self, used): + """Forget all permissions which are not used.""" + + keep = {} + + for p in self._perms: + if p in used: + keep[p] = self._perms[p] + + self._perms = keep + + for p in keep: + self._used[p] = [] + + + def check_call(self, addr, line): + """Check if a call requires some rights.""" + + found = False + + for p in self._perms: + + if line.find("Wall") > -1: + print "[+]", line, ' ==> ', p + + for c in self._perms[p]: + + #print " - ", c + + #if line.find(c) > -1: + if c.find(line) > -1: + self._used[p].append([addr, c + "()"]) + #found = True + + if not found: + + func = line.split('.')[-1] + + for p in self._perms: + + for c in self._perms[p]: + + if line.find("Wall") > -1: + print " <> ", c, " vs ", func + + if c.find(func) > -1: + self._used[p].append([addr, line + "()"]) + break + + + def get_used_permissions(self): + """Provide the list of used permissions.""" + + return self._used diff --git a/plugins/python/androperms/panel.py b/plugins/python/androperms/panel.py index ea26f74..bebeed5 100644 --- a/plugins/python/androperms/panel.py +++ b/plugins/python/androperms/panel.py @@ -1,85 +1,120 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -import os +from pychrysalide.gui.panels import PanelItem import gtk +import os -class PermsPanel: - """Display all permissions found in the Manifest.""" +def _build_permissions_panel_content(): + """Build content for permissions panels.""" - def __init__(self): + scrolled_window = gtk.ScrolledWindow() + scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrolled_window.show() + + tree = gtk.TreeView() + tree.set_headers_visible(False) + tree.show() + scrolled_window.add_with_viewport(tree) + + locations = gtk.TreeViewColumn() + tree.append_column(locations) + + cell = gtk.CellRendererPixbuf() + locations.pack_start(cell, False) + locations.add_attribute(cell, 'pixbuf', 0) + + cell = gtk.CellRendererText() + locations.pack_start(cell, False) + locations.add_attribute(cell, 'text', 1) - self._perms = { } - self._used = { } - - self._load_all_definitions() + functions = gtk.TreeViewColumn() + tree.append_column(functions) + cell = gtk.CellRendererPixbuf() + functions.pack_start(cell, False) + functions.add_attribute(cell, 'pixbuf', 2) - def _load_all_definitions(self): - """Load the database in memory.""" + cell = gtk.CellRendererText() + functions.pack_start(cell, True) + functions.add_attribute(cell, 'text', 3) - with open(os.path.dirname(__file__) + '/androperms.db', 'r') as f: + store = gtk.TreeStore(gtk.gdk.Pixbuf, str, gtk.gdk.Pixbuf, str) + tree.set_model(store) - for line in f.readlines(): + return scrolled_window, tree, store - perm = line.strip("\n").split("\t") - for p in perm[1].split(" "): +class PermsPanel(PanelItem): + """Display all permissions found in the Manifest.""" - if not p.startswith("android.permission."): - continue + def __new__(cls): + """Create the GLib instance relative this class as soon as possible, + for the pygobject registering process.""" - if p not in self._perms: - self._perms[p] = [] + scrolled_window, tree, store = _build_permissions_panel_content() - call = perm[0].split("(")[0] + self = super(PermsPanel, cls).__new__(cls, 'Permissions', 'Android Permissions', \ + scrolled_window, 'SE') - if call not in self._perms[p]: - self._perms[p].append(call) + self._scrolled_window = scrolled_window + self._tree = tree + self._store = store + self._perms = {} - def filter_permissions(self, used): - """Forget all permissions which are not used.""" + return self - keep = {} - for p in self._perms: - if p in used: - keep[p] = self._perms[p] + def __init__(self): + """Initialize the Python instance of the panel.""" - self._perms = keep + self._tree.connect('row-activated', self._on_row_selection) - for p in keep: - self._used[p] = [] + self.dock() + self.register() - def check_call(self, addr, line): - """Check if a call requires some rights.""" + def memorize_permissions(self, binary, perms): + """Attach found permissions to a new loaded binary.""" - for p in self._perms: + self._perms[binary] = perms - for c in self._perms[p]: - if line.find(c) > -1: - self._used[p].append([addr, c + "()"]) + def update_for_binary(self, binary): + """Fill the treeview with all found permissions for the given binary.""" + self._store.clear() - def fill_tree(self, store): - """Fill a treeview with all found permissions.""" + used = self._perms[binary] - for p in self._used: + for p in used: - if len(self._used[p]) > 0 or True: + if len(used[p]) > 0 or True: img = os.path.dirname(os.path.abspath(__file__)) + '/android.png' buf = gtk.gdk.pixbuf_new_from_file(img) - it = store.append(None, [buf, p, None, None]) + it = self._store.append(None, [buf, p, None, None]) img = os.path.dirname(os.path.abspath(__file__)) + '/routine.png' buf = gtk.gdk.pixbuf_new_from_file(img) - for f in self._used[p]: - store.append(it, [None, "0x%08x" % f[0], buf, f[1]]) + for f in used[p]: + self._store.append(it, [None, "0x%08x" % f[0], buf, f[1]]) + + self._tree.expand_all() + + + def _on_row_selection(self, treeview, path, column): + """Scroll the current view to the selected address.""" + + selection = treeview.get_selection() + model, it = selection.get_selected() + + # On ne traite que les lignes de code + if model.get_value(it, 0) == None: + + self.get_current_view().scroll_to_address(int(model.get_value(it, 1), 16)) |