Esempio n. 1
0
    def reload_java_sources(self):
        """Reload completely the sources by asking Androguard
           to decompile it again. Useful when:
            - an element has been renamed to propagate the info
            - the current tab is changed because we do not know what user
              did since then, so we need to propagate previous changes as well
        """

        androconf.debug("Getting sources for %s" % self.current_class)

        lines = []
        lines.append(
            (
                "COMMENTS",
                [("COMMENT", "/*\n * filename:%s\n * digest:%s\n */\n" % (self.current_filename, self.current_digest))],
            )
        )
        lines.extend(self.current_class.get_source_ext())

        # TODO: delete doc when tab is closed? not deleted by "self" :(
        if hasattr(self, "doc"):
            del self.doc
        self.doc = SourceDocument(parent=self, lines=lines)
        self.setDocument(self.doc)

        # No need to save hightlighter. highlighBlock will automatically be called
        # because we passed the QTextDocument to QSyntaxHighlighter constructor
        if PYGMENTS:
            PygmentsHighlighter(self.doc, lexer=JavaLexer())
        else:
            androconf.debug("Pygments is not present !")
Esempio n. 2
0
    def __init__(self,
                 parent=None,
                 win=None,
                 current_class=None,
                 current_title=None,
                 current_filename=None,
                 current_digest=None,
                 session=None):
        super(SourceWindow, self).__init__(parent)
        androconf.debug("New source tab for: %s" % current_class)

        self.mainwin = win
        self.session = session
        self.current_class = current_class
        self.current_title = current_title
        self.current_filename = current_filename
        self.current_digest = current_digest

        self.title = current_title

        self.setReadOnly(True)

        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.CustomContextMenuHandler)

        self.cursorPositionChanged.connect(self.cursor_position_changed)
Esempio n. 3
0
    def reload_java_sources(self):
        '''Reload completely the sources by asking Androguard
           to decompile it again. Useful when:
            - an element has been renamed to propagate the info
            - the current tab is changed because we do not know what user
              did since then, so we need to propagate previous changes as well
        '''

        androconf.debug("Getting sources for %s" % self.current_class)

        lines = []
        lines.append(("COMMENTS",
                      [("COMMENT", "/*\n * filename:%s\n * digest:%s\n */\n" %
                        (self.current_filename, self.current_digest))]))
        lines.extend(self.current_class.get_source_ext())

        #TODO: delete doc when tab is closed? not deleted by "self" :(
        if hasattr(self, "doc"):
            del self.doc
        self.doc = SourceDocument(parent=self, lines=lines)
        self.setDocument(self.doc)

        #No need to save hightlighter. highlighBlock will automatically be called
        #because we passed the QTextDocument to QSyntaxHighlighter constructor
        if PYGMENTS:
            PygmentsHighlighter(self.doc, lexer=JavaLexer())
        else:
            androconf.debug("Pygments is not present !")
Esempio n. 4
0
    def __init__(
        self,
        parent=None,
        win=None,
        current_class=None,
        current_title=None,
        current_filename=None,
        current_digest=None,
        session=None,
    ):
        super(SourceWindow, self).__init__(parent)
        androconf.debug("New source tab for: %s" % current_class)

        self.mainwin = win
        self.session = session
        self.current_class = current_class
        self.current_title = current_title
        self.current_filename = current_filename
        self.current_digest = current_digest

        self.title = current_title

        self.setReadOnly(True)

        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.CustomContextMenuHandler)

        self.cursorPositionChanged.connect(self.cursor_position_changed)
Esempio n. 5
0
    def actionGoto(self):
        cursor = self.textCursor()
        start = cursor.selectionStart()
        end = cursor.selectionEnd()
        selection = cursor.selectedText()
        androconf.debug("Goto asked for '%s' (%d, %d)" % (selection, start, end))

        if start not in self.doc.binding.keys():
            self.mainwin.showStatus("Goto not available. No info for: '%s'." % selection)
            return

        t = self.doc.binding[start]
        if t[0] == "NAME_METHOD_INVOKE":
            class_, method_ = t[2].split(" -> ")
            if class_ == "this":
                class_ = self.path
            else:
                class_ = classdot2class(class_)
        else:
            self.mainwin.showStatus("Goto not available. Info ok: '%s' but object not supported." % selection)
            return

        androconf.debug("Found corresponding method: %s -> %s in source file: %s" % (class_, method_, self.path))

        if not self.mainwin.doesClassExist(class_):
            self.mainwin.showStatus("Goto not available. Class: %s not in database." % class_)
            return

        self.mainwin.openSourceWindow(class_, method=method_)
Esempio n. 6
0
 def addAPK(self, filename, data):
     digest = hashlib.sha256(data).hexdigest()
     androconf.debug("add APK:%s" % digest)
     apk = APK(data, True)
     self.analyzed_apk[digest] = apk
     self.analyzed_files[filename].append(digest)
     self.analyzed_digest[digest] = filename
     androconf.debug("added APK:%s" % digest)
     return (digest, apk)
Esempio n. 7
0
 def addAPK(self, filename, data):
     digest = hashlib.sha256(data).hexdigest()
     androconf.debug("add APK:%s" % digest)
     apk = APK(data, True)
     self.analyzed_apk[digest] = [apk]
     self.analyzed_files[filename].append(digest)
     self.analyzed_digest[digest] = filename
     androconf.debug("added APK:%s" % digest)
     return (digest, apk)
Esempio n. 8
0
    def actionInfo(self):
        cursor = self.textCursor()
        start = cursor.selectionStart()
        end = cursor.selectionEnd()
        androconf.debug("actionInfo asked for (%d, %d)" % (start, end))

        if start in self.doc.binding.keys():
            self.mainwin.showStatus("%s at position: (%d, %d)" % (str(self.doc.binding[start]), start, end))
        else:
            self.mainwin.showStatus("No info available.")
Esempio n. 9
0
    def itemDoubleClickedHandler(self, item, column):
        '''Signal sent by PySide when a tree element is clicked'''

        androconf.debug("item %s has been double clicked at column %s" % (str(item), str(column)))
        if item.childCount() != 0:
            self.mainwin.showStatus("Sources not available. %s is not a class" % path)
            return

        current_class, current_filename, current_digest = self._reverse_cache[item]
        self.mainwin.openSourceWindow(current_class)
Esempio n. 10
0
    def actionInfo(self):
        cursor = self.textCursor()
        start = cursor.selectionStart()
        end = cursor.selectionEnd()
        androconf.debug("actionInfo asked for (%d, %d)" % (start, end))

        if start in self.doc.binding.keys():
            self.mainwin.showStatus('%s at position: (%d, %d)' %
                                    (str(self.doc.binding[start]), start, end))
        else:
            self.mainwin.showStatus("No info available.")
Esempio n. 11
0
    def get_xrefs_list(cls, class_item, method=None):
        '''Static method called before creating a XrefDialog
           to check if there are xrefs to display
            method (optional): method of the class we are looking xref from
        '''
        androconf.debug("Getting XREF for %s" % class_item)

        item = class_item
        if method:
            item = method

        return XrefDialog.get_xrefs_list_from_element(item)
Esempio n. 12
0
    def runAnalysis(self, d, dx=None):
        androconf.debug("VMAnalysis ...")

        if dx is None:
            dx = newVMAnalysis(d)
        else:
            dx.add(d)

        dx.create_xref()
        d.set_decompiler(DecompilerDAD(d, dx))

        return dx
Esempio n. 13
0
    def get_xrefs_list(cls, class_item, method=None):
        '''Static method called before creating a XrefDialog
           to check if there are xrefs to display
            method (optional): method of the class we are looking xref from
        '''
        androconf.debug("Getting XREF for %s" % class_item)

        item = class_item
        if method:
            item = method

        return XrefDialog.get_xrefs_list_from_element(item)
Esempio n. 14
0
    def actionRename(self):
        cursor = self.textCursor()
        start = cursor.selectionStart()
        end = cursor.selectionEnd()
        selection = cursor.selectedText()
        androconf.debug("Rename asked for '%s' (%d, %d)" %
                        (selection, start, end))

        if start not in self.doc.binding.keys():
            self.mainwin.showStatus(
                "Rename not available. No info for: '%s'." % selection)
            return

        # Double check if we support the renaming for the type of
        # object before poping a new window to the user
        t = self.doc.binding[start]
        if t[0] == 'NAME_METHOD_PROTOTYPE':
            class_ = self.current_class
            method_ = t[1]
            if method_ == self.title:
                method_ = 'init'
            androconf.debug(
                "Found corresponding method: %s -> %s in source file: %s" %
                (class_, method_, self.current_filename))
        elif t[0] == 'NAME_METHOD_INVOKE':
            class_, method_ = t[2].split(' -> ')
            if class_ == 'this':
                class_ = self.current_class
            androconf.debug(
                "Found corresponding method: %s -> %s in source file: %s" %
                (class_, method_, self.current_filename))
        elif t[0] == 'NAME_PROTOTYPE':
            class_ = t[2] + '.' + t[1]
            androconf.debug(
                "Found corresponding class: %s in source file: %s" %
                (class_, self.current_filename))
        elif t[0] == 'NAME_FIELD':
            field_ = t[1]
            androconf.debug(
                "Found corresponding field: %s in source file: %s" %
                (field_, self.current_filename))
        else:
            self.mainwin.showStatus(
                "Rename not available. Info ok: '%s' but object not supported."
                % selection)
            return

        rwin = RenameDialog(parent=self,
                            win=self.mainwin,
                            element=selection,
                            info=(start, end))
        rwin.show()
Esempio n. 15
0
    def browse_to_method(self, method):
        """Scroll to the right place were the method is.

           TODO: implement it, because does not work for now.
        """

        # TODO: we need to find a way to scroll to the right place because
        #      moving the cursor is not enough. Indeed if it is already in the window
        #      it does not do nothing

        # TODO: idea, highlight the method in the screen so we do not have to search for it

        androconf.debug("Browsing to %s -> %s" % (self.current_class, method))
Esempio n. 16
0
    def itemDoubleClickedHandler(self, item, column):
        '''Signal sent by PySide when a tree element is clicked'''

        androconf.debug("item %s has been double clicked at column %s" %
                        (str(item), str(column)))
        if item.childCount() != 0:
            self.mainwin.showStatus(
                "Sources not available. %s is not a class" % path)
            return

        current_class, current_filename, current_digest = self._reverse_cache[
            item]
        self.mainwin.openSourceWindow(current_class)
Esempio n. 17
0
    def browse_to_method(self, method):
        '''Scroll to the right place were the method is.

           TODO: implement it, because does not work for now.
        '''

        #TODO: we need to find a way to scroll to the right place because
        #      moving the cursor is not enough. Indeed if it is already in the window
        #      it does not do nothing

        #TODO: idea, highlight the method in the screen so we do not have to search for it

        androconf.debug("Browsing to %s -> %s" % (self.current_class, method))
Esempio n. 18
0
    def addDEY(self, filename, data, dx=None):
        digest = hashlib.sha256(data).hexdigest()
        androconf.debug("add DEY:%s" % digest)

        d = DalvikOdexVMFormat(data)
        dx = self.runAnalysis(d, dx)

        androconf.debug("added DEY:%s" % digest)

        self.analyzed_dex[digest] = (d, dx)
        self.analyzed_files[filename].append(digest)
        self.analyzed_digest[digest] = filename

        return (digest, d, dx)
Esempio n. 19
0
    def cursor_position_changed(self):
        """Used to detect when cursor change position and to auto select word
           underneath it"""
        androconf.debug("cursor_position_changed")

        cur = self.textCursor()
        androconf.debug(cur.position())
        androconf.debug(cur.selectedText())
        if len(cur.selectedText()) == 0:
            cur.select(QtGui.QTextCursor.SelectionType.WordUnderCursor)
            self.setTextCursor(cur)
            androconf.debug("cursor: %s" % cur.selectedText())
        else:
            androconf.debug("cursor: no selection %s" % cur.selectedText())
Esempio n. 20
0
    def cursor_position_changed(self):
        '''Used to detect when cursor change position and to auto select word
           underneath it'''
        androconf.debug("cursor_position_changed")

        cur = self.textCursor()
        androconf.debug(cur.position())
        androconf.debug(cur.selectedText())
        if len(cur.selectedText()) == 0:
            cur.select(QtGui.QTextCursor.SelectionType.WordUnderCursor)
            self.setTextCursor(cur)
            androconf.debug("cursor: %s" % cur.selectedText())
        else:
            androconf.debug("cursor: no selection %s" % cur.selectedText())
Esempio n. 21
0
        def worker(idx, q):
            debug("Running worker-%d" % idx)

            while True:
                a, d, dx, axmlobj, arscobj = None, None, None, None, None
                try:
                    filename, fileraw = q.get()
                    id_file = zlib.adler32(fileraw)

                    debug("(worker-%d) get %s %d" % (idx, filename, id_file))

                    log = self.settings["log"](id_file, filename)

                    is_analysis_dex, is_analysis_adex = True, True
                    debug("(worker-%d) filtering file %d" % (idx, id_file))
                    filter_file_ret, filter_file_type = myandro.filter_file(
                        log, fileraw)
                    if filter_file_ret:
                        debug("(worker-%d) analysis %s" %
                              (id_file, filter_file_type))

                        if filter_file_type == "APK":
                            a = myandro.create_apk(log, fileraw)
                            is_analysis_dex = myandro.analysis_apk(log, a)
                            fileraw = a.get_dex()
                            filter_file_type = androconf.is_android_raw(
                                fileraw)

                        elif filter_file_type == "AXML":
                            axmlobj = myandro.create_axml(log, fileraw)
                            myandro.analysis_axml(log, axmlobj)

                        elif filter_file_type == "ARSC":
                            arscobj = myandro.create_arsc(log, fileraw)
                            myandro.analysis_arsc(log, arscobj)

                        if is_analysis_dex and filter_file_type == "DEX":
                            d = myandro.create_dex(log, fileraw)
                            is_analysis_adex = myandro.analysis_dex(log, d)

                        elif is_analysis_dex and filter_file_type == "DEY":
                            d = myandro.create_dey(log, fileraw)
                            is_analysis_adex = myandro.analysis_dey(log, d)

                        if is_analysis_adex and d:
                            dx = myandro.create_adex(log, d)
                            myandro.analysis_adex(log, dx)

                        myandro.analysis_app(log, a, d, dx)

                    myandro.finish(log)
                except Exception, why:
                    myandro.crash(log, why)
                    myandro.finish(log)

                del a, d, dx, axmlobj, arscobj
                q.task_done()
Esempio n. 22
0
def AnalyzeAPK(filename, raw=False, decompiler="dad"):
    """
        Analyze an android application and setup all stuff for a more quickly analysis !

        :param filename: the filename of the android application or a buffer which represents the application
        :type filename: string
        :param raw: True is you would like to use a buffer (optional)
        :type raw: boolean
        :param decompiler: ded, dex2jad, dad (optional)
        :type decompiler: string

        :rtype: return the :class:`APK`, :class:`DalvikVMFormat`, and :class:`VMAnalysis` objects
    """
    androconf.debug("APK ...")
    a = APK(filename, raw)
    d, dx = AnalyzeDex(a.get_dex(), raw=True, decompiler=decompiler)
    return a, d, dx
Esempio n. 23
0
    def worker(idx, q):
      debug("Running worker-%d" % idx)

      while True:
        a, d, dx, axmlobj, arscobj = None, None, None, None, None
        try:
          filename, fileraw = q.get()
          id_file = zlib.adler32(fileraw)

          debug("(worker-%d) get %s %d" % (idx, filename, id_file))

          log = self.settings["log"](id_file, filename)

          is_analysis_dex, is_analysis_adex = True, True
          debug("(worker-%d) filtering file %d" % (idx, id_file))
          filter_file_ret, filter_file_type = myandro.filter_file(log, fileraw)
          if filter_file_ret:
            debug("(worker-%d) analysis %s" % (id_file, filter_file_type))

            if filter_file_type == "APK":
              a = myandro.create_apk(log, fileraw)
              is_analysis_dex = myandro.analysis_apk(log, a)
              fileraw = a.get_dex()
              filter_file_type = androconf.is_android_raw(fileraw)

            elif filter_file_type == "AXML":
              axmlobj = myandro.create_axml(log, fileraw)
              myandro.analysis_axml(log, axmlobj)

            elif filter_file_type == "ARSC":
              arscobj = myandro.create_arsc(log, fileraw)
              myandro.analysis_arsc(log, arscobj)

            if is_analysis_dex and filter_file_type == "DEX":
              d = myandro.create_dex(log, fileraw)
              is_analysis_adex = myandro.analysis_dex(log, d)

            elif is_analysis_dex and filter_file_type == "DEY":
              d = myandro.create_dey(log, fileraw)
              is_analysis_adex = myandro.analysis_dey(log, d)

            if is_analysis_adex and d:
              dx = myandro.create_adex(log, d)
              myandro.analysis_adex(log, dx)

            myandro.analysis_app(log, a, d, dx)

          myandro.finish(log)
        except Exception, why:
          myandro.crash(log, why)
          myandro.finish(log)

        del a, d, dx, axmlobj, arscobj
        q.task_done()
Esempio n. 24
0
    def run(self):
        if self.incoming_file:
            try:
                file_path, file_type = self.incoming_file
                if file_type in ["APK", "DEX", "DEY"]:
                    ret = self.session.add(file_path,
                                           open(file_path, 'r').read())
                    self.emit(QtCore.SIGNAL("loadedFile(bool)"), ret)
                elif file_type == "SESSION":
                    self.session.load(file_path)
                    self.emit(QtCore.SIGNAL("loadedFile(bool)"), True)
            except Exception as e:
                androconf.debug(e)
                androconf.debug(traceback.format_exc())
                self.emit(QtCore.SIGNAL("loadedFile(bool)"), False)

            self.incoming_file = []
        else:
            self.emit(QtCore.SIGNAL("loadedFile(bool)"), False)
Esempio n. 25
0
    def run(self):
        if self.incoming_file:
            try:
                file_path, file_type = self.incoming_file
                if file_type in ["APK", "DEX", "DEY"]:
                    ret = self.session.add(file_path,
                                           open(file_path, 'r').read())
                    self.emit(QtCore.SIGNAL("loadedFile(bool)"), ret)
                elif file_type == "SESSION" :
                    self.session.load(file_path)
                    self.emit(QtCore.SIGNAL("loadedFile(bool)"), True)
            except Exception as e:
                androconf.debug(e)
                androconf.debug(traceback.format_exc())
                self.emit(QtCore.SIGNAL("loadedFile(bool)"), False)

            self.incoming_file = []
        else:
            self.emit(QtCore.SIGNAL("loadedFile(bool)"), False)
Esempio n. 26
0
    def fill(self):
        '''Parse all the paths (['Lcom/example/myclass/MyActivity$1;', ...])
           and build a tree using the QTreeWidgetItem insertion method.'''
        androconf.debug("Fill classes tree")

        for idx, filename, digest, classes in self.session.get_classes():
            for c in sorted(classes, key=lambda c: c.name):
                sig = Signature(c)
                path_node = self.root_path_node

                path = None
                if sig.class_path == []:
                    path = '.'
                    if path not in path_node[0]:
                        path_node[0][path] = ({},
                                              QtGui.QTreeWidgetItem(
                                                  path_node[1]))
                        path_node[0][path][1].setText(0, path)
                    path_node = path_node[0][path]
                else:
                    # Namespaces
                    for path in sig.class_path:
                        if path not in path_node[0]:
                            path_node[0][path] = ({},
                                                  QtGui.QTreeWidgetItem(
                                                      path_node[1]))
                            path_node[0][path][1].setText(0, path)
                        path_node = path_node[0][path]

                # Class
                path_node[0][path] = ({}, QtGui.QTreeWidgetItem(path_node[1]))

                class_name = sig.class_name

                if idx > 0:
                    class_name += "@%d" % idx

                c.current_title = class_name
                self._reverse_cache[path_node[0][path][1]] = (c, filename,
                                                              digest)

                path_node[0][path][1].setText(0, class_name)
Esempio n. 27
0
    def get_xrefs_list_from_element(cls, element):
        '''Helper for get_xrefs_list

           element is a ClassDefItem or MethodDefItem

           At the end of the function, we lost if we worked on
           a class or method but we do not care for now.
        '''

        xref_items = element.XREFfrom.items
        androconf.debug("%d XREFs found" % len(xref_items))
#        print xref_items
        xrefs = []
        for xref_item in xref_items:
            class_ = xref_item[0].get_class_name()
            method_ = xref_item[0].get_name()
            descriptor_ = xref_item[0].get_descriptor()
            xrefs.append(classmethod2display(class_, method_, descriptor_))
#        print xrefs
        return xrefs
Esempio n. 28
0
    def actionRename(self):
        cursor = self.textCursor()
        start = cursor.selectionStart()
        end = cursor.selectionEnd()
        selection = cursor.selectedText()
        androconf.debug("Rename asked for '%s' (%d, %d)" % (selection, start, end))

        if start not in self.doc.binding.keys():
            self.mainwin.showStatus("Rename not available. No info for: '%s'." % selection)
            return

        # Double check if we support the renaming for the type of
        # object before poping a new window to the user
        t = self.doc.binding[start]
        if t[0] == "NAME_METHOD_PROTOTYPE":
            class_ = self.current_class
            method_ = t[1]
            if method_ == self.title:
                method_ = "init"
            androconf.debug(
                "Found corresponding method: %s -> %s in source file: %s" % (class_, method_, self.current_filename)
            )
        elif t[0] == "NAME_METHOD_INVOKE":
            class_, method_ = t[2].split(" -> ")
            if class_ == "this":
                class_ = self.current_class
            androconf.debug(
                "Found corresponding method: %s -> %s in source file: %s" % (class_, method_, self.current_filename)
            )
        elif t[0] == "NAME_PROTOTYPE":
            class_ = t[2] + "." + t[1]
            androconf.debug("Found corresponding class: %s in source file: %s" % (class_, self.current_filename))
        elif t[0] == "NAME_FIELD":
            field_ = t[1]
            androconf.debug("Found corresponding field: %s in source file: %s" % (field_, self.current_filename))
        else:
            self.mainwin.showStatus("Rename not available. Info ok: '%s' but object not supported." % selection)
            return

        rwin = RenameDialog(parent=self, win=self.mainwin, element=selection, info=(start, end))
        rwin.show()
Esempio n. 29
0
    def fill(self):
        '''Parse all the paths (['Lcom/example/myclass/MyActivity$1;', ...])
           and build a tree using the QTreeWidgetItem insertion method.'''
        androconf.debug("Fill classes tree")

        for idx, filename, digest, classes in self.session.get_classes():
            for c in sorted(classes, key=lambda c: c.name):
                sig = Signature(c)
                path_node = self.root_path_node

                path = None
                if sig.class_path == []:
                    path = '.'
                    if path not in path_node[0]:
                        path_node[0][path] = ({}, QtGui.QTreeWidgetItem(path_node[1]))
                        path_node[0][path][1].setText(0, path)
                    path_node = path_node[0][path]
                else:
                    # Namespaces
                    for path in sig.class_path:
                        if path not in path_node[0]:
                            path_node[0][path] = ({}, QtGui.QTreeWidgetItem(path_node[1]))
                            path_node[0][path][1].setText(0, path)
                        path_node = path_node[0][path]

                # Class
                path_node[0][path] = ({}, QtGui.QTreeWidgetItem(path_node[1]))

                class_name = sig.class_name

                if idx > 0:
                    class_name += "@%d" % idx

                c.current_title = class_name
                self._reverse_cache[path_node[0][path][1]] = (c,
                                                              filename,
                                                              digest)


                path_node[0][path][1].setText(0, class_name)
Esempio n. 30
0
    def get_xrefs_list_from_element(cls, element):
        '''Helper for get_xrefs_list

           element is a ClassDefItem or MethodDefItem

           At the end of the function, we lost if we worked on
           a class or method but we do not care for now.
        '''

        xref_items = element.XREFfrom.items
        androconf.debug("%d XREFs found" % len(xref_items))
        #        print xref_items
        xrefs = []
        for xref_item in xref_items:
            class_ = xref_item[0].get_class_name()
            method_ = xref_item[0].get_name()
            descriptor_ = xref_item[0].get_descriptor()
            xrefs.append(classmethod2display(class_, method_, descriptor_))


#        print xrefs
        return xrefs
Esempio n. 31
0
def RunDecompiler(d, dx, decompiler):
    """
        Run the decompiler on a specific analysis

        :param d: the DalvikVMFormat object
        :type d: :class:`DalvikVMFormat` object
        :param dx: the analysis of the format
        :type dx: :class:`VMAnalysis` object
        :param decompiler: the type of decompiler to use ("dad", "dex2jad", "ded")
        :type decompiler: string
    """
    if decompiler != None:
      androconf.debug("Decompiler ...")
      decompiler = decompiler.lower()
      if decompiler == "dex2jad":
        d.set_decompiler(DecompilerDex2Jad(d,
                                           androconf.CONF["PATH_DEX2JAR"],
                                           androconf.CONF["BIN_DEX2JAR"],
                                           androconf.CONF["PATH_JAD"],
                                           androconf.CONF["BIN_JAD"],
                                           androconf.CONF["TMP_DIRECTORY"]))
      elif decompiler == "dex2fernflower":
        d.set_decompiler(DecompilerDex2Fernflower(d,
                                                  androconf.CONF["PATH_DEX2JAR"],
                                                  androconf.CONF["BIN_DEX2JAR"],
                                                  androconf.CONF["PATH_FERNFLOWER"],
                                                  androconf.CONF["BIN_FERNFLOWER"],
                                                  androconf.CONF["OPTIONS_FERNFLOWER"],
                                                  androconf.CONF["TMP_DIRECTORY"]))
      elif decompiler == "ded":
        d.set_decompiler(DecompilerDed(d,
                                       androconf.CONF["PATH_DED"],
                                       androconf.CONF["BIN_DED"],
                                       androconf.CONF["TMP_DIRECTORY"]))
      else:
        d.set_decompiler(DecompilerDAD(d, dx))
Esempio n. 32
0
    def actionGoto(self):
        cursor = self.textCursor()
        start = cursor.selectionStart()
        end = cursor.selectionEnd()
        selection = cursor.selectedText()
        androconf.debug("Goto asked for '%s' (%d, %d)" %
                        (selection, start, end))

        if start not in self.doc.binding.keys():
            self.mainwin.showStatus("Goto not available. No info for: '%s'." %
                                    selection)
            return

        t = self.doc.binding[start]
        if t[0] == 'NAME_METHOD_INVOKE':
            class_, method_ = t[2].split(' -> ')
            if class_ == 'this':
                class_ = self.path
            else:
                class_ = classdot2class(class_)
        else:
            self.mainwin.showStatus(
                "Goto not available. Info ok: '%s' but object not supported." %
                selection)
            return

        androconf.debug(
            "Found corresponding method: %s -> %s in source file: %s" %
            (class_, method_, self.path))

        if not self.mainwin.doesClassExist(class_):
            self.mainwin.showStatus(
                "Goto not available. Class: %s not in database." % class_)
            return

        self.mainwin.openSourceWindow(class_, method=method_)
Esempio n. 33
0
    def addDEX(self, filename, data):
        digest = hashlib.sha256(data).hexdigest()
        androconf.debug("add DEX:%s" % digest)

        d = DalvikVMFormat(data)
        androconf.debug("VMAnalysis ...")
        dx = newVMAnalysis(d)
        dx.create_xref()

        d.set_decompiler(DecompilerDAD(d, dx))

        androconf.debug("added DEX:%s" % digest)

        self.analyzed_dex[digest] = (d, dx)
        self.analyzed_files[filename].append(digest)
        self.analyzed_digest[digest] = filename

        return (digest, d, dx)
Esempio n. 34
0
 def display_bytecodes(self):
     androconf.debug("Display bytecodes for %s" % self.current_class)
     self.mainwin.openBytecodeWindow(self.current_class)
Esempio n. 35
0
    def renameElement(self, oldname, newname, info):
        """Called back after a user chose a new name for an element.
        """

        androconf.debug("Renaming %s into %s in %s" % (oldname, newname, self.current_filename))
        start, end = info
        try:
            t = self.doc.binding[start]
        except:
            self.mainwin.showStatus("Unexpected error in renameElement")
            return

        # Determine type of the to-be-renamed element and Androguard internal objects
        type_ = None
        if t[0] == "NAME_METHOD_PROTOTYPE":  # method definition in a class
            method_ = t[1]
            if method_ == self.title:
                method_ = "init"

            proto_ = t[2].method.proto
            androconf.debug("Found: class=%s, method=%s, proto=%s" % (self.current_class, method_, proto_))
            type_ = "METHOD"
        elif t[0] == "NAME_METHOD_INVOKE":  # method call in a method
            class_, method_ = t[2].split(" -> ")
            class_ = classdot2class(class_)
            if class_ == "this":
                class_ = self.path
            proto_ = proto2methodprotofunc("".join(t[3]) + t[4])
            androconf.debug("Found: class=%s, method=%s, proto=%s" % (class_, method_, proto_))
            type_ = "METHOD"
        elif t[0] == "NAME_PROTOTYPE":  # class definition on top of a class
            class_ = t[2] + "." + t[1]
            package_ = t[2]
            androconf.debug("Found: package=%s, class=%s" % (package_, class_))
            type_ = "CLASS"
        elif t[0] == "NAME_FIELD":
            field_item = t[3]
            type_ = "FIELD"
        else:
            self.mainwin.showStatus("Rename not available. Info found: '%s' but object not supported." % selection)
            return

        # Do the actual renaming
        if type_ == "METHOD":
            if self.method_name_exist(newname):
                self.mainwin.showStatus("Method name already exist")
                return

            method_class_name = self.current_class.get_name()
            method_name = method_
            method_proto = proto_
            current_analysis = self.session.get_analysis(self.current_class)

            method_item = current_analysis.get_method_by_name(method_class_name, method_name, method_proto)
            if not method_item:
                self.mainwin.showStatus("Impossible to find the method")
                return

            method_item.set_name(str(newname))  # unicode to ascii
        elif type_ == "CLASS":
            newname_class = classdot2class(package_ + "." + newname)
            self.mainwin.showStatus("New name: %s" % newname_class)
            class_item = self.current_class  # getattr(self.mainwin.d, classdot2func(class_))
            class_item.set_name(str(newname_class))  # unicode to ascii
            self.mainwin.updateDockWithTree()
        elif type_ == "FIELD":
            if self.field_name_exist(newname):
                self.mainwin.showStatus("Field name already exist")
                return
            field_item.set_name(str(newname))
        else:
            self.mainwin.showStatus("Unsupported type: %s" % str(type_))
            return
        self.reload_java_sources()
Esempio n. 36
0
def AnalyzeDex(filename, raw=False, decompiler="dad"):
    """
        Analyze an android dex file and setup all stuff for a more quickly analysis !

        :param filename: the filename of the android dex file or a buffer which represents the dex file
        :type filename: string
        :param raw: True is you would like to use a buffer (optional)
        :type raw: boolean

        :rtype: return the :class:`DalvikVMFormat`, and :class:`VMAnalysis` objects
    """
    androconf.debug("DalvikVMFormat ...")

    d = None
    if raw == False:
        d = DalvikVMFormat(read(filename))
    else:
        d = DalvikVMFormat(filename)

    androconf.debug("Export VM to python namespace")
    d.create_python_export()

    androconf.debug("VMAnalysis ...")
    dx = uVMAnalysis(d)

    androconf.debug("GVMAnalysis ...")
    gx = GVMAnalysis(dx, None)

    d.set_vmanalysis(dx)
    d.set_gvmanalysis(gx)

    RunDecompiler(d, dx, decompiler)

    androconf.debug("XREF ...")
    d.create_xref()
    androconf.debug("DREF ...")
    d.create_dref()

    return d, dx
Esempio n. 37
0
    def actionXref(self):
        cursor = self.textCursor()
        start = cursor.selectionStart()
        end = cursor.selectionEnd()
        selection = cursor.selectedText()
        androconf.debug("Xref asked for '%s' (%d, %d)" % (selection, start, end))

        if start not in self.doc.binding.keys():
            self.mainwin.showStatus("Xref not available. No info for: '%s'." % selection)
            return

        class_ = None
        method_ = None
        t = self.doc.binding[start]
        print t

        if t[0] == "NAME_METHOD_PROTOTYPE":
            method_ = t[1]
            if method_ == self.title:
                method_ = "init"

            proto_ = t[2].method.proto

            method_class_name = self.current_class.get_name()
            method_name = method_
            method_proto = proto_
            current_analysis = self.session.get_analysis(self.current_class)

            androconf.debug(
                "Found corresponding method: %s %s %s in source file: %s"
                % (method_class_name, method_name, method_proto, self.current_filename)
            )

            class_analysis = current_analysis.get_class_analysis(self.current_class.get_name())
            if not class_analysis:
                self.mainwin.showStatus("No xref returned (no class_analysis object).")
                return

            method_analysis = class_analysis.get_method_analysis(
                current_analysis.get_method_by_name(method_class_name, method_name, method_proto)
            )
            print method_analysis
            if not method_analysis:
                self.mainwin.showStatus("No xref returned (no method_analysis object).")
                return

            xwin = XrefDialogMethod(
                parent=self.mainwin,
                win=self.mainwin,
                current_class=self.current_class,
                class_analysis=class_analysis,
                method_analysis=method_analysis,
            )
            xwin.show()
        elif t[0] == "NAME_FIELD":
            field_ = t[3]

            current_analysis = self.session.get_analysis(self.current_class)
            class_analysis = current_analysis.get_class_analysis(self.current_class.get_name())
            if not class_analysis:
                self.mainwin.showStatus("No xref returned (no class_analysis object).")
                return

            field_analysis = class_analysis.get_field_analysis(field_)
            print field_analysis
            if not field_analysis:
                self.mainwin.showStatus("No xref returned (no field_analysis object).")
                return

            xwin = XrefDialogField(
                parent=self.mainwin,
                win=self.mainwin,
                current_class=self.current_class,
                class_analysis=class_analysis,
                field_analysis=field_analysis,
            )
            xwin.show()
        else:
            self.mainwin.showStatus("No xref returned.")
            return
Esempio n. 38
0
    def analyze_axml(self, a, flags):
      perms = {
                "SEND_SMS"                  : [ "MONEY",    "SMS" ],
                "SEND_SMS_NO_CONFIRMATION"  : [ "MONEY",    "SMS"],
                "READ_SMS"                  : [ "SMS",      "PRIVACY" ],
                "WRITE_SMS"                 : [ "MONEY",    "SMS" ],
                "RECEIVE_SMS"               : [ "SMS",      "PRIVACY" ],
                "RECEIVE_MMS"               : [ "SMS",      "PRIVACY" ],

                "PHONE_CALL"                : [ "MONEY",    "CALL" ],
                "PROCESS_OUTGOING_CALLS"    : [ "MONEY",    "CALL" ],
                "CALL_PRIVILEGED"           : [ "MONEY",    "CALL" ],

                "INTERNET"                  : [ "INTERNET" ],

                "READ_PHONE_STATE"          : [ "PRIVACY" ],

                "READ_CONTACTS"             : [ "PRIVACY" ],
                "WRITE_CONTACTS"            : [ "PRIVACY" ],

                "READ_HISTORY_BOOKMARKS"    : [ "PRIVACY" ],
                "WRITE_HISTORY_BOOKMARKS"   : [ "PRIVACY" ],

                "READ_PROFILE"              : [ "PRIVACY" ],
                "WRITE_PROFILE"             : [ "PRIVACY" ],

                "READ_SOCIAL_STREAM"        : [ "PRIVACY" ],
                "WRITE_SOCIAL_STREAM"       : [ "PRIVACY" ],

                "READ_CALENDAR"             : [ "PRIVACY" ],
                "WRITE_CALENDAR"            : [ "PRIVACY" ],

                "READ_USER_DICTIONARY"      : [ "PRIVACY" ],
                "WRITE_USER_DICTIONARY"     : [ "PRIVACY" ],

                "SET_ALARM"                 : [ "PRIVACY" ],

                "ADD_VOICEMAIL"             : [ "PRIVACY" ],

                "GET_ACCOUNTS"              : [ "PRIVACY" ],
                "MANAGE_ACCOUNTS"           : [ "PRIVACY" ],

                "RECORD_AUDIO"              : [ "PRIVACY" ],
                "CAMERA"                    : [ "PRIVACY" ],


                "ACCESS_FINE_LOCATION"      : [ "PRIVACY",  "GPS" ],
                "ACCESS_COARSE_LOCATION"    : [ "PRIVACY",  "GPS" ],
                "ACCESS_LOCATION_EXTRA_COMMANS" : [ "GPS"],
                "INSTALL_LOCATION_PROVIDER" : [ "GPS" ],
      }

      for i in a.get_permissions():
        perm = i.split(".")[-1]

        try:
          flags[ DVM_PERMISSIONS["MANIFEST_PERMISSION"][perm][0].upper() ] += 1

          for j in perms:
            if j == perm:
              for k in perms[j]:
                flags[k] += 1
        except:
          debug("Unknown permission %s" % perm)
Esempio n. 39
0
 def display_bytecodes(self):
     androconf.debug("Display bytecodes for %s" % self.current_class)
     self.mainwin.openBytecodeWindow(self.current_class)
Esempio n. 40
0
    def actionXref(self):
        cursor = self.textCursor()
        start = cursor.selectionStart()
        end = cursor.selectionEnd()
        selection = cursor.selectedText()
        androconf.debug("Xref asked for '%s' (%d, %d)" %
                        (selection, start, end))

        if start not in self.doc.binding.keys():
            self.mainwin.showStatus("Xref not available. No info for: '%s'." %
                                    selection)
            return

        class_ = None
        method_ = None
        t = self.doc.binding[start]
        print t

        if t[0] == 'NAME_METHOD_PROTOTYPE':
            method_ = t[1]
            if method_ == self.title:
                method_ = 'init'

            proto_ = t[2].method.proto

            method_class_name = self.current_class.get_name()
            method_name = method_
            method_proto = proto_
            current_analysis = self.session.get_analysis(self.current_class)

            androconf.debug(
                "Found corresponding method: %s %s %s in source file: %s" %
                (method_class_name, method_name, method_proto,
                 self.current_filename))

            class_analysis = current_analysis.get_class_analysis(
                self.current_class.get_name())
            if not class_analysis:
                self.mainwin.showStatus(
                    "No xref returned (no class_analysis object).")
                return

            method_analysis = class_analysis.get_method_analysis(
                current_analysis.get_method_by_name(method_class_name,
                                                    method_name, method_proto))
            print method_analysis
            if not method_analysis:
                self.mainwin.showStatus(
                    "No xref returned (no method_analysis object).")
                return

            xwin = XrefDialogMethod(parent=self.mainwin,
                                    win=self.mainwin,
                                    current_class=self.current_class,
                                    class_analysis=class_analysis,
                                    method_analysis=method_analysis)
            xwin.show()
        elif t[0] == 'NAME_FIELD':
            field_ = t[3]

            current_analysis = self.session.get_analysis(self.current_class)
            class_analysis = current_analysis.get_class_analysis(
                self.current_class.get_name())
            if not class_analysis:
                self.mainwin.showStatus(
                    "No xref returned (no class_analysis object).")
                return

            field_analysis = class_analysis.get_field_analysis(field_)
            print field_analysis
            if not field_analysis:
                self.mainwin.showStatus(
                    "No xref returned (no field_analysis object).")
                return

            xwin = XrefDialogField(parent=self.mainwin,
                                   win=self.mainwin,
                                   current_class=self.current_class,
                                   class_analysis=class_analysis,
                                   field_analysis=field_analysis)
            xwin.show()
        else:
            self.mainwin.showStatus("No xref returned.")
            return
Esempio n. 41
0
    def renameElement(self, oldname, newname, info):
        '''Called back after a user chose a new name for an element.
        '''

        androconf.debug("Renaming %s into %s in %s" %
                        (oldname, newname, self.current_filename))
        start, end = info
        try:
            t = self.doc.binding[start]
        except:
            self.mainwin.showStatus("Unexpected error in renameElement")
            return

        # Determine type of the to-be-renamed element and Androguard internal objects
        type_ = None
        if t[0] == 'NAME_METHOD_PROTOTYPE':  # method definition in a class
            method_ = t[1]
            if method_ == self.title:
                method_ = 'init'

            proto_ = t[2].method.proto
            androconf.debug("Found: class=%s, method=%s, proto=%s" %
                            (self.current_class, method_, proto_))
            type_ = "METHOD"
        elif t[0] == 'NAME_METHOD_INVOKE':  # method call in a method
            class_, method_ = t[2].split(' -> ')
            class_ = classdot2class(class_)
            if class_ == 'this':
                class_ = self.path
            proto_ = proto2methodprotofunc("".join(t[3]) + t[4])
            androconf.debug("Found: class=%s, method=%s, proto=%s" %
                            (class_, method_, proto_))
            type_ = "METHOD"
        elif t[0] == 'NAME_PROTOTYPE':  # class definition on top of a class
            class_ = t[2] + '.' + t[1]
            package_ = t[2]
            androconf.debug("Found: package=%s, class=%s" % (package_, class_))
            type_ = "CLASS"
        elif t[0] == 'NAME_FIELD':
            field_item = t[3]
            type_ = "FIELD"
        else:
            self.mainwin.showStatus(
                "Rename not available. Info found: '%s' but object not supported."
                % selection)
            return

        # Do the actual renaming
        if type_ == "METHOD":
            if self.method_name_exist(newname):
                self.mainwin.showStatus("Method name already exist")
                return

            method_class_name = self.current_class.get_name()
            method_name = method_
            method_proto = proto_
            current_analysis = self.session.get_analysis(self.current_class)

            method_item = current_analysis.get_method_by_name(
                method_class_name, method_name, method_proto)
            if not method_item:
                self.mainwin.showStatus("Impossible to find the method")
                return

            method_item.set_name(str(newname))  #unicode to ascii
        elif type_ == "CLASS":
            newname_class = classdot2class(package_ + '.' + newname)
            self.mainwin.showStatus("New name: %s" % newname_class)
            class_item = self.current_class  #getattr(self.mainwin.d, classdot2func(class_))
            class_item.set_name(str(newname_class))  #unicode to ascii
            self.mainwin.updateDockWithTree()
        elif type_ == 'FIELD':
            if self.field_name_exist(newname):
                self.mainwin.showStatus("Field name already exist")
                return
            field_item.set_name(str(newname))
        else:
            self.mainwin.showStatus("Unsupported type: %s" % str(type_))
            return
        self.reload_java_sources()