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
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()
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
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")
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")
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
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
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")
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
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
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)
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)
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)
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)
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()
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()
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())
def Warning(msg): warning(msg)
def Exit(msg): warning("Error : " + msg) raise("oops")
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))
def Exit(msg): warning("Error : " + msg) raise ("oops")
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()
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))