summaryrefslogtreecommitdiff
path: root/plugins/python
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2012-12-18 22:44:24 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2012-12-18 22:44:24 (GMT)
commitf4dbbab3190d13e61f125eea51a0ecec2ab9e897 (patch)
tree2362579b428c363e2cca94e0fa89b1e39b7a50e7 /plugins/python
parent64e09a6c3e39785975b5322973ed83734cedb82e (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')
-rw-r--r--plugins/python/androperms/Makefile.am1
-rw-r--r--plugins/python/androperms/androperms.py91
-rw-r--r--plugins/python/androperms/db.py94
-rw-r--r--plugins/python/androperms/panel.py121
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))