<s> import re , random , cPickle , collections <EOL> from androguard . core . androconf import error , warning , debug , is_ascii_problem , load_api_specific_resource_module <EOL> from androguard . core . bytecodes import dvm <EOL> from androguard . core . bytecodes . api_permissions import DVM_PERMISSIONS_BY_PERMISSION , DVM_PERMISSIONS_BY_ELEMENT <EOL> class DVMBasicBlock ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , start , vm , method , context ) : <EOL> self . __vm = vm <EOL> self . method = method <EOL> self . context = context <EOL> self . last_length = <NUM_LIT:0> <EOL> self . nb_instructions = <NUM_LIT:0> <EOL> self . fathers = [ ] <EOL> self . childs = [ ] <EOL> self . start = start <EOL> self . end = self . start <EOL> self . special_ins = { } <EOL> self . name = "<STR_LIT>" % ( self . method . get_name ( ) , self . start ) <EOL> self . exception_analysis = None <EOL> self . notes = [ ] <EOL> def get_notes ( self ) : <EOL> return self . notes <EOL> def set_notes ( self , value ) : <EOL> self . notes = [ value ] <EOL> def add_note ( self , note ) : <EOL> self . notes . append ( note ) <EOL> def clear_notes ( self ) : <EOL> self . notes = [ ] <EOL> def get_instructions ( self ) : <EOL> """<STR_LIT>""" <EOL> tmp_ins = [ ] <EOL> idx = <NUM_LIT:0> <EOL> for i in self . method . get_instructions ( ) : <EOL> if idx >= self . start and idx < self . end : <EOL> tmp_ins . append ( i ) <EOL> idx += i . get_length ( ) <EOL> return tmp_ins <EOL> def get_nb_instructions ( self ) : <EOL> return self . nb_instructions <EOL> def get_method ( self ) : <EOL> return self . method <EOL> def get_name ( self ) : <EOL> return "<STR_LIT>" % ( self . method . get_name ( ) , self . start ) <EOL> def get_start ( self ) : <EOL> return self . start <EOL> def get_end ( self ) : <EOL> return self . end <EOL> def get_last ( self ) : <EOL> return self . get_instructions ( ) [ - <NUM_LIT:1> ] <EOL> def get_next ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . childs <EOL> def get_prev ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . fathers <EOL> def set_fathers ( self , f ) : <EOL> self . fathers . append ( f ) <EOL> def get_last_length ( self ) : <EOL> return self . last_length <EOL> def set_childs ( self , values ) : <EOL> if values == [ ] : <EOL> next_block = self . context . get_basic_block ( self . end + <NUM_LIT:1> ) <EOL> if next_block != None : <EOL> self . childs . append ( ( self . end - self . get_last_length ( ) , self . end , <EOL> next_block ) ) <EOL> else : <EOL> for i in values : <EOL> if i != - <NUM_LIT:1> : <EOL> next_block = self . context . get_basic_block ( i ) <EOL> if next_block != None : <EOL> self . childs . append ( ( self . end - self . get_last_length ( ) , <EOL> i , next_block ) ) <EOL> for c in self . childs : <EOL> if c [ <NUM_LIT:2> ] != None : <EOL> c [ <NUM_LIT:2> ] . set_fathers ( ( c [ <NUM_LIT:1> ] , c [ <NUM_LIT:0> ] , self ) ) <EOL> def push ( self , i ) : <EOL> self . nb_instructions += <NUM_LIT:1> <EOL> idx = self . end <EOL> self . last_length = i . get_length ( ) <EOL> self . end += self . last_length <EOL> op_value = i . get_op_value ( ) <EOL> if op_value == <NUM_LIT> or ( op_value >= <NUM_LIT> and op_value <= <NUM_LIT> ) : <EOL> code = self . method . get_code ( ) . get_bc ( ) <EOL> self . special_ins [ idx ] = code . get_ins_off ( idx + i . get_ref_off ( ) * <NUM_LIT:2> ) <EOL> def get_special_ins ( self , idx ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return self . special_ins [ idx ] <EOL> except : <EOL> return None <EOL> def get_exception_analysis ( self ) : <EOL> return self . exception_analysis <EOL> def set_exception_analysis ( self , exception_analysis ) : <EOL> self . exception_analysis = exception_analysis <EOL> class Enum ( object ) : <EOL> def __init__ ( self , names ) : <EOL> self . names = names <EOL> for value , name in enumerate ( self . names ) : <EOL> setattr ( self , name . upper ( ) , value ) <EOL> def tuples ( self ) : <EOL> return tuple ( enumerate ( self . names ) ) <EOL> TAG_ANDROID = Enum ( <EOL> [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> TAG_REVERSE_ANDROID = dict ( ( i [ <NUM_LIT:0> ] , i [ <NUM_LIT:1> ] ) for i in TAG_ANDROID . tuples ( ) ) <EOL> TAGS_ANDROID = { <EOL> TAG_ANDROID . ANDROID : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . TELEPHONY : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . SMS : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . SMSMESSAGE : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . DEBUG : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . ACCESSIBILITYSERVICE : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . ACCOUNTS : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . ANIMATION : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . APP : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . BLUETOOTH : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . CONTENT : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . DATABASE : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . DRM : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . GESTURE : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . GRAPHICS : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . HARDWARE : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . INPUTMETHODSERVICE : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . LOCATION : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . MEDIA : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . MTP : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . NET : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . NFC : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . OPENGL : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . OS : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . PREFERENCE : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . PROVIDER : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . RENDERSCRIPT : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . SAX : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . SECURITY : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . SERVICE : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . SPEECH : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . SUPPORT : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . TEST : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . TEXT : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . UTIL : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . VIEW : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . WEBKIT : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . WIDGET : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . DALVIK_BYTECODE : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . DALVIK_SYSTEM : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> TAG_ANDROID . JAVA_REFLECTION : [ <NUM_LIT:0> , "<STR_LIT>" ] , <EOL> } <EOL> class Tags ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , patterns = TAGS_ANDROID , reverse = TAG_REVERSE_ANDROID ) : <EOL> self . tags = set ( ) <EOL> self . patterns = patterns <EOL> self . reverse = TAG_REVERSE_ANDROID <EOL> for i in self . patterns : <EOL> self . patterns [ i ] [ <NUM_LIT:1> ] = re . compile ( self . patterns [ i ] [ <NUM_LIT:1> ] ) <EOL> def emit ( self , method ) : <EOL> for i in self . patterns : <EOL> if self . patterns [ i ] [ <NUM_LIT:0> ] == <NUM_LIT:0> : <EOL> if self . patterns [ i ] [ <NUM_LIT:1> ] . search ( method . get_class ( ) ) != None : <EOL> self . tags . add ( i ) <EOL> def emit_by_classname ( self , classname ) : <EOL> for i in self . patterns : <EOL> if self . patterns [ i ] [ <NUM_LIT:0> ] == <NUM_LIT:0> : <EOL> if self . patterns [ i ] [ <NUM_LIT:1> ] . search ( classname ) != None : <EOL> self . tags . add ( i ) <EOL> def get_list ( self ) : <EOL> return [ self . reverse [ i ] for i in self . tags ] <EOL> def __contains__ ( self , key ) : <EOL> return key in self . tags <EOL> def __str__ ( self ) : <EOL> return str ( [ self . reverse [ i ] for i in self . tags ] ) <EOL> def empty ( self ) : <EOL> return self . tags == set ( ) <EOL> class BasicBlocks ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , _vm ) : <EOL> self . __vm = _vm <EOL> self . bb = [ ] <EOL> def push ( self , bb ) : <EOL> self . bb . append ( bb ) <EOL> def pop ( self , idx ) : <EOL> return self . bb . pop ( idx ) <EOL> def get_basic_block ( self , idx ) : <EOL> for i in self . bb : <EOL> if idx >= i . get_start ( ) and idx < i . get_end ( ) : <EOL> return i <EOL> return None <EOL> def get ( self ) : <EOL> """<STR_LIT>""" <EOL> for i in self . bb : <EOL> yield i <EOL> def gets ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . bb <EOL> def get_basic_block_pos ( self , idx ) : <EOL> return self . bb [ idx ] <EOL> class ExceptionAnalysis ( object ) : <EOL> def __init__ ( self , exception , bb ) : <EOL> self . start = exception [ <NUM_LIT:0> ] <EOL> self . end = exception [ <NUM_LIT:1> ] <EOL> self . exceptions = exception [ <NUM_LIT:2> : ] <EOL> for i in self . exceptions : <EOL> i . append ( bb . get_basic_block ( i [ <NUM_LIT:1> ] ) ) <EOL> def show_buff ( self ) : <EOL> buff = "<STR_LIT>" % ( self . start , self . end ) <EOL> for i in self . exceptions : <EOL> if i [ <NUM_LIT:2> ] == None : <EOL> buff += "<STR_LIT>" % ( i [ <NUM_LIT:0> ] , i [ <NUM_LIT:1> ] , i [ <NUM_LIT:2> ] ) <EOL> else : <EOL> buff += "<STR_LIT>" % ( i [ <NUM_LIT:0> ] , i [ <NUM_LIT:1> ] , i [ <NUM_LIT:2> ] . get_name ( ) ) <EOL> return buff [ : - <NUM_LIT:1> ] <EOL> def get ( self ) : <EOL> d = { "<STR_LIT:start>" : self . start , "<STR_LIT:end>" : self . end , "<STR_LIT:list>" : [ ] } <EOL> for i in self . exceptions : <EOL> d [ "<STR_LIT:list>" ] . append ( { "<STR_LIT:name>" : i [ <NUM_LIT:0> ] , "<STR_LIT>" : i [ <NUM_LIT:1> ] , "<STR_LIT>" : i [ <NUM_LIT:2> ] . get_name ( ) } ) <EOL> return d <EOL> class Exceptions ( object ) : <EOL> def __init__ ( self , _vm ) : <EOL> self . __vm = _vm <EOL> self . exceptions = [ ] <EOL> def add ( self , exceptions , basic_blocks ) : <EOL> for i in exceptions : <EOL> self . exceptions . append ( ExceptionAnalysis ( i , basic_blocks ) ) <EOL> def get_exception ( self , addr_start , addr_end ) : <EOL> for i in self . exceptions : <EOL> if i . start >= addr_start and i . end <= addr_end : <EOL> return i <EOL> elif addr_end <= i . end and addr_start >= i . start : <EOL> return i <EOL> return None <EOL> def gets ( self ) : <EOL> return self . exceptions <EOL> def get ( self ) : <EOL> for i in self . exceptions : <EOL> yield i <EOL> BasicOPCODES = [ ] <EOL> for i in dvm . BRANCH_DVM_OPCODES : <EOL> BasicOPCODES . append ( re . compile ( i ) ) <EOL> class MethodAnalysis ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , vm , method ) : <EOL> self . __vm = vm <EOL> self . method = method <EOL> self . basic_blocks = BasicBlocks ( self . __vm ) <EOL> self . exceptions = Exceptions ( self . __vm ) <EOL> code = self . method . get_code ( ) <EOL> if code == None : <EOL> return <EOL> current_basic = DVMBasicBlock ( <NUM_LIT:0> , self . __vm , self . method , self . basic_blocks ) <EOL> self . basic_blocks . push ( current_basic ) <EOL> bc = code . get_bc ( ) <EOL> l = [ ] <EOL> h = { } <EOL> idx = <NUM_LIT:0> <EOL> debug ( "<STR_LIT>" ) <EOL> instructions = [ i for i in bc . get_instructions ( ) ] <EOL> for i in instructions : <EOL> for j in BasicOPCODES : <EOL> if j . match ( i . get_name ( ) ) != None : <EOL> v = dvm . determineNext ( i , idx , self . method ) <EOL> h [ idx ] = v <EOL> l . extend ( v ) <EOL> break <EOL> idx += i . get_length ( ) <EOL> debug ( "<STR_LIT>" ) <EOL> excepts = dvm . determineException ( self . __vm , self . method ) <EOL> for i in excepts : <EOL> l . extend ( [ i [ <NUM_LIT:0> ] ] ) <EOL> for handler in i [ <NUM_LIT:2> : ] : <EOL> l . append ( handler [ <NUM_LIT:1> ] ) <EOL> debug ( "<STR_LIT>" % self . method ) <EOL> idx = <NUM_LIT:0> <EOL> for i in instructions : <EOL> if idx in l : <EOL> if current_basic . get_nb_instructions ( ) != <NUM_LIT:0> : <EOL> current_basic = DVMBasicBlock ( current_basic . get_end ( ) , <EOL> self . __vm , self . method , <EOL> self . basic_blocks ) <EOL> self . basic_blocks . push ( current_basic ) <EOL> current_basic . push ( i ) <EOL> if idx in h : <EOL> current_basic = DVMBasicBlock ( current_basic . get_end ( ) , <EOL> self . __vm , self . method , <EOL> self . basic_blocks ) <EOL> self . basic_blocks . push ( current_basic ) <EOL> idx += i . get_length ( ) <EOL> if current_basic . get_nb_instructions ( ) == <NUM_LIT:0> : <EOL> self . basic_blocks . pop ( - <NUM_LIT:1> ) <EOL> debug ( "<STR_LIT>" ) <EOL> for i in self . basic_blocks . get ( ) : <EOL> try : <EOL> i . set_childs ( h [ i . end - i . get_last_length ( ) ] ) <EOL> except KeyError : <EOL> i . set_childs ( [ ] ) <EOL> debug ( "<STR_LIT>" ) <EOL> self . exceptions . add ( excepts , self . basic_blocks ) <EOL> for i in self . basic_blocks . get ( ) : <EOL> i . set_exception_analysis ( self . exceptions . get_exception ( i . start , <EOL> i . end - <NUM_LIT:1> ) ) <EOL> del instructions <EOL> del h , l <EOL> def get_basic_blocks ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . basic_blocks <EOL> def get_length ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . get_code ( ) . get_length ( ) <EOL> def get_vm ( self ) : <EOL> return self . __vm <EOL> def get_method ( self ) : <EOL> return self . method <EOL> def show ( self ) : <EOL> print "<STR_LIT>" , self . method . get_class_name ( ) , self . method . get_name ( <EOL> ) , self . method . get_descriptor ( ) <EOL> for i in self . basic_blocks . get ( ) : <EOL> print "<STR_LIT:\t>" , i <EOL> i . show ( ) <EOL> print "<STR_LIT>" <EOL> def show_methods ( self ) : <EOL> print "<STR_LIT>" <EOL> for i in self . __bb : <EOL> methods = i . get_methods ( ) <EOL> for method in methods : <EOL> print "<STR_LIT>" , method . get_class_name ( ) , method . get_name ( <EOL> ) , method . get_descriptor ( ) <EOL> for context in methods [ method ] : <EOL> print "<STR_LIT>" , context . details <EOL> def get_tags ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . tags <EOL> class StringAnalysis ( object ) : <EOL> def __init__ ( self , value ) : <EOL> self . value = value <EOL> self . orig_value = value <EOL> self . xreffrom = set ( ) <EOL> def AddXrefFrom ( self , classobj , methodobj ) : <EOL> self . xreffrom . add ( ( classobj , methodobj ) ) <EOL> def get_xref_from ( self ) : <EOL> return self . xreffrom <EOL> def set_value ( self , value ) : <EOL> self . value = value <EOL> def get_value ( self ) : <EOL> return self . value <EOL> def get_orig_value ( self ) : <EOL> return self . orig_value <EOL> def __str__ ( self ) : <EOL> data = "<STR_LIT>" % repr ( self . get_value ( ) ) <EOL> for ref_class , ref_method in self . xreffrom : <EOL> data += "<STR_LIT>" % ( ref_class . get_vm_class ( ) . get_name ( ) , ref_method <EOL> ) <EOL> return data <EOL> class MethodClassAnalysis ( object ) : <EOL> def __init__ ( self , method ) : <EOL> self . method = method <EOL> self . xrefto = set ( ) <EOL> self . xreffrom = set ( ) <EOL> def AddXrefTo ( self , classobj , methodobj , offset ) : <EOL> self . xrefto . add ( ( classobj , methodobj , offset ) ) <EOL> def AddXrefFrom ( self , classobj , methodobj , offset ) : <EOL> self . xreffrom . add ( ( classobj , methodobj , offset ) ) <EOL> def get_xref_from ( self ) : <EOL> return self . xreffrom <EOL> def get_xref_to ( self ) : <EOL> return self . xrefto <EOL> def __str__ ( self ) : <EOL> data = "<STR_LIT>" % self . method <EOL> for ref_class , ref_method , offset in self . xrefto : <EOL> data += "<STR_LIT>" <EOL> data += "<STR_LIT>" % ( ref_class . get_vm_class ( ) . get_name ( ) , ref_method , offset <EOL> ) <EOL> data += "<STR_LIT>" % self . method <EOL> for ref_class , ref_method , offset in self . xreffrom : <EOL> data += "<STR_LIT>" <EOL> data += "<STR_LIT>" % ( ref_class . get_vm_class ( ) . get_name ( ) , ref_method , offset <EOL> ) <EOL> return data <EOL> class FieldClassAnalysis ( object ) : <EOL> def __init__ ( self , field ) : <EOL> self . field = field <EOL> self . xrefread = set ( ) <EOL> self . xrefwrite = set ( ) <EOL> def AddXrefRead ( self , classobj , methodobj ) : <EOL> self . xrefread . add ( ( classobj , methodobj ) ) <EOL> def AddXrefWrite ( self , classobj , methodobj ) : <EOL> self . xrefwrite . add ( ( classobj , methodobj ) ) <EOL> def get_xref_read ( self ) : <EOL> return self . xrefread <EOL> def get_xref_write ( self ) : <EOL> return self . xrefwrite <EOL> def __str__ ( self ) : <EOL> data = "<STR_LIT>" % self . field <EOL> for ref_class , ref_method in self . xrefread : <EOL> data += "<STR_LIT>" <EOL> data += "<STR_LIT>" % ( ref_class . get_vm_class ( ) . get_name ( ) , ref_method <EOL> ) <EOL> data += "<STR_LIT>" % self . field <EOL> for ref_class , ref_method in self . xrefwrite : <EOL> data += "<STR_LIT>" <EOL> data += "<STR_LIT>" % ( ref_class . get_vm_class ( ) . get_name ( ) , ref_method <EOL> ) <EOL> return data <EOL> REF_NEW_INSTANCE = <NUM_LIT:0> <EOL> REF_CLASS_USAGE = <NUM_LIT:1> <EOL> class ClassAnalysis ( object ) : <EOL> def __init__ ( self , classobj ) : <EOL> self . orig_class = classobj <EOL> self . _methods = { } <EOL> self . _fields = { } <EOL> self . xrefto = collections . defaultdict ( set ) <EOL> self . xreffrom = collections . defaultdict ( set ) <EOL> def get_method_analysis ( self , method ) : <EOL> return self . _methods . get ( method ) <EOL> def get_field_analysis ( self , field ) : <EOL> return self . _fields . get ( field ) <EOL> def AddFXrefRead ( self , method , classobj , field ) : <EOL> if field not in self . _fields : <EOL> self . _fields [ field ] = FieldClassAnalysis ( field ) <EOL> self . _fields [ field ] . AddXrefRead ( classobj , method ) <EOL> def AddFXrefWrite ( self , method , classobj , field ) : <EOL> if field not in self . _fields : <EOL> self . _fields [ field ] = FieldClassAnalysis ( field ) <EOL> self . _fields [ field ] . AddXrefWrite ( classobj , method ) <EOL> def AddMXrefTo ( self , method1 , classobj , method2 , offset ) : <EOL> if method1 not in self . _methods : <EOL> self . _methods [ method1 ] = MethodClassAnalysis ( method1 ) <EOL> self . _methods [ method1 ] . AddXrefTo ( classobj , method2 , offset ) <EOL> def AddMXrefFrom ( self , method1 , classobj , method2 , offset ) : <EOL> if method1 not in self . _methods : <EOL> self . _methods [ method1 ] = MethodClassAnalysis ( method1 ) <EOL> self . _methods [ method1 ] . AddXrefFrom ( classobj , method2 , offset ) <EOL> def AddXrefTo ( self , ref_kind , classobj , methodobj , offset ) : <EOL> self . xrefto [ classobj ] . add ( ( ref_kind , methodobj , offset ) ) <EOL> def AddXrefFrom ( self , ref_kind , classobj , methodobj , offset ) : <EOL> self . xreffrom [ classobj ] . add ( ( ref_kind , methodobj , offset ) ) <EOL> def get_xref_from ( self ) : <EOL> return self . xreffrom <EOL> def get_xref_to ( self ) : <EOL> return self . xrefto <EOL> def get_vm_class ( self ) : <EOL> return self . orig_class <EOL> def __str__ ( self ) : <EOL> data = "<STR_LIT>" % self . orig_class <EOL> for ref_class in self . xrefto : <EOL> data += str ( ref_class . get_vm_class ( ) . get_name ( ) ) + "<STR_LIT:U+0020>" <EOL> data += "<STR_LIT>" <EOL> for ref_kind , ref_method , ref_offset in self . xrefto [ ref_class ] : <EOL> data += "<STR_LIT>" % ( ref_kind , ref_method , ref_offset ) <EOL> data += "<STR_LIT:\n>" <EOL> data += "<STR_LIT>" % self . orig_class <EOL> for ref_class in self . xreffrom : <EOL> data += str ( ref_class . get_vm_class ( ) . get_name ( ) ) + "<STR_LIT:U+0020>" <EOL> data += "<STR_LIT>" <EOL> for ref_kind , ref_method , ref_offset in self . xreffrom [ ref_class ] : <EOL> data += "<STR_LIT>" % ( ref_kind , ref_method , ref_offset ) <EOL> data += "<STR_LIT:\n>" <EOL> return data <EOL> class newVMAnalysis ( object ) : <EOL> def __init__ ( self , vm ) : <EOL> self . vms = [ vm ] <EOL> self . classes = { } <EOL> self . strings = { } <EOL> for current_class in vm . get_classes ( ) : <EOL> self . classes [ current_class . get_name ( ) ] = ClassAnalysis ( <EOL> current_class ) <EOL> def create_xref ( self ) : <EOL> debug ( "<STR_LIT>" ) <EOL> instances_class_name = self . classes . keys ( ) <EOL> last_vm = self . vms [ - <NUM_LIT:1> ] <EOL> for current_class in last_vm . get_classes ( ) : <EOL> for current_method in current_class . get_methods ( ) : <EOL> debug ( "<STR_LIT>" % current_method ) <EOL> code = current_method . get_code ( ) <EOL> if code == None : <EOL> continue <EOL> off = <NUM_LIT:0> <EOL> bc = code . get_bc ( ) <EOL> try : <EOL> for instruction in bc . get_instructions ( ) : <EOL> op_value = instruction . get_op_value ( ) <EOL> if op_value in [ <NUM_LIT> , <NUM_LIT> ] : <EOL> idx_type = instruction . get_ref_kind ( ) <EOL> type_info = last_vm . get_cm_type ( idx_type ) <EOL> if type_info in instances_class_name and type_info != current_class . get_name ( <EOL> ) : <EOL> if op_value == <NUM_LIT> : <EOL> self . classes [ current_class . get_name ( <EOL> ) ] . AddXrefTo ( REF_NEW_INSTANCE , <EOL> self . classes [ type_info ] , <EOL> current_method , off ) <EOL> self . classes [ type_info ] . AddXrefFrom ( <EOL> REF_NEW_INSTANCE , <EOL> self . classes [ current_class . get_name ( ) ] , <EOL> current_method , off ) <EOL> else : <EOL> self . classes [ current_class . get_name ( <EOL> ) ] . AddXrefTo ( REF_CLASS_USAGE , <EOL> self . classes [ type_info ] , <EOL> current_method , off ) <EOL> self . classes [ type_info ] . AddXrefFrom ( <EOL> REF_CLASS_USAGE , <EOL> self . classes [ current_class . get_name ( ) ] , <EOL> current_method , off ) <EOL> elif ( ( op_value >= <NUM_LIT> and op_value <= <NUM_LIT> ) or <EOL> ( op_value >= <NUM_LIT> and op_value <= <NUM_LIT> ) ) : <EOL> idx_meth = instruction . get_ref_kind ( ) <EOL> method_info = last_vm . get_cm_method ( idx_meth ) <EOL> if method_info : <EOL> class_info = method_info [ <NUM_LIT:0> ] <EOL> method_item = last_vm . get_method_descriptor ( <EOL> method_info [ <NUM_LIT:0> ] , method_info [ <NUM_LIT:1> ] , <EOL> '<STR_LIT>' . join ( method_info [ <NUM_LIT:2> ] ) ) <EOL> if method_item : <EOL> self . classes [ current_class . get_name ( <EOL> ) ] . AddMXrefTo ( current_method , <EOL> self . classes [ class_info ] , <EOL> method_item , <EOL> off ) <EOL> self . classes [ class_info ] . AddMXrefFrom ( <EOL> method_item , <EOL> self . classes [ current_class . get_name ( ) ] , <EOL> current_method , <EOL> off ) <EOL> if class_info in instances_class_name and class_info != current_class . get_name ( <EOL> ) : <EOL> self . classes [ current_class . get_name ( <EOL> ) ] . AddXrefTo ( REF_CLASS_USAGE , <EOL> self . classes [ class_info ] , <EOL> method_item , off ) <EOL> self . classes [ class_info ] . AddXrefFrom ( <EOL> REF_CLASS_USAGE , <EOL> self . classes [ current_class . get_name ( ) ] , <EOL> current_method , off ) <EOL> elif op_value >= <NUM_LIT> and op_value <= <NUM_LIT> : <EOL> string_value = last_vm . get_cm_string ( <EOL> instruction . get_ref_kind ( ) ) <EOL> if string_value not in self . strings : <EOL> self . strings [ string_value ] = StringAnalysis ( <EOL> string_value ) <EOL> self . strings [ string_value ] . AddXrefFrom ( <EOL> self . classes [ current_class . get_name ( ) ] , <EOL> current_method ) <EOL> elif op_value >= <NUM_LIT> and op_value <= <NUM_LIT> : <EOL> idx_field = instruction . get_ref_kind ( ) <EOL> field_info = last_vm . get_cm_field ( idx_field ) <EOL> field_item = last_vm . get_field_descriptor ( <EOL> field_info [ <NUM_LIT:0> ] , field_info [ <NUM_LIT:2> ] , field_info [ <NUM_LIT:1> ] ) <EOL> if field_item : <EOL> if ( op_value >= <NUM_LIT> and op_value <= <NUM_LIT> ) or ( <EOL> op_value >= <NUM_LIT> and op_value <= <NUM_LIT> ) : <EOL> self . classes [ current_class . get_name ( <EOL> ) ] . AddFXrefRead ( <EOL> current_method , <EOL> self . classes [ current_class . get_name ( ) ] , <EOL> field_item ) <EOL> else : <EOL> self . classes [ current_class . get_name ( <EOL> ) ] . AddFXrefWrite ( <EOL> current_method , <EOL> self . classes [ current_class . get_name ( ) ] , <EOL> field_item ) <EOL> off += instruction . get_length ( ) <EOL> except dvm . InvalidInstruction as e : <EOL> warning ( "<STR_LIT>" % str ( e ) ) <EOL> def get_method ( self , method ) : <EOL> for vm in self . vms : <EOL> if method in vm . get_methods ( ) : <EOL> return MethodAnalysis ( vm , method ) <EOL> return None <EOL> def get_method_by_name ( self , class_name , method_name , method_descriptor ) : <EOL> if class_name in self . classes : <EOL> for method in self . classes [ class_name ] . get_vm_class ( ) . get_methods ( ) : <EOL> if method . get_name ( ) == method_name and method . get_descriptor ( <EOL> ) == method_descriptor : <EOL> return method <EOL> return None <EOL> def get_method_analysis ( self , method ) : <EOL> class_analysis = self . get_class_analysis ( method . get_class_name ( ) ) <EOL> if class_analysis : <EOL> return class_analysis . get_method_analysis ( method ) <EOL> return None <EOL> def get_method_analysis_by_name ( self , class_name , method_name , method_descriptor ) : <EOL> method = self . get_method_by_name ( class_name , method_name , method_descriptor ) <EOL> if method : <EOL> return self . get_method_analysis ( method ) <EOL> return None <EOL> def get_field_analysis ( self , field ) : <EOL> class_analysis = self . get_class_analysis ( field . get_class_name ( ) ) <EOL> if class_analysis : <EOL> return class_analysis . get_field_analysis ( field ) <EOL> return None <EOL> def is_class_present ( self , class_name ) : <EOL> return class_name in self . classes <EOL> def get_class_analysis ( self , class_name ) : <EOL> return self . classes . get ( class_name ) <EOL> def get_strings_analysis ( self ) : <EOL> return self . strings <EOL> def add ( self , vm ) : <EOL> self . vms . append ( vm ) <EOL> for current_class in vm . get_classes ( ) : <EOL> if current_class . get_name ( ) not in self . classes : <EOL> self . classes [ current_class . get_name ( ) ] = ClassAnalysis ( <EOL> current_class ) <EOL> def is_ascii_obfuscation ( vm ) : <EOL> for classe in vm . get_classes ( ) : <EOL> if is_ascii_problem ( classe . get_name ( ) ) : <EOL> return True <EOL> for method in classe . get_methods ( ) : <EOL> if is_ascii_problem ( method . get_name ( ) ) : <EOL> return True <EOL> return False </s>
