Example #1
0
    def get_app_name(self):
        """
            Return the appname of the APK

            :rtype: string
        """
        main_activity_name = self.get_main_activity()

        app_name = self.get_element('activity',
                                    'label',
                                    name=main_activity_name)
        if not app_name:
            app_name = self.get_element('application', 'label')

        if app_name is None:
            # No App name set
            # TODO return packagename instead?
            return ""
        if app_name.startswith("@"):
            res_id = int(app_name[1:], 16)
            res_parser = self.get_android_resources()

            try:
                app_name = res_parser.get_resolved_res_configs(
                    res_id, ARSCResTableConfig.default_config())[0][1]
            except Exception as e:
                androconf.warning("Exception selecting app name: %s" % e)
                app_name = ""
        return app_name
Example #2
0
    def visit_fill_array(self, array, value):
        self.write_ind()
        array.visit(self)
        self.write(' = {', data="ARRAY_FILLED")
        data = value.get_data()
        tab = []
        elem_size = value.element_width

        # Set type depending on size of elements
        data_types = {1: 'b', 2: 'h', 4: 'i', 8: 'd'}

        if elem_size in data_types:
            elem_id = data_types[elem_size]
        else:
            # FIXME for other types we just assume bytes...
            warning("Unknown element size {} for array. Assume bytes.".format(
                elem_size))
            elem_id = 'b'
            elem_size = 1

        for i in range(0, value.size * elem_size, elem_size):
            tab.append('%s' % unpack(elem_id, data[i:i + elem_size])[0])
        self.write(', '.join(tab), data="COMMA")
        self.write('}', data="ARRAY_FILLED_END")
        self.end_ins()
Example #3
0
    def get_app_icon(self, max_dpi=65536):
        """
            Return the first non-greater density than max_dpi icon file name,
            unless exact icon resolution is set in the manifest, in which case
            return the exact file

            From https://developer.android.com/guide/practices/screens_support.html
            ldpi (low) ~120dpi
            mdpi (medium) ~160dpi
            hdpi (high) ~240dpi
            xhdpi (extra-high) ~320dpi
            xxhdpi (extra-extra-high) ~480dpi
            xxxhdpi (extra-extra-extra-high) ~640dpi

            :rtype: string
        """
        main_activity_name = self.get_main_activity()

        app_icon = self.get_element('activity',
                                    'icon',
                                    name=main_activity_name)

        if not app_icon:
            app_icon = self.get_element('application', 'icon')

        if not app_icon:
            res_id = self.get_android_resources().get_res_id_by_key(
                self.package, 'mipmap', 'ic_launcher')
            if res_id:
                app_icon = "@%x" % res_id

        if not app_icon:
            res_id = self.get_android_resources().get_res_id_by_key(
                self.package, 'drawable', 'ic_launcher')
            if res_id:
                app_icon = "@%x" % res_id

        if not app_icon:
            # If the icon can not be found, return now
            return None

        if app_icon.startswith("@"):
            res_id = int(app_icon[1:], 16)
            res_parser = self.get_android_resources()
            candidates = res_parser.get_resolved_res_configs(res_id)

            app_icon = None
            current_dpi = -1

            try:
                for config, file_name in candidates:
                    dpi = config.get_density()
                    if current_dpi < dpi <= max_dpi:
                        app_icon = file_name
                        current_dpi = dpi
            except Exception as e:
                androconf.warning("Exception selecting app icon: %s" % e)

        return app_icon
Example #4
0
 def saveSession(self, filepath):
     """Save androguard session."""
     try:
         session_module.Save(self.session, filepath)
     except RuntimeError as e:
         androconf.error(str(e))
         os.remove(filepath)
         androconf.warning("Session not saved")
Example #5
0
 def saveSession(self, filepath):
     '''Save androguard session.'''
     try:
         session_module.Save(self.session, filepath)
     except RuntimeError as e:
         androconf.error(str(e))
         os.remove(filepath)
         androconf.warning("Session not saved")
Example #6
0
 def load_androguard_session(self):
     if not self.apk_path.endswith(".apk") and not self.apk_path.endswith(".ag"):
         androconf.warning("Not loading session. APK not supported")
         return False
     if os.path.isfile(self.session_path):
         androconf.debug("Loading previous session")
         self.a, self.d, self.x = load_session(self.session_path)
         return True
     return False
Example #7
0
    def _validatePosition(self, x, y):
        if x >= self._cols:
            androconf.warning("x > cols")
            return False

        if y >= self._rows:
            androconf.warning("y > rows")
            return False
        return True
Example #8
0
    def _validatePosition(self, x, y):
        if x >= self._cols:
            androconf.warning("x > cols")
            return False

        if y >= self._rows:
            androconf.warning("y > rows")
            return False
        return True
Example #9
0
 def saveSession(self, path):
     '''Save androguard session.'''
     try:
         self.session.save(path)
     except RuntimeError as e:
         androconf.error(str(e))
         # http://stackoverflow.com/questions/2134706/hitting-maximum-recursion-depth-using-pythons-pickle-cpickle
         androconf.error("Try increasing sys.recursionlimit")
         os.remove(path)
         androconf.warning("Session not saved")
Example #10
0
 def saveSession(self, path):
     '''Save androguard session.'''
     try:
         self.session.save(path)
     except RuntimeError as e:
         androconf.error(str(e))
         # http://stackoverflow.com/questions/2134706/hitting-maximum-recursion-depth-using-pythons-pickle-cpickle
         androconf.error("Try increasing sys.recursionlimit")
         os.remove(path)
         androconf.warning("Session not saved")
Example #11
0
 def load_androguard_session(self):
     if not self.apk_path.endswith(".apk") and not self.apk_path.endswith(
             ".ag"):
         androconf.warning("Not loading session. APK not supported")
         return False
     if os.path.isfile(self.session_path):
         androconf.debug("Loading previous session")
         self.a, self.d, self.x = load_session(self.session_path)
         return True
     return False
Example #12
0
    def get_app_icon(self, max_dpi=65536):
        """
            Return the first non-greater density than max_dpi icon file name,
            unless exact icon resolution is set in the manifest, in which case
            return the exact file

            :rtype: string
        """
        main_activity_name = self.get_main_activity()

        app_icon = self.get_element('activity',
                                    'icon',
                                    name=main_activity_name)

        if not app_icon:
            app_icon = self.get_element('application', 'icon')

        if not app_icon:
            res_id = self.get_android_resources().get_res_id_by_key(
                self.package, 'mipmap', 'ic_launcher')
            if res_id:
                app_icon = "@%x" % res_id

        if not app_icon:
            res_id = self.get_android_resources().get_res_id_by_key(
                self.package, 'drawable', 'ic_launcher')
            if res_id:
                app_icon = "@%x" % res_id

        if not app_icon:
            # If the icon can not be found, return now
            return None

        if app_icon.startswith("@"):
            res_id = int(app_icon[1:], 16)
            res_parser = self.get_android_resources()
            candidates = res_parser.get_resolved_res_configs(res_id)

            app_icon = None
            current_dpi = -1

            try:
                for config, file_name in candidates:
                    dpi = config.get_density()
                    if current_dpi < dpi <= max_dpi:
                        app_icon = file_name
                        current_dpi = dpi
            except Exception as e:
                androconf.warning("Exception selecting app icon: %s" % e)

        return app_icon
Example #13
0
    def __init__(self, parent=None, win=None, xrefs_list=None, method=""):
        super(XrefDialog, self).__init__(parent)

        if not isinstance(xrefs_list, list) or len(xrefs_list) == 0:
            androconf.warning("Bad XrefDialog creation")
            return

        if not method:
            title = "Xrefs to %s" % path.split("/")[-1]
        else:
            title = "Xrefs to %s -> %s" % (path.split("/")[-1], method)

        self.setWindowTitle(title)
        layout = QtGui.QGridLayout()
        xrefwin = XrefListView(self, win=win, xrefs=xrefs_list)
        layout.addWidget(xrefwin, 0, 0)
        self.setLayout(layout)
    def __init__(self, parent=None, win=None, xrefs_list=None, method=""):
        super(XrefDialog, self).__init__(parent)

        if not isinstance(xrefs_list, list) or len(xrefs_list) == 0:
            androconf.warning("Bad XrefDialog creation")
            return

        if not method:
            title = "Xrefs to %s" % path.split("/")[-1]
        else:
            title = "Xrefs to %s -> %s" % (path.split("/")[-1], method)

        self.setWindowTitle(title)
        layout = QtWidgets.QGridLayout()
        xrefwin = XrefListView(self, win=win, xrefs=xrefs_list)
        layout.addWidget(xrefwin, 0, 0)
        self.setLayout(layout)
Example #15
0
    def drawCursor(self, qp):
        cursorX, cursorY = self.cursor.getPosition()

        xstart = cursorX

        try:
            asm = self.OPCODES[cursorY]
            width = asm.getSelectionWidth(xstart)
        except IndexError as e:
            androconf.warning(e)
            width = 2

        qp.setBrush(QtGui.QColor(255, 255, 0))

        qp.setOpacity(0.5)
        qp.drawRect(xstart * self.fontWidth, cursorY * self.fontHeight,
                    width * self.fontWidth, self.fontHeight + 2)
        qp.setOpacity(1)
    def drawCursor(self, qp):
        cursorX, cursorY = self.cursor.getPosition()

        xstart = cursorX

        try:
            asm = self.OPCODES[cursorY]
            width = asm.getSelectionWidth(xstart)
        except IndexError as e:
            androconf.warning(e)
            width = 2


        qp.setBrush(QtGui.QColor(255, 255, 0))

        qp.setOpacity(0.5)
        qp.drawRect(xstart*self.fontWidth, cursorY*self.fontHeight, width*self.fontWidth, self.fontHeight + 2)
        qp.setOpacity(1)
Example #17
0
    def drawCursor(self, qp):
        cursorX, cursorY = self.cursor.getPosition()

        print(cursorX, cursorY)

        xstart = cursorX

        if cursorY not in self.OPCODES:
            androconf.warning("Impossible to find instruction at cursor %d, %d" % (cursorY, len(self.OPCODES)))
            return

        asm = self.OPCODES[cursorY]
        width = asm.getSelectionWidth(xstart)

        qp.setBrush(QtGui.QColor(255, 255, 0))

        qp.setOpacity(0.5)
        qp.drawRect(xstart * self.fontWidth,
                    cursorY * self.fontHeight,
                    width * self.fontWidth,
                    self.fontHeight + 2)
        qp.setOpacity(1)
Example #18
0
    def drawCursor(self, qp):
        cursorX, cursorY = self.cursor.getPosition()

        print cursorX, cursorY

        xstart = cursorX

        if cursorY not in self.OPCODES:
            androconf.warning(
                "Impossible to find instruction at cursor %d, %d" %
                (cursorY, len(self.OPCODES)))
            return

        asm = self.OPCODES[cursorY]
        width = asm.getSelectionWidth(xstart)

        qp.setBrush(QtGui.QColor(255, 255, 0))

        qp.setOpacity(0.5)
        qp.drawRect(xstart * self.fontWidth, cursorY * self.fontHeight,
                    width * self.fontWidth, self.fontHeight + 2)
        qp.setOpacity(1)
Example #19
0
    def visit_fill_array(self, array, value):
        self.write_ind()
        array.visit(self)
        self.write(' = {', data="ARRAY_FILLED")
        data = value.get_data()
        tab = []
        elem_size = value.element_width

        # Set type depending on size of elements
        data_types = {1: 'b', 2: 'h', 4: 'i', 8: 'd'}

        if elem_size in data_types:
            elem_id = data_types[elem_size]
        else:
            # FIXME for other types we just assume bytes...
            warning("Unknown element size {} for array. Assume bytes.".format(elem_size))
            elem_id = 'b'
            elem_size = 1

        for i in range(0, value.size*elem_size, elem_size):
            tab.append('%s' % unpack(elem_id, data[i:i+elem_size])[0])
        self.write(', '.join(tab), data="COMMA")
        self.write('}', data="ARRAY_FILLED_END")
        self.end_ins()
Example #20
0
    def _create_xref(self, instances_class_name, last_vm, queue_classes):
        while not queue_classes.empty():
            current_class = queue_classes.get()
            debug("Creating XREF/DREF for %s" % current_class.get_name())
            for current_method in current_class.get_methods():
                debug("Creating XREF for %s" % current_method)

                code = current_method.get_code()
                if code is None:
                    continue

                off = 0
                bc = code.get_bc()
                try:
                    for instruction in bc.get_instructions():
                        op_value = instruction.get_op_value()
                        if op_value in [0x1c, 0x22]:
                            idx_type = instruction.get_ref_kind()
                            type_info = last_vm.get_cm_type(idx_type)

                            # Internal xref related to class manipulation
                            if type_info in instances_class_name and type_info != current_class.get_name(
                            ):
                                # new instance
                                if op_value == 0x22:
                                    self.classes[current_class.get_name(
                                    )].AddXrefTo(REF_NEW_INSTANCE,
                                                 self.classes[type_info],
                                                 current_method, off)
                                    self.classes[type_info].AddXrefFrom(
                                        REF_NEW_INSTANCE,
                                        self.classes[current_class.get_name()],
                                        current_method, off)
                                # class reference
                                else:
                                    self.classes[current_class.get_name(
                                    )].AddXrefTo(REF_CLASS_USAGE,
                                                 self.classes[type_info],
                                                 current_method, off)
                                    self.classes[type_info].AddXrefFrom(
                                        REF_CLASS_USAGE,
                                        self.classes[current_class.get_name()],
                                        current_method, off)

                        elif ((0x6e <= op_value <= 0x72) or
                                  (0x74 <= op_value <= 0x78)):
                            idx_meth = instruction.get_ref_kind()
                            method_info = last_vm.get_cm_method(idx_meth)
                            if method_info:
                                class_info = method_info[0]

                                method_item = last_vm.get_method_descriptor(
                                    method_info[0], method_info[1],
                                    ''.join(method_info[2]))

                                # Seems to be an external classes
                                if not method_item:
                                    if method_info[0] not in self.classes:
                                        self.classes[method_info[0]] = ClassAnalysis(ExternalClass(method_info[0]),
                                                                                     False)
                                    method_item = self.classes[method_info[0]].GetFakeMethod(method_info[1],
                                                                                             method_info[2])

                                if method_item:
                                    self.classes[current_class.get_name(
                                    )].AddMXrefTo(current_method,
                                                  self.classes[class_info],
                                                  method_item,
                                                  off)
                                    self.classes[class_info].AddMXrefFrom(
                                        method_item,
                                        self.classes[current_class.get_name()],
                                        current_method,
                                        off)

                                    # Internal xref related to class manipulation
                                    if class_info in instances_class_name and class_info != current_class.get_name(
                                    ):
                                        self.classes[current_class.get_name(
                                        )].AddXrefTo(REF_CLASS_USAGE,
                                                     self.classes[class_info],
                                                     method_item, off)
                                        self.classes[class_info].AddXrefFrom(
                                            REF_CLASS_USAGE,
                                            self.classes[current_class.get_name()],
                                            current_method, off)

                        elif 0x1a <= op_value <= 0x1b:
                            string_value = last_vm.get_cm_string(
                                instruction.get_ref_kind())
                            if string_value not in self.strings:
                                self.strings[string_value] = StringAnalysis(
                                    string_value)
                            self.strings[string_value].AddXrefFrom(
                                self.classes[current_class.get_name()],
                                current_method)

                        elif 0x52 <= op_value <= 0x6d:
                            idx_field = instruction.get_ref_kind()
                            field_info = last_vm.get_cm_field(idx_field)
                            field_item = last_vm.get_field_descriptor(
                                field_info[0], field_info[2], field_info[1])
                            if field_item:
                                # read access to a field
                                if (0x52 <= op_value <= 0x58) or (
                                                0x60 <= op_value <= 0x66):
                                    self.classes[current_class.get_name(
                                    )].AddFXrefRead(
                                        current_method,
                                        self.classes[current_class.get_name()],
                                        field_item)
                                # write access to a field
                                else:
                                    self.classes[current_class.get_name(
                                    )].AddFXrefWrite(
                                        current_method,
                                        self.classes[current_class.get_name()],
                                        field_item)

                        off += instruction.get_length()
                except dvm.InvalidInstruction as e:
                    warning("Invalid instruction %s" % str(e))
            queue_classes.task_done()
Example #21
0
    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:
                    androconf.warning("AXML parsing failed, file is empty")
                else:
                    try:
                        if self.axml[i].is_packed():
                            androconf.warning(
                                "XML Seems to be packed, parsing is very likely to fail."
                            )
                        parser = etree.XMLParser(recover=True)
                        tree = etree.fromstring(raw_xml, parser=parser)
                        self.xml[i] = parse_lxml_dom(tree)
                    except Exception as e:
                        androconf.warning("reading AXML as XML failed: " +
                                          str(e))

                if self.xml[i] is not None:
                    self.package = self.xml[i].documentElement.getAttribute(
                        "package")
                    self.androidversion["Code"] = self.xml[
                        i].documentElement.getAttributeNS(
                            NS_ANDROID_URI, "versionCode")
                    self.androidversion["Name"] = self.xml[
                        i].documentElement.getAttributeNS(
                            NS_ANDROID_URI, "versionName")

                    for item in self.xml[i].getElementsByTagName(
                            'uses-permission'):
                        self.permissions.append(
                            str(item.getAttributeNS(NS_ANDROID_URI, "name")))

                    # getting details of the declared permissions
                    for d_perm_item in self.xml[i].getElementsByTagName(
                            'permission'):
                        d_perm_name = self._get_res_string_value(
                            str(
                                d_perm_item.getAttributeNS(
                                    NS_ANDROID_URI, "name")))
                        d_perm_label = self._get_res_string_value(
                            str(
                                d_perm_item.getAttributeNS(
                                    NS_ANDROID_URI, "label")))
                        d_perm_description = self._get_res_string_value(
                            str(
                                d_perm_item.getAttributeNS(
                                    NS_ANDROID_URI, "description")))
                        d_perm_permissionGroup = self._get_res_string_value(
                            str(
                                d_perm_item.getAttributeNS(
                                    NS_ANDROID_URI, "permissionGroup")))
                        d_perm_protectionLevel = self._get_res_string_value(
                            str(
                                d_perm_item.getAttributeNS(
                                    NS_ANDROID_URI, "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())
Example #22
0
def Warning(msg):
    warning(msg)
Example #23
0
def Exit(msg):
    warning("Error : " + msg)
    raise("oops")
Example #24
0
File: analysis.py Project: wcx/DFFA
    def create_xref(self):
        debug("Creating XREF/DREF")

        instances_class_name = self.classes.keys()

        last_vm = self.vms[-1]
        for current_class in last_vm.get_classes():
            for current_method in current_class.get_methods():
                debug("Creating XREF for %s" % current_method)

                code = current_method.get_code()
                if code == None:
                    continue

                off = 0
                bc = code.get_bc()
                try:
                    for instruction in bc.get_instructions():
                        op_value = instruction.get_op_value()
                        if op_value in [0x1c, 0x22]:
                            idx_type = instruction.get_ref_kind()
                            type_info = last_vm.get_cm_type(idx_type)

                            # Internal xref related to class manipulation
                            if type_info in instances_class_name and type_info != current_class.get_name(
                            ):
                                # new instance
                                if op_value == 0x22:
                                    self.classes[current_class.get_name(
                                    )].AddXrefTo(REF_NEW_INSTANCE,
                                                 self.classes[type_info],
                                                 current_method, off)
                                    self.classes[type_info].AddXrefFrom(
                                        REF_NEW_INSTANCE,
                                        self.classes[current_class.get_name()],
                                        current_method, off)
                                # class reference
                                else:
                                    self.classes[current_class.get_name(
                                    )].AddXrefTo(REF_CLASS_USAGE,
                                                 self.classes[type_info],
                                                 current_method, off)
                                    self.classes[type_info].AddXrefFrom(
                                        REF_CLASS_USAGE,
                                        self.classes[current_class.get_name()],
                                        current_method, off)

                        elif ((op_value >= 0x6e and op_value <= 0x72) or
                              (op_value >= 0x74 and op_value <= 0x78)):
                            idx_meth = instruction.get_ref_kind()
                            method_info = last_vm.get_cm_method(idx_meth)
                            if method_info:
                                class_info = method_info[0]

                                method_item = last_vm.get_method_descriptor(
                                    method_info[0], method_info[1],
                                    ''.join(method_info[2]))
                                if method_item:
                                    self.classes[current_class.get_name(
                                    )].AddMXrefTo(current_method,
                                                  self.classes[class_info],
                                                  method_item,
                                                  off)
                                    self.classes[class_info].AddMXrefFrom(
                                        method_item,
                                        self.classes[current_class.get_name()],
                                        current_method,
                                        off)

                                    # Internal xref related to class manipulation
                                    if class_info in instances_class_name and class_info != current_class.get_name(
                                    ):
                                        self.classes[current_class.get_name(
                                        )].AddXrefTo(REF_CLASS_USAGE,
                                                     self.classes[class_info],
                                                     method_item, off)
                                        self.classes[class_info].AddXrefFrom(
                                            REF_CLASS_USAGE,
                                            self.classes[current_class.get_name()],
                                            current_method, off)

                        elif op_value >= 0x1a and op_value <= 0x1b:
                            string_value = last_vm.get_cm_string(
                                instruction.get_ref_kind())
                            if string_value not in self.strings:
                                self.strings[string_value] = StringAnalysis(
                                    string_value)
                            self.strings[string_value].AddXrefFrom(
                                self.classes[current_class.get_name()],
                                current_method)

                        elif op_value >= 0x52 and op_value <= 0x6d:
                            idx_field = instruction.get_ref_kind()
                            field_info = last_vm.get_cm_field(idx_field)
                            field_item = last_vm.get_field_descriptor(
                                field_info[0], field_info[2], field_info[1])
                            if field_item:
                                # read access to a field
                                if (op_value >= 0x52 and op_value <= 0x58) or (
                                        op_value >= 0x60 and op_value <= 0x66):
                                    self.classes[current_class.get_name(
                                    )].AddFXrefRead(
                                        current_method,
                                        self.classes[current_class.get_name()],
                                        field_item)
                                # write access to a field
                                else:
                                    self.classes[current_class.get_name(
                                    )].AddFXrefWrite(
                                        current_method,
                                        self.classes[current_class.get_name()],
                                        field_item)

                        off += instruction.get_length()
                except dvm.InvalidInstruction as e:
                    warning("Invalid instruction %s" % str(e))
Example #25
0
def Exit(msg):
    warning("Error : " + msg)
    raise ("oops")
Example #26
0
def Warning(msg):
    warning(msg)
Example #27
0
    def _create_xref(self, last_vm, queue_classes):
        while not queue_classes.empty():
            current_class = queue_classes.get()
            debug("Creating XREF/DREF for %s" % current_class.get_name())
            for current_method in current_class.get_methods():
                debug("Creating XREF for %s" % current_method)

                code = current_method.get_code()
                if code is None:
                    continue

                off = 0
                bc = code.get_bc()
                try:
                    for instruction in bc.get_instructions():
                        op_value = instruction.get_op_value()
                        if op_value in [0x1c, 0x22]:
                            idx_type = instruction.get_ref_kind()
                            type_info = last_vm.get_cm_type(idx_type)

                            # Internal xref related to class manipulation
                            if type_info in self.classes and type_info != current_class.get_name(
                            ):
                                # new instance
                                if op_value == 0x22:
                                    self.classes[
                                        current_class.get_name()].AddXrefTo(
                                            REF_NEW_INSTANCE,
                                            self.classes[type_info],
                                            current_method, off)
                                    self.classes[type_info].AddXrefFrom(
                                        REF_NEW_INSTANCE,
                                        self.classes[current_class.get_name()],
                                        current_method, off)
                                # class reference
                                else:
                                    self.classes[
                                        current_class.get_name()].AddXrefTo(
                                            REF_CLASS_USAGE,
                                            self.classes[type_info],
                                            current_method, off)
                                    self.classes[type_info].AddXrefFrom(
                                        REF_CLASS_USAGE,
                                        self.classes[current_class.get_name()],
                                        current_method, off)

                        elif ((0x6e <= op_value <= 0x72)
                              or (0x74 <= op_value <= 0x78)):
                            idx_meth = instruction.get_ref_kind()
                            method_info = last_vm.get_cm_method(idx_meth)
                            if method_info:
                                class_info = method_info[0]

                                method_item = last_vm.get_method_descriptor(
                                    method_info[0], method_info[1],
                                    ''.join(method_info[2]))

                                # Seems to be an external classes
                                if not method_item:
                                    if method_info[0] not in self.classes:
                                        self.classes[
                                            method_info[0]] = ClassAnalysis(
                                                ExternalClass(method_info[0]),
                                                False)
                                    method_item = self.classes[
                                        method_info[0]].GetFakeMethod(
                                            method_info[1], method_info[2])

                                if method_item:
                                    self.classes[
                                        current_class.get_name()].AddMXrefTo(
                                            current_method,
                                            self.classes[class_info],
                                            method_item, off)
                                    self.classes[class_info].AddMXrefFrom(
                                        method_item,
                                        self.classes[current_class.get_name()],
                                        current_method, off)

                                    # Internal xref related to class manipulation
                                    if class_info in self.classes and class_info != current_class.get_name(
                                    ):
                                        self.classes[current_class.get_name(
                                        )].AddXrefTo(REF_CLASS_USAGE,
                                                     self.classes[class_info],
                                                     method_item, off)
                                        self.classes[class_info].AddXrefFrom(
                                            REF_CLASS_USAGE, self.classes[
                                                current_class.get_name()],
                                            current_method, off)

                        elif 0x1a <= op_value <= 0x1b:
                            string_value = last_vm.get_cm_string(
                                instruction.get_ref_kind())
                            if string_value not in self.strings:
                                self.strings[string_value] = StringAnalysis(
                                    string_value)
                            self.strings[string_value].AddXrefFrom(
                                self.classes[current_class.get_name()],
                                current_method)

                        elif 0x52 <= op_value <= 0x6d:
                            idx_field = instruction.get_ref_kind()
                            field_info = last_vm.get_cm_field(idx_field)
                            field_item = last_vm.get_field_descriptor(
                                field_info[0], field_info[2], field_info[1])
                            if field_item:
                                # read access to a field
                                if (0x52 <= op_value <=
                                        0x58) or (0x60 <= op_value <= 0x66):
                                    self.classes[current_class.get_name(
                                    )].AddFXrefRead(
                                        current_method,
                                        self.classes[current_class.get_name()],
                                        field_item)
                                # write access to a field
                                else:
                                    self.classes[current_class.get_name(
                                    )].AddFXrefWrite(
                                        current_method,
                                        self.classes[current_class.get_name()],
                                        field_item)

                        off += instruction.get_length()
                except dvm.InvalidInstruction as e:
                    warning("Invalid instruction %s" % str(e))
            queue_classes.task_done()
Example #28
0
    def create_xref(self):
        debug("Creating XREF/DREF")

        instances_class_name = self.classes.keys()
        external_instances = {}

        last_vm = self.vms[-1]
        for current_class in last_vm.get_classes():
            for current_method in current_class.get_methods():
                debug("Creating XREF for %s" % current_method)

                code = current_method.get_code()
                if code == None:
                    continue

                off = 0
                bc = code.get_bc()
                try:
                    for instruction in bc.get_instructions():
                        op_value = instruction.get_op_value()
                        if op_value in [0x1c, 0x22]:
                            idx_type = instruction.get_ref_kind()
                            type_info = last_vm.get_cm_type(idx_type)

                            # Internal xref related to class manipulation
                            if type_info in instances_class_name and type_info != current_class.get_name(
                            ):
                                # new instance
                                if op_value == 0x22:
                                    self.classes[current_class.get_name(
                                    )].AddXrefTo(REF_NEW_INSTANCE,
                                                 self.classes[type_info],
                                                 current_method, off)
                                    self.classes[type_info].AddXrefFrom(
                                        REF_NEW_INSTANCE,
                                        self.classes[current_class.get_name()],
                                        current_method, off)
                                # class reference
                                else:
                                    self.classes[current_class.get_name(
                                    )].AddXrefTo(REF_CLASS_USAGE,
                                                 self.classes[type_info],
                                                 current_method, off)
                                    self.classes[type_info].AddXrefFrom(
                                        REF_CLASS_USAGE,
                                        self.classes[current_class.get_name()],
                                        current_method, off)

                        elif ((op_value >= 0x6e and op_value <= 0x72) or
                              (op_value >= 0x74 and op_value <= 0x78)):
                            idx_meth = instruction.get_ref_kind()
                            method_info = last_vm.get_cm_method(idx_meth)
                            if method_info:
                                class_info = method_info[0]

                                method_item = last_vm.get_method_descriptor(
                                    method_info[0], method_info[1],
                                    ''.join(method_info[2]))
                                if method_item:
                                    self.classes[current_class.get_name(
                                    )].AddMXrefTo(current_method,
                                                  self.classes[class_info],
                                                  method_item)
                                    self.classes[class_info].AddMXrefFrom(
                                        method_item,
                                        self.classes[current_class.get_name()],
                                        current_method)

                                    # Internal xref related to class manipulation
                                    if class_info in instances_class_name and class_info != current_class.get_name(
                                    ):
                                        self.classes[current_class.get_name(
                                        )].AddXrefTo(REF_CLASS_USAGE,
                                                     self.classes[class_info],
                                                     method_item, off)
                                        self.classes[class_info].AddXrefFrom(
                                            REF_CLASS_USAGE,
                                            self.classes[current_class.get_name()],
                                            current_method, off)

                        elif op_value >= 0x1a and op_value <= 0x1b:
                            string_value = last_vm.get_cm_string(
                                instruction.get_ref_kind())
                            if string_value not in self.strings:
                                self.strings[string_value] = StringAnalysis(
                                    string_value)
                            self.strings[string_value].AddXrefFrom(
                                self.classes[current_class.get_name()],
                                current_method)

                        elif op_value >= 0x52 and op_value <= 0x6d:
                            idx_field = instruction.get_ref_kind()
                            field_info = last_vm.get_cm_field(idx_field)
                            field_item = last_vm.get_field_descriptor(
                                field_info[0], field_info[2], field_info[1])
                            if field_item:
                                # read access to a field
                                if (op_value >= 0x52 and op_value <= 0x58) or (
                                        op_value >= 0x60 and op_value <= 0x66):
                                    self.classes[current_class.get_name(
                                    )].AddFXrefRead(
                                        current_method,
                                        self.classes[current_class.get_name()],
                                        field_item)
                                # write access to a field
                                else:
                                    self.classes[current_class.get_name(
                                    )].AddFXrefWrite(
                                        current_method,
                                        self.classes[current_class.get_name()],
                                        field_item)

                        off += instruction.get_length()
                except dvm.InvalidInstruction as e:
                    warning("Invalid instruction %s" % str(e))