<s> import sys <EOL> sys . path . append ( '<STR_LIT>' ) <EOL> import logging <EOL> import struct <EOL> from collections import defaultdict <EOL> import androguard . core . androconf as androconf <EOL> import androguard . decompiler . dad . util as util <EOL> from androguard . core . analysis import analysis <EOL> from androguard . core . bytecodes import apk , dvm <EOL> from androguard . decompiler . dad . ast import ( <EOL> JSONWriter , parse_descriptor , literal_string , literal_null , literal_int , <EOL> literal_long , literal_float , literal_double , literal_bool , literal_hex_int , <EOL> dummy ) <EOL> from androguard . decompiler . dad . control_flow import identify_structures <EOL> from androguard . decompiler . dad . dataflow import ( <EOL> build_def_use , place_declarations , dead_code_elimination , <EOL> register_propagation , split_variables ) <EOL> from androguard . decompiler . dad . graph import construct , simplify , split_if_nodes <EOL> from androguard . decompiler . dad . instruction import Param , ThisParam <EOL> from androguard . decompiler . dad . writer import Writer <EOL> from androguard . util import read <EOL> def auto_vm ( filename ) : <EOL> ret = androconf . is_android ( filename ) <EOL> if ret == '<STR_LIT>' : <EOL> return dvm . DalvikVMFormat ( apk . APK ( filename ) . get_dex ( ) ) <EOL> elif ret == '<STR_LIT>' : <EOL> return dvm . DalvikVMFormat ( read ( filename ) ) <EOL> elif ret == '<STR_LIT>' : <EOL> return dvm . DalvikOdexVMFormat ( read ( filename ) ) <EOL> return None <EOL> def get_field_ast ( field ) : <EOL> triple = field . get_class_name ( ) [ <NUM_LIT:1> : - <NUM_LIT:1> ] , field . get_name ( <EOL> ) , field . get_descriptor ( ) <EOL> expr = None <EOL> if field . init_value : <EOL> val = field . init_value . value <EOL> expr = dummy ( str ( val ) ) <EOL> if val is not None : <EOL> if field . get_descriptor ( ) == '<STR_LIT>' : <EOL> expr = literal_string ( val ) <EOL> elif field . proto == '<STR_LIT:B>' : <EOL> expr = literal_hex_int ( struct . unpack ( '<STR_LIT>' , val ) [ <NUM_LIT:0> ] ) <EOL> return { <EOL> '<STR_LIT>' : triple , <EOL> '<STR_LIT:type>' : parse_descriptor ( field . get_descriptor ( ) ) , <EOL> '<STR_LIT>' : util . get_access_field ( field . get_access_flags ( ) ) , <EOL> '<STR_LIT>' : expr , <EOL> } <EOL> class DvMethod ( object ) : <EOL> def __init__ ( self , methanalysis ) : <EOL> method = methanalysis . get_method ( ) <EOL> self . method = method <EOL> self . start_block = next ( methanalysis . get_basic_blocks ( ) . get ( ) , None ) <EOL> self . cls_name = method . get_class_name ( ) <EOL> self . name = method . get_name ( ) <EOL> self . lparams = [ ] <EOL> self . var_to_name = defaultdict ( ) <EOL> self . writer = None <EOL> self . graph = None <EOL> self . ast = None <EOL> self . access = util . get_access_method ( method . get_access_flags ( ) ) <EOL> desc = method . get_descriptor ( ) <EOL> self . type = desc . split ( '<STR_LIT:)>' ) [ - <NUM_LIT:1> ] <EOL> self . params_type = util . get_params_type ( desc ) <EOL> self . triple = method . get_triple ( ) <EOL> self . exceptions = methanalysis . exceptions . exceptions <EOL> code = method . get_code ( ) <EOL> if code is None : <EOL> logger . debug ( '<STR_LIT>' , self . name , self . cls_name ) <EOL> else : <EOL> start = code . registers_size - code . ins_size <EOL> if '<STR_LIT>' not in self . access : <EOL> self . var_to_name [ start ] = ThisParam ( start , self . cls_name ) <EOL> self . lparams . append ( start ) <EOL> start += <NUM_LIT:1> <EOL> num_param = <NUM_LIT:0> <EOL> for ptype in self . params_type : <EOL> param = start + num_param <EOL> self . lparams . append ( param ) <EOL> self . var_to_name [ param ] = Param ( param , ptype ) <EOL> num_param += util . get_type_size ( ptype ) <EOL> if not __debug__ : <EOL> from androguard . core import bytecode <EOL> bytecode . method2png ( '<STR_LIT>' % ( self . cls_name . split ( '<STR_LIT:/>' ) [ - <NUM_LIT:1> ] [ : - <NUM_LIT:1> ] , self . name ) , methanalysis ) <EOL> def process ( self , doAST = False ) : <EOL> logger . debug ( '<STR_LIT>' , self . name ) <EOL> if self . start_block is None : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> if doAST : <EOL> self . ast = JSONWriter ( None , self ) . get_ast ( ) <EOL> else : <EOL> self . writer = Writer ( None , self ) <EOL> self . writer . write_method ( ) <EOL> return <EOL> graph = construct ( self . start_block , self . var_to_name , self . exceptions ) <EOL> self . graph = graph <EOL> if not __debug__ : <EOL> util . create_png ( self . cls_name , self . name , graph , '<STR_LIT>' ) <EOL> use_defs , def_uses = build_def_use ( graph , self . lparams ) <EOL> split_variables ( graph , self . var_to_name , def_uses , use_defs ) <EOL> dead_code_elimination ( graph , def_uses , use_defs ) <EOL> register_propagation ( graph , def_uses , use_defs ) <EOL> place_declarations ( graph , self . var_to_name , def_uses , use_defs ) <EOL> del def_uses , use_defs <EOL> split_if_nodes ( graph ) <EOL> simplify ( graph ) <EOL> graph . compute_rpo ( ) <EOL> if not __debug__ : <EOL> util . create_png ( self . cls_name , self . name , graph , <EOL> '<STR_LIT>' ) <EOL> identify_structures ( graph , graph . immediate_dominators ( ) ) <EOL> if not __debug__ : <EOL> util . create_png ( self . cls_name , self . name , graph , <EOL> '<STR_LIT>' ) <EOL> if doAST : <EOL> self . ast = JSONWriter ( graph , self ) . get_ast ( ) <EOL> else : <EOL> self . writer = Writer ( graph , self ) <EOL> self . writer . write_method ( ) <EOL> def get_ast ( self ) : <EOL> return self . ast <EOL> def show_source ( self ) : <EOL> print self . get_source ( ) <EOL> def get_source ( self ) : <EOL> if self . writer : <EOL> return '<STR_LIT:%s>' % self . writer <EOL> return '<STR_LIT>' <EOL> def get_source_ext ( self ) : <EOL> if self . writer : <EOL> return self . writer . str_ext ( ) <EOL> return [ ] <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % self . name <EOL> class DvClass ( object ) : <EOL> def __init__ ( self , dvclass , vma ) : <EOL> name = dvclass . get_name ( ) <EOL> if name . find ( '<STR_LIT:/>' ) > <NUM_LIT:0> : <EOL> pckg , name = name . rsplit ( '<STR_LIT:/>' , <NUM_LIT:1> ) <EOL> else : <EOL> pckg , name = '<STR_LIT>' , name <EOL> self . package = pckg [ <NUM_LIT:1> : ] . replace ( '<STR_LIT:/>' , '<STR_LIT:.>' ) <EOL> self . name = name [ : - <NUM_LIT:1> ] <EOL> self . vma = vma <EOL> self . methods = dvclass . get_methods ( ) <EOL> self . fields = dvclass . get_fields ( ) <EOL> self . code = [ ] <EOL> self . inner = False <EOL> access = dvclass . get_access_flags ( ) <EOL> if <NUM_LIT> & access : <EOL> prototype = '<STR_LIT>' <EOL> if access & <NUM_LIT> : <EOL> access -= <NUM_LIT> <EOL> else : <EOL> prototype = '<STR_LIT>' <EOL> self . access = util . get_access_class ( access ) <EOL> self . prototype = prototype % ( '<STR_LIT:U+0020>' . join ( self . access ) , self . name ) <EOL> self . interfaces = dvclass . get_interfaces ( ) <EOL> self . superclass = dvclass . get_superclassname ( ) <EOL> self . thisclass = dvclass . get_name ( ) <EOL> logger . info ( '<STR_LIT>' , self . name ) <EOL> logger . info ( '<STR_LIT>' ) <EOL> for meth in self . methods : <EOL> logger . info ( '<STR_LIT>' , meth . get_method_idx ( ) , self . name , <EOL> meth . name ) <EOL> logger . info ( '<STR_LIT>' ) <EOL> def get_methods ( self ) : <EOL> return self . methods <EOL> def process_method ( self , num , doAST = False ) : <EOL> method = self . methods [ num ] <EOL> if not isinstance ( method , DvMethod ) : <EOL> cached = True <EOL> if not method . is_cached_instructions ( ) : <EOL> method . set_instructions ( [ i for i in method . get_instructions ( ) ] ) <EOL> cached = False <EOL> self . methods [ num ] = DvMethod ( self . vma . get_method ( method ) ) <EOL> self . methods [ num ] . process ( doAST = doAST ) <EOL> if not cached : <EOL> method . set_instructions ( [ ] ) <EOL> else : <EOL> method . process ( doAST = doAST ) <EOL> def process ( self , doAST = False ) : <EOL> for i in range ( len ( self . methods ) ) : <EOL> try : <EOL> self . process_method ( i , doAST = doAST ) <EOL> except Exception as e : <EOL> logger . debug ( <EOL> '<STR_LIT>' , self . methods [ i ] , e ) <EOL> def get_ast ( self ) : <EOL> fields = [ get_field_ast ( f ) for f in self . fields ] <EOL> methods = [ ] <EOL> for m in self . methods : <EOL> if isinstance ( m , DvMethod ) and m . ast : <EOL> methods . append ( m . get_ast ( ) ) <EOL> isInterface = '<STR_LIT>' in self . access <EOL> return { <EOL> '<STR_LIT>' : self . thisclass [ <NUM_LIT:1> : - <NUM_LIT:1> ] , <EOL> '<STR_LIT:name>' : parse_descriptor ( self . thisclass ) , <EOL> '<STR_LIT>' : parse_descriptor ( self . superclass ) , <EOL> '<STR_LIT>' : self . access , <EOL> '<STR_LIT>' : isInterface , <EOL> '<STR_LIT>' : map ( parse_descriptor , self . interfaces ) , <EOL> '<STR_LIT>' : fields , <EOL> '<STR_LIT>' : methods , <EOL> } <EOL> def get_source ( self ) : <EOL> source = [ ] <EOL> if not self . inner and self . package : <EOL> source . append ( '<STR_LIT>' % self . package ) <EOL> superclass , prototype = self . superclass , self . prototype <EOL> if superclass is not None and superclass != '<STR_LIT>' : <EOL> superclass = superclass [ <NUM_LIT:1> : - <NUM_LIT:1> ] . replace ( '<STR_LIT:/>' , '<STR_LIT:.>' ) <EOL> prototype += '<STR_LIT>' % superclass <EOL> if len ( self . interfaces ) > <NUM_LIT:0> : <EOL> prototype += '<STR_LIT>' % '<STR_LIT:U+002CU+0020>' . join ( <EOL> [ n [ <NUM_LIT:1> : - <NUM_LIT:1> ] . replace ( '<STR_LIT:/>' , '<STR_LIT:.>' ) for n in self . interfaces ] ) <EOL> source . append ( '<STR_LIT>' % prototype ) <EOL> for field in self . fields : <EOL> name = field . get_name ( ) <EOL> access = util . get_access_field ( field . get_access_flags ( ) ) <EOL> f_type = util . get_type ( field . get_descriptor ( ) ) <EOL> source . append ( '<STR_LIT:U+0020>' ) <EOL> if access : <EOL> source . append ( '<STR_LIT:U+0020>' . join ( access ) ) <EOL> source . append ( '<STR_LIT:U+0020>' ) <EOL> if field . init_value : <EOL> value = field . init_value . value <EOL> if f_type == '<STR_LIT>' : <EOL> value = '<STR_LIT>' % value <EOL> elif field . proto == '<STR_LIT:B>' : <EOL> value = '<STR_LIT>' % struct . unpack ( '<STR_LIT:b>' , value ) [ <NUM_LIT:0> ] <EOL> source . append ( '<STR_LIT>' % ( f_type , name , value ) ) <EOL> else : <EOL> source . append ( '<STR_LIT>' % ( f_type , name ) ) <EOL> for method in self . methods : <EOL> if isinstance ( method , DvMethod ) : <EOL> source . append ( method . get_source ( ) ) <EOL> source . append ( '<STR_LIT>' ) <EOL> return '<STR_LIT>' . join ( source ) <EOL> def get_source_ext ( self ) : <EOL> source = [ ] <EOL> if not self . inner and self . package : <EOL> source . append ( <EOL> ( '<STR_LIT>' , [ ( '<STR_LIT>' , '<STR_LIT>' ) , ( <EOL> '<STR_LIT>' , '<STR_LIT:%s>' % self . package ) , ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> ] ) ) <EOL> list_proto = [ ] <EOL> list_proto . append ( <EOL> ( '<STR_LIT>' , '<STR_LIT>' % '<STR_LIT:U+0020>' . join ( self . access ) ) ) <EOL> list_proto . append ( ( '<STR_LIT>' , '<STR_LIT:%s>' % self . name , self . package ) ) <EOL> superclass = self . superclass <EOL> if superclass is not None and superclass != '<STR_LIT>' : <EOL> superclass = superclass [ <NUM_LIT:1> : - <NUM_LIT:1> ] . replace ( '<STR_LIT:/>' , '<STR_LIT:.>' ) <EOL> list_proto . append ( ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> list_proto . append ( ( '<STR_LIT>' , '<STR_LIT:%s>' % superclass ) ) <EOL> if len ( self . interfaces ) > <NUM_LIT:0> : <EOL> list_proto . append ( ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> for i , interface in enumerate ( self . interfaces ) : <EOL> if i != <NUM_LIT:0> : <EOL> list_proto . append ( ( '<STR_LIT>' , '<STR_LIT:U+002CU+0020>' ) ) <EOL> list_proto . append ( <EOL> ( '<STR_LIT>' , interface [ <NUM_LIT:1> : - <NUM_LIT:1> ] . replace ( '<STR_LIT:/>' , '<STR_LIT:.>' ) ) ) <EOL> list_proto . append ( ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> source . append ( ( "<STR_LIT>" , list_proto ) ) <EOL> for field in self . fields : <EOL> field_access_flags = field . get_access_flags ( ) <EOL> access = [ util . ACCESS_FLAGS_FIELDS [ flag ] <EOL> for flag in util . ACCESS_FLAGS_FIELDS <EOL> if flag & field_access_flags ] <EOL> f_type = util . get_type ( field . get_descriptor ( ) ) <EOL> name = field . get_name ( ) <EOL> if access : <EOL> access_str = '<STR_LIT>' % '<STR_LIT:U+0020>' . join ( access ) <EOL> else : <EOL> access_str = '<STR_LIT:U+0020>' <EOL> source . append ( <EOL> ( '<STR_LIT>' , [ ( '<STR_LIT>' , access_str ) , ( <EOL> '<STR_LIT>' , '<STR_LIT:%s>' % f_type ) , ( '<STR_LIT>' , '<STR_LIT:U+0020>' ) , ( <EOL> '<STR_LIT>' , '<STR_LIT:%s>' % name , f_type , field ) , ( '<STR_LIT>' , <EOL> '<STR_LIT>' ) ] ) ) <EOL> for method in self . methods : <EOL> if isinstance ( method , DvMethod ) : <EOL> source . append ( ( "<STR_LIT>" , method . get_source_ext ( ) ) ) <EOL> source . append ( ( "<STR_LIT>" , [ ( '<STR_LIT>' , '<STR_LIT>' ) ] ) ) <EOL> return source <EOL> def show_source ( self ) : <EOL> print self . get_source ( ) <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % self . name <EOL> class DvMachine ( object ) : <EOL> def __init__ ( self , name ) : <EOL> vm = auto_vm ( name ) <EOL> if vm is None : <EOL> raise ValueError ( '<STR_LIT>' % name ) <EOL> self . vma = analysis . newVMAnalysis ( vm ) <EOL> self . classes = dict ( ( dvclass . get_name ( ) , dvclass ) <EOL> for dvclass in vm . get_classes ( ) ) <EOL> def get_classes ( self ) : <EOL> return self . classes . keys ( ) <EOL> def get_class ( self , class_name ) : <EOL> for name , klass in self . classes . iteritems ( ) : <EOL> if class_name in name : <EOL> if isinstance ( klass , DvClass ) : <EOL> return klass <EOL> dvclass = self . classes [ name ] = DvClass ( klass , self . vma ) <EOL> return dvclass <EOL> def process ( self ) : <EOL> for name , klass in self . classes . iteritems ( ) : <EOL> logger . info ( '<STR_LIT>' , name ) <EOL> if isinstance ( klass , DvClass ) : <EOL> klass . process ( ) <EOL> else : <EOL> dvclass = self . classes [ name ] = DvClass ( klass , self . vma ) <EOL> dvclass . process ( ) <EOL> def show_source ( self ) : <EOL> for klass in self . classes . values ( ) : <EOL> klass . show_source ( ) <EOL> def process_and_show ( self ) : <EOL> for name , klass in sorted ( self . classes . iteritems ( ) ) : <EOL> logger . info ( '<STR_LIT>' , name ) <EOL> if not isinstance ( klass , DvClass ) : <EOL> klass = DvClass ( klass , self . vma ) <EOL> klass . process ( ) <EOL> klass . show_source ( ) <EOL> logger = logging . getLogger ( '<STR_LIT>' ) <EOL> sys . setrecursionlimit ( <NUM_LIT> ) <EOL> def main ( ) : <EOL> logger . setLevel ( logging . INFO ) <EOL> console_hdlr = logging . StreamHandler ( sys . stdout ) <EOL> console_hdlr . setFormatter ( logging . Formatter ( '<STR_LIT>' ) ) <EOL> logger . addHandler ( console_hdlr ) <EOL> default_file = '<STR_LIT>' <EOL> if len ( sys . argv ) > <NUM_LIT:1> : <EOL> machine = DvMachine ( sys . argv [ <NUM_LIT:1> ] ) <EOL> else : <EOL> machine = DvMachine ( default_file ) <EOL> logger . info ( '<STR_LIT>' ) <EOL> logger . info ( '<STR_LIT>' ) <EOL> for class_name in sorted ( machine . get_classes ( ) ) : <EOL> logger . info ( '<STR_LIT>' , class_name ) <EOL> logger . info ( '<STR_LIT>' ) <EOL> cls_name = raw_input ( '<STR_LIT>' ) <EOL> if cls_name == '<STR_LIT:*>' : <EOL> machine . process_and_show ( ) <EOL> else : <EOL> cls = machine . get_class ( cls_name ) <EOL> if cls is None : <EOL> logger . error ( '<STR_LIT>' , cls_name ) <EOL> else : <EOL> logger . info ( '<STR_LIT>' ) <EOL> for i , method in enumerate ( cls . get_methods ( ) ) : <EOL> logger . info ( '<STR_LIT>' , i , method . name ) <EOL> logger . info ( '<STR_LIT>' ) <EOL> meth = raw_input ( '<STR_LIT>' ) <EOL> if meth == '<STR_LIT:*>' : <EOL> logger . info ( '<STR_LIT>' , cls ) <EOL> cls . process ( ) <EOL> else : <EOL> cls . process_method ( int ( meth ) ) <EOL> logger . info ( '<STR_LIT>' ) <EOL> logger . info ( '<STR_LIT>' ) <EOL> cls . show_source ( ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> main ( ) </s>
