def testcode(self):
        skipped_methods = []

        fname = "examples/android/TestsAndroguard/bin/classes.dex"

        parsed = parse_dex.read_dex(fname)

        with open(fname, "rb") as f:
            d = DalvikVMFormat(f.read())

            dif = Differ()

            for m in d.get_methods():
                if not m.get_code():
                    continue

                if m.get_method_idx() in skipped_methods:
                    continue

                code = hexlify(m.get_code().get_raw())
                self.assertEqual(parsed[m.get_method_idx()],
                                 code,
                                 "incorrect code for "
                                 "[{}]: {} --> {}:\n"
                                 "{}\ntries_size: {}, insns_size: {}\nSHOULD BE {}\n{}\n{}".format(m.get_method_idx(),
                                             m.get_class_name(),
                                             m.get_name(),
                                             "".join(dif.compare(parsed[m.get_method_idx()],
                                             code)),
                                             m.get_code().tries_size,
                                             m.get_code().insns_size,
                                             hexlify(m.get_code().get_raw()),
                                             parsed[m.get_method_idx()],
                                             hexlify(m.get_code().code.get_raw())))
    def testClassManager(self):
        """Test if the classmanager has the same items"""

        from androguard.core.bytecodes.mutf8 import decode, patch_string

        fname = "examples/android/TestsAndroguard/bin/classes.dex"

        parsed = parse_dex.read_dex(fname)

        with open(fname, "rb") as f:
            d = DalvikVMFormat(f.read())

        cm = d.get_class_manager()

        self.assertFalse(cm.get_odex_format())

        ERR_STR = 'AG:IS: invalid string'

        ## Testing Strings...
        for idx in range(parsed.string_ids_size):
            self.assertNotEqual(cm.get_string(idx), ERR_STR)
            self.assertNotEqual(cm.get_raw_string(idx), ERR_STR)
            self.assertEqual(cm.get_raw_string(idx), patch_string(decode(parsed.str_raw[idx])))

        self.assertEqual(cm.get_string(parsed.string_ids_size), ERR_STR)
        self.assertEqual(cm.get_raw_string(parsed.string_ids_size), ERR_STR)

        self.assertEqual(cm.get_string(parsed.string_ids_size + 100), ERR_STR)
        self.assertEqual(cm.get_raw_string(parsed.string_ids_size + 100), ERR_STR)
class GetFieldType:

    predictions = {}
    
    def __init__(self, args):
        
        
        self.apk = args.apk
        self.verbosity = args.verbosity
        self.output_location = args.output_location
        self.file_identifier = args.apk.split('.')[0]
        self.file_identifier = self.file_identifier[-24:]

        # print "Analyzing " + self.apk
        # print " Output Location " + self.output_location
        # print "File Identifier " + self.file_identifier
        
        

        
        # analyze the dex file
        print "From LOCATION = ",self.apk
        self.a = APK(self.apk)

        # get the vm analysis
        self.d = DalvikVMFormat(self.a.get_dex())
        self.dx = VMAnalysis(self.d)
        self.gx = GVMAnalysis(self.dx, None)

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

        # create the cross reference
        self.d.create_xref()
        self.d.create_dref()
        
        print 'CWD: ', os.getcwd()
        predictor = Predict_Input(self.output_location,self.file_identifier)
        self.predictions = predictor.predict(self.apk, self.apk[:-4],self.output_location,self.file_identifier)

        

        try:
            # get the classes for this apk
            # store them in a dict
            self.classes = self.get_class_dict()

            # Find the R$layout class
            self.Rlayout = self.get_RLayout(self.d.get_classes())

            # Find the R$id class
            self.Rid = self.get_Rid(self.d.get_classes())

            # Store all fields referenced in R$id
            self.fields, self.field_refs = self.get_fields(self.Rid)
        except Exception, e:
            print e
 def __analyze_dex(self, dex_file, raw=False) :
     # DalvikVMFormat
     dalvik_vm_format = None
     if raw == False :
         dalvik_vm_format = DalvikVMFormat( open(dex_file, "rb").read() )
     else :
         dalvik_vm_format = DalvikVMFormat( dex_file )
   
     # VMAnalysis
     vm_analysis = VMAnalysis( dalvik_vm_format )
     dalvik_vm_format.set_vmanalysis( vm_analysis )
             
     return vm_analysis
示例#5
0
def AnalyzeAPK(_file, session=None, raw=False):
    """
    Analyze an android application and setup all stuff for a more quickly
    analysis!
    If session is None, no session is used at all. This is the default
    behaviour.
    If you like to continue your work later, it might be a good idea to use a
    session.
    A default session can be created by using :meth:`~get_default_session`.

    :param _file: the filename of the android application or a buffer which represents the application
    :type _file: string (for filename) or bytes (for raw)
    :param session: A session (default: None)
    :param raw: boolean if raw bytes are supplied instead of a filename
    :rtype: return the :class:`~androguard.core.bytecodes.apk.APK`, list of :class:`~androguard.core.bytecodes.dvm.DalvikVMFormat`, and :class:`~androguard.core.analysis.analysis.Analysis` objects
    """
    log.debug("AnalyzeAPK")


    if session:
        log.debug("Using existing session {}".format(session))
        if raw:
            data = _file
            filename = hashlib.md5(_file).hexdigest()
        else:
            with open(_file, "rb") as fd:
                data = fd.read()
                filename = _file

        digest = session.add(filename, data)
        return session.get_objects_apk(filename, digest)
    else:
        log.debug("Analysing without session")
        a = APK(_file, raw=raw)
        # FIXME: probably it is not necessary to keep all DalvikVMFormats, as
        # they are already part of Analysis. But when using sessions, it works
        # this way...
        d = []
        dx = Analysis()
        for dex in a.get_all_dex():
            df = DalvikVMFormat(dex, using_api=a.get_target_sdk_version())
            dx.add(df)
            d.append(df)
            df.set_decompiler(decompiler.DecompilerDAD(d, dx))

        dx.create_xref()

        return a, d, dx
示例#6
0
class GetFieldType:

    def __init__(self, args):
        self.apk = args.apk
        self.verbosity = args.verbosity

        print "Analyzing " + self.apk

        # analyze the dex file
        self.a = APK(self.apk)

        # get the vm analysis
        self.d = DalvikVMFormat(self.a.get_dex())
        self.dx = VMAnalysis(self.d)
        self.gx = GVMAnalysis(self.dx, None)

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

        # create the cross reference
        self.d.create_xref()
        self.d.create_dref()

        try:
            # get the classes for this apk
            # store them in a dict
            self.classes = self.get_class_dict()

            # Find the R$layout class
            self.Rlayout = self.get_RLayout(self.d.get_classes())

            # Find the R$id class
            self.Rid = self.get_Rid(self.d.get_classes())

            # Store all fields referenced in R$id
            self.fields, self.field_refs = self.get_fields(self.Rid)
        except Exception, e:
            print e
示例#7
0
文件: apk.py 项目: Rafiot/viper
        def analyze_dex(filename, raw=False, decompiler=None):
            """
            Analyze an android dex file and setup all stuff for a more quickly analysis !

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

            :rtype: return the :class:`DalvikVMFormat`, and :class:`VMAnalysis` objects
            """
            d = None
            if raw:
                d = DalvikVMFormat(filename)
            else:
                d = DalvikVMFormat(open(filename, "rb").read())
            dx = analysis.Analysis(d)
            d.set_vmanalysis(dx)
            run_decompiler(d, dx, decompiler)
            dx.create_xref()
            return d, dx
示例#8
0
    def __init__(self, args):
        self.apk = args.apk
        self.verbosity = args.verbosity

        print "Analyzing " + self.apk

        # analyze the dex file
        self.a = APK(self.apk)

        # get the vm analysis
        self.d = DalvikVMFormat(self.a.get_dex())
        self.dx = VMAnalysis(self.d)
        self.gx = GVMAnalysis(self.dx, None)

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

        # create the cross reference
        self.d.create_xref()
        self.d.create_dref()

        try:
            # get the classes for this apk
            # store them in a dict
            self.classes = self.get_class_dict()

            # Find the R$layout class
            self.Rlayout = self.get_RLayout(self.d.get_classes())

            # Find the R$id class
            self.Rid = self.get_Rid(self.d.get_classes())

            # Store all fields referenced in R$id
            self.fields, self.field_refs = self.get_fields(self.Rid)
        except Exception, e:
            print e
    def on_complete(self):

        receivers = self.get_results("apkinfo",
                                     {}).get("manifest",
                                             {}).get("receivers", {})
        activities = self.get_results("apkinfo",
                                      {}).get("manifest",
                                              {}).get("activities", {})
        services = self.get_results("apkinfo", {}).get("manifest",
                                                       {}).get("services", {})

        app_path = self.get_results("target", {}).get("file",
                                                      {}).get("path", None)

        if not app_path:
            return False

        if not os.path.exists(app_path):
            return False

        app_apk = APK(app_path)
        dvm = DalvikVMFormat(app_apk.get_dex())
        classes = set()
        for cls in dvm.get_classes():
            classes.add(cls.name)
        for receiver in receivers:
            if self.convert_class(receiver) not in classes:
                return True

        for activity in activities:
            if self.convert_class(activity) not in classes:
                return True

        for service in services:
            if self.convert_class(service) not in classes:
                return True
示例#10
0
def extract_features(file_path):
    #result = []
    try:
        a = APK(file_path)
        d = DalvikVMFormat(a.get_dex())
        dx = Analysis(d)
        vm = dvm.DalvikVMFormat(a.get_dex())
        vmx = analysis.uAnalysis(vm)
        d.set_Analysis(dx)
        d.set_decompiler(DecompilerDAD(d, dx))
    except:
        return None
    return a.get_permissions()  #it will return permission
示例#11
0
    def __analyze_dex(self, dex_file, raw=False):
        # DalvikVMFormat
        dalvik_vm_format = None
        if raw == False:
            dalvik_vm_format = DalvikVMFormat(open(dex_file, "rb").read())
        else:
            dalvik_vm_format = DalvikVMFormat(dex_file)

        # VMAnalysis
        vm_analysis = VMAnalysis(dalvik_vm_format)
        dalvik_vm_format.set_vmanalysis(vm_analysis)

        return vm_analysis
示例#12
0
    def addDEX(self, filename, data, dx=None, postpone_xref=False):
        """
        Add a DEX file to the Session and run analysis.

        :param filename: the (file)name of the DEX file
        :param data: binary data of the dex file
        :param dx: an existing Analysis Object (optional)
        :param postpone_xref: True if no xref shall be created, and will be called manually
        :return: A tuple of SHA256 Hash, DalvikVMFormat Object and Analysis object
        """
        digest = hashlib.sha256(data).hexdigest()
        log.debug("add DEX:%s" % digest)

        log.debug("Parsing format ...")
        d = DalvikVMFormat(data)
        log.debug("added DEX:%s" % digest)

        self.analyzed_files[filename].append(digest)
        self.analyzed_digest[digest] = filename

        self.analyzed_dex[digest] = d

        if dx is None:
            dx = Analysis()

        dx.add(d)
        if not postpone_xref:
            dx.create_xref()

        # TODO: If multidex: this will called many times per dex, even if already set
        for d in dx.vms:
            # TODO: allow different decompiler here!
            d.set_decompiler(DecompilerDAD(d, dx))
            d.set_vmanalysis(dx)
        self.analyzed_vms[digest] = dx

        if self.export_ipython:
            log.debug("Exporting in ipython")
            d.create_python_export()

        return digest, d, dx
示例#13
0
    def addDEX(self, filename, data, dx=None):
        """
        Add a DEX file to the Session and run analysis.

        :param filename: the (file)name of the DEX file
        :param data: binary data of the dex file
        :param dx: an existing Analysis Object (optional)
        :return: A tuple of SHA256 Hash, DalvikVMFormat Object and Analysis object
        """
        digest = hashlib.sha256(data).hexdigest()
        log.debug("add DEX:%s" % digest)

        log.debug("Parsing format ...")
        d = DalvikVMFormat(data)
        log.debug("added DEX:%s" % digest)

        self.analyzed_files[filename].append(digest)
        self.analyzed_digest[digest] = filename

        self.analyzed_dex[digest] = d

        if dx is None:
            dx = Analysis()

        dx.add(d)
        dx.create_xref()

        # TODO: If multidex: this will called many times per dex, even if already set
        for d in dx.vms:
            # TODO: allow different decompiler here!
            d.set_decompiler(DecompilerDAD(d, dx))
            d.set_vmanalysis(dx)
        self.analyzed_vms[digest] = dx

        if self.export_ipython:
            log.debug("Exporting in ipython")
            d.create_python_export()

        return digest, d, dx
示例#14
0
文件: apk.py 项目: geekscrapy/viper
        def analyze_dex(filename, raw=False, decompiler=None):
            """
            Analyze an android dex file and setup all stuff for a more quickly analysis !

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

            :rtype: return the :class:`DalvikVMFormat`, and :class:`VMAnalysis` objects
            """
            d = None
            if raw:
                d = DalvikVMFormat(filename)
            else:
                d = DalvikVMFormat(open(filename, "rb").read())
            dx = analysis.Analysis(d)
            d.set_vmanalysis(dx)
            run_decompiler(d, dx, decompiler)
            dx.create_xref()
            return d, dx
示例#15
0
def init(apk_file):
    print_k(apk_file)
    dalvik_ctx = DalvikVMFormat( APK(apk_file) )
    methods = dalvik_ctx.get_methods()
    return methods 
示例#16
0
    def process_vm(self, apk=False, dex=False):
        """
        Process the application's classes.dex

        Args:
            param1 = boolean
            param2 = boolean

        Results:
            None
        """
        try:
            if apk:
                # Make sure the APK contains a classes.dex file
                if self.find_dex():
                    self.dex = self.apk.get_dex()
                    if self.dex:
                        self.logger.log("info", "Loading classes.dex ...")
                        from androguard.core.bytecodes.dvm import DalvikVMFormat
                        from androguard.core.analysis.analysis import VMAnalysis
                        from androguard.core.analysis.ganalysis import GVMAnalysis
                        # Create a DalvikVMFormat instance ...
                        # In this case self.dex will be a file type
                        self.vm = DalvikVMFormat(self.dex)
                        if self.vm:
                            print(self.t.yellow("\n\t--> Loaded classes.dex (!)\n"))
                            self.logger.log("info", "Analyzing classes.dex ...")
                            # Analyze the DalvikVMFormat instance and return
                            # analysis instances of VMAnalysis and GVMAnalysis
                            self.vmx = VMAnalysis(self.vm)
                            self.gmx = GVMAnalysis(self.vmx, None)
                            if self.vmx and self.gmx:
                                print(self.t.yellow("\n\t--> Analyzed classes.dex (!)\n"))
                                # Set the analysis properties on the
                                # DalvikVMFormat instance
                                self.vm.set_vmanalysis(self.vmx)
                                self.vm.set_gvmanalysis(self.gmx)
                                # Generate xref(s) and dref(s)
                                self.vm.create_xref()
                                self.vm.create_dref()
                                return
                            else:
                                CommandError("process_vm : Cannot analyze VM instance (!)")
                                return
                        else:
                            CommandError("process_vm : Cannot load VM instance (!)")
                            return
                    else:
                        CommandError("process_vm : classes.dex not found (!)")
                        return
            if dex:
                if self.dex:
                    from androguard.core.bytecodes.dvm import DalvikVMFormat
                    from androguard.core.analysis.analysis import VMAnalysis
                    from androguard.core.analysis.ganalysis import GVMAnalysis
                    # Analyze the DalvikVMFormat instance and return
                    # analysis instances of VMAnalysis and GVMAnalysis
                    self.vm = DalvikVMFormat(self.util.read(self.dex))
                    if self.vm:
                        print(self.t.yellow("\n\t--> Loaded {} (!)\n"
                                            .format(self.dex
                                                    .split("/")[-1])))
                        self.logger.log("info", "Analyzing {} ..."
                                        .format(self.dex
                                                .split("/")[-1]))
                        # Set the analysis properties on the
                        # DalvikVMFormat instance
                        self.vmx = VMAnalysis(self.vm)
                        self.gmx = GVMAnalysis(self.vmx, None)
                        if self.vmx and self.gmx:
                            print(self.t.yellow("\n\t--> Analyzed {} (!)\n"
                                                .format(self.dex
                                                        .split("/")[-1])))
                            # Set the analysis properties on the
                            # DalvikVMFormat instance
                            self.vm.set_vmanalysis(self.vmx)
                            self.vm.set_gvmanalysis(self.gmx)
                            # Generate xref(s) and dref(s)
                            self.vm.create_xref()
                            self.vm.create_dref()
                            return
                        else:
                            CommandError("process_vm :" +
                                         "Cannot analyze VM instance (!)")
                            return
                    else:
                        CommandError("process_vm :" +
                                     "Cannot load VM instance (!)")
                        return
                else:
                    CommandError("process_vm : classes.dex not found (!)")
                    return
        except Exception as e:
            CommandError("process_vm : {}".format(e))
示例#17
0
class Run(Lobotomy):
    def __init__(self, ROOT_DIR):
        Lobotomy.__init__(self)
        self.ROOT_DIR = ROOT_DIR
        self.t = Terminal()
        self.logger = Logger()
        self.util = Util()
        self.apk = None
        self.package = None
        self.vm = None
        self.vmx = None
        self.gmx = None
        self.components = None
        self.dex = None
        self.strings = None
        self.permissions = None
        self.permissions_details = None
        self.files = None
        self.attack_surface = None

    def _cmd_completer(self, name, text, line, begidx, endidx):
        fn = getattr(self, 'do_'+name)
        if not hasattr(fn.im_func, "_expected_args"):
            return []
        a = [arg for arg in fn.im_func._expected_args if arg.startswith(text)]
        return a

    def find_dex(self):
        """
        Return True is classes.dex is found within the target APK.

        Args:
            None

        Returns:
            None
        """
        if self.files:
            for f in self.files:
                if "classes" in f:
                    return True
                    break

    def process_vm(self, apk=False, dex=False):
        """
        Process the application's classes.dex

        Args:
            param1 = boolean
            param2 = boolean

        Results:
            None
        """
        try:
            if apk:
                # Make sure the APK contains a classes.dex file
                if self.find_dex():
                    self.dex = self.apk.get_dex()
                    if self.dex:
                        self.logger.log("info", "Loading classes.dex ...")
                        from androguard.core.bytecodes.dvm import DalvikVMFormat
                        from androguard.core.analysis.analysis import VMAnalysis
                        from androguard.core.analysis.ganalysis import GVMAnalysis
                        # Create a DalvikVMFormat instance ...
                        # In this case self.dex will be a file type
                        self.vm = DalvikVMFormat(self.dex)
                        if self.vm:
                            print(self.t.yellow("\n\t--> Loaded classes.dex (!)\n"))
                            self.logger.log("info", "Analyzing classes.dex ...")
                            # Analyze the DalvikVMFormat instance and return
                            # analysis instances of VMAnalysis and GVMAnalysis
                            self.vmx = VMAnalysis(self.vm)
                            self.gmx = GVMAnalysis(self.vmx, None)
                            if self.vmx and self.gmx:
                                print(self.t.yellow("\n\t--> Analyzed classes.dex (!)\n"))
                                # Set the analysis properties on the
                                # DalvikVMFormat instance
                                self.vm.set_vmanalysis(self.vmx)
                                self.vm.set_gvmanalysis(self.gmx)
                                # Generate xref(s) and dref(s)
                                self.vm.create_xref()
                                self.vm.create_dref()
                                return
                            else:
                                CommandError("process_vm : Cannot analyze VM instance (!)")
                                return
                        else:
                            CommandError("process_vm : Cannot load VM instance (!)")
                            return
                    else:
                        CommandError("process_vm : classes.dex not found (!)")
                        return
            if dex:
                if self.dex:
                    from androguard.core.bytecodes.dvm import DalvikVMFormat
                    from androguard.core.analysis.analysis import VMAnalysis
                    from androguard.core.analysis.ganalysis import GVMAnalysis
                    # Analyze the DalvikVMFormat instance and return
                    # analysis instances of VMAnalysis and GVMAnalysis
                    self.vm = DalvikVMFormat(self.util.read(self.dex))
                    if self.vm:
                        print(self.t.yellow("\n\t--> Loaded {} (!)\n"
                                            .format(self.dex
                                                    .split("/")[-1])))
                        self.logger.log("info", "Analyzing {} ..."
                                        .format(self.dex
                                                .split("/")[-1]))
                        # Set the analysis properties on the
                        # DalvikVMFormat instance
                        self.vmx = VMAnalysis(self.vm)
                        self.gmx = GVMAnalysis(self.vmx, None)
                        if self.vmx and self.gmx:
                            print(self.t.yellow("\n\t--> Analyzed {} (!)\n"
                                                .format(self.dex
                                                        .split("/")[-1])))
                            # Set the analysis properties on the
                            # DalvikVMFormat instance
                            self.vm.set_vmanalysis(self.vmx)
                            self.vm.set_gvmanalysis(self.gmx)
                            # Generate xref(s) and dref(s)
                            self.vm.create_xref()
                            self.vm.create_dref()
                            return
                        else:
                            CommandError("process_vm :" +
                                         "Cannot analyze VM instance (!)")
                            return
                    else:
                        CommandError("process_vm :" +
                                     "Cannot load VM instance (!)")
                        return
                else:
                    CommandError("process_vm : classes.dex not found (!)")
                    return
        except Exception as e:
            CommandError("process_vm : {}".format(e))

    def complete_operate(self, *args):
        return self._cmd_completer("operate", *args)

    @cmd_arguments(["apk", "dex"])
    def do_operate(self, *args):
        """
        := operate apk path_to_apk
        := operate dex path_to_classes.dex
        """
        # Locals
        arg0 = args[0].split(" ")[0]
        arg1 = args[0].split(" ")[1]

        try:
            if arg0 == "apk":
                if arg1:
                    self.logger.log("info", "Loading : {} ..."
                                    .format(arg1.split("/")[-1]))
                    from androguard.core.bytecodes.apk import APK
                    self.apk = APK(arg1)
                    if self.apk:
                        print(self.t.yellow("\n\t--> Loaded : {} (!)\n"
                                            .format(arg1.split("/")[-1])))
                        self.package = self.apk.get_package()
                        from core.brains.apk.components import Components
                        # Load activies, services, broadcast receivers, and
                        # content providers
                        self.components = Components(self.apk)
                        self.components.enumerate_components()
                        self.permissions = self.apk.get_permissions()
                        self.files = self.apk.get_files()
                        self.files_type = self.apk.get_files_types()
                        # Process DVM
                        self.process_vm(apk=True)
                    else:
                        CommandError("APK not loaded (!)")
            elif arg0 == "dex":
                if arg1:
                    self.logger.log("info", "Loading : {} ..."
                                    .format(arg1.split("/")[-1]))
                    self.dex = arg1
                    self.process_vm(dex=True)
        except ImportError as e:
            CommandError("operate : {}".format(e))

    def complete_surgical(self, *args):
        return self._cmd_completer("surgical", *args)

    def do_surgical(self, *args):
        """
        := surgical
        """
        try:
            if self.vm and self.vmx:
                from .surgical import Run
                run = Run(self.vm, self.vmx)
                run.prompt = self.t.yellow("(surgical) ")
                run.ruler = self.t.yellow("-")
                run.cmdloop()
            else:
                CommandError("classes.dex not loaded (!)")
        except Exception as e:
            CommandError("surgical : {}".format(e))

    def complete_attacksurface(self, *args):
        return self._cmd_completer("attacksurface", *args)

    def do_attacksurface(self, *args):
        """
        := attacksurface
        """
        try:
            if self.apk and self.components:
                self.logger.log("info", "Loading attacksurface module ...")
                from core.brains.apk.attacksurface import AttackSurface
                self.attack_surface = AttackSurface(self.apk, self.components)
                self.attack_surface.run()
                # Helps with visual spacing after the results are printed
                print("\n")
        except ImportError as e:
            CommandError("attacksurface : {}".format(e))

    def complete_permissions(self, *args):
        return self._cmd_completer("permissions", *args)

    @cmd_arguments(["list"])
    def do_permissions(self, *args):
        """
        := permissions list
        """
        # Locals
        arg0 = args[0]

        try:
            if self.permissions:
                if args[0] == "list":
                    self.logger.log("info", "Loading permissions ... \n")
                    for p in self.permissions:
                        print(self.t.yellow("\t--> {}".format(p)))
                    print("\n")
            else:
                CommandError("Permissions not found (!)")
        except Exception as e:
            CommandError("permissions : {}".format(e))

    def complete_binja(self, *args):
        return self._cmd_completer("binja", *args)

    def do_binja(self, *args):
        """
        := binja
        """
        try:
            from .binja import Run
            run = Run(self.files, self.apk)
            run.prompt = self.t.cyan("(binja) ")
            run.ruler = self.t.cyan("-")
            run.cmdloop()
        except Exception as e:
            CommandError("binja : {}".format(e))



    def complete_files(self, *args):
        return self._cmd_completer("files", *args)

    @cmd_arguments(["all", "assets", "libs", "res"])
    def do_files(self, *args):
        """
        := files all
        := files assets
        := files libs
        := files res
        """
        # Locals
        arg0 = args[0]

        try:
            if self.files:
                if arg0 == "assets":
                    self.logger.log("info", "Loading files ... \n")
                    for f in self.files:
                        if f.startswith("assets"):
                            print(self.t.yellow("\t--> {}".format(f)))
                    print("\n")
                elif arg0 == "libs":
                    self.logger.log("info", "Loading files ... \n")
                    for f in self.files:
                        if f.startswith("lib"):
                            print(self.t.yellow("\t--> {}".format(f)))
                    print("\n")
                elif arg0 == "res":
                    self.logger.log("info", "Loading files ... \n")
                    for f in self.files:
                        if f.startswith("res"):
                            print(self.t.yellow("\t--> {}".format(f)))
                    print("\n")
                elif arg0 == "all":
                    self.logger.log("info", "Loading files ... \n")
                    for f in self.files:
                        print(self.t.yellow("\t--> {}".format(f)))
                    print("\n")
            else:
                CommandError("Files not populated (!)")
        except Exception as e:
            CommandError("files : {}".format(e))

    def complete_strings(self, *args):
        return self._cmd_completer("strings", *args)

    @cmd_arguments(["list", "search"])
    def do_strings(self, *args):
        """
        List and search for strings found in classes.dex

        := strings list
        := strings search
        """
        # Locals
        arg0 = args[0]
        strings = None

        try:
            if arg0 == "list":
                if self.vm:
                    strings = self.vm.get_strings()
                    if strings:
                        for s in strings:
                            print(self.t.cyan("--> {}".format(s.encode("utf-8", errors="ignore"))))
                    else:
                        CommandError("Strings not found (!)")
                else:
                    CommandError("classes.dex not loaded (!)")
            elif arg0 == "search":
                if self.vm:
                    strings = self.vm.get_strings()
                    if strings:
                        target = raw_input(self.t.yellow("\n\t--> Enter string : "))
                        for s in strings:
                            if target in s:
                                print(self.t.cyan("\t\t --> {}".format(s.encode("utf-8", errors="ignore"))))
                        print("\n")
                    else:
                        CommandError("Strings not found (!)")
                else:
                    CommandError("classes.dex not loaded (!)")
        except Exception as e:
            CommandError("strings : {}".format(e))

    def complete_components(self, *args):
        return self._cmd_completer("components", *args)

    @cmd_arguments(["list"])
    def do_components(self, *args):
        """
        := components list
        """
        # Locals
        arg0 = args[0]

        try:
            if arg0 == "list":
                if self.apk:
                    self.logger.log("info", "Enumerating components ...\n")
                    if self.components.activities:
                        for a in self.components.activities:
                            print(self.t.yellow("\t--> activity : {}"
                                                .format(a)))
                        print("\n")
                    if self.components.services:
                        for s in self.components.services:
                            print(self.t.yellow("\t--> service : {}"
                                                .format(s)))
                        print("\n")
                    if self.components.receivers:
                        for r in self.components.receivers:
                            print(self.t.yellow("\t--> receiver : {}"
                                                .format(r)))
                        print("\n")
                    if self.components.providers:
                        for r in self.components.providers:
                            print(self.t.yellow("\t--> provider : {}"
                                                .format(s)))
                        print("\n")
                else:
                    CommandError("APK not loaded (!)")
        except Exception as e:
            CommandError("components : {}".format(e))

    def complete_interact(self, *args):
        return self._cmd_completer("interact", *args)

    def do_interact(self, *args):
        """
        Drop into an interactive IPython session.

        := interact
        """
        try:
            if self.vm and self.vmx:
                from core.brains.interact.interact import Interact
                i = Interact(self.vm, self.vmx)
                i.run()
            else:
                CommandError("classes.dex not loaded (!)")
        except Exception as e:
            CommandError("interact : {}".format(e.message))

    def complete_class_tree(self, *args):
        return self._cmd_completer("class_tree", *args)

    def do_class_tree(self, *args):
        """
        := class_tree
        """
        try:
            if self.vm:
                for c in self.vm.get_classes():
                    # We don't care about Android support classes or resource
                    # classes
                    if c.name.startswith("Landroid") or \
                            c.name.split("/")[-1].startswith("R"):
                        continue
                    print("\n")
                    print(self.t.yellow("\t--> class : {} {}".format(c.get_access_flags_string(), c.name)))
                    for f in c.get_fields():
                        print(self.t.white("\t\t--> field : {} {} {}".format(f.get_access_flags_string(), f.get_descriptor(), f.name)))
                    for m in c.get_methods():
                        print(self.t.cyan("\t\t\t--> method : {} {} {}".format(m.get_access_flags_string(), m.name, m.get_descriptor())))
                print("\n")
            else:
                CommandError("class_tree : classes.dex not loaded (!)")
        except Exception as e:
            CommandError("class_tree : {}".format(e))

    def complete_native(self, *args):
        return self._cmd_completer("native", *args)

    def do_native(self, *args):
        """
        := native
        """
        # Locals
        native_methods = list()

        try:
            if self.vm:
                for method in self.vm.get_methods():
                    if method.get_access_flags() & 0x100:
                        native_methods.append((method.get_class_name(),
                                               method.get_name()))
                if native_methods:
                    print("\n")
                    for n in native_methods:
                        print(self.t.cyan("\t--> {} : {}".format(n[0], n[1])))
                    print("\n")
            else:
                self.logger.log("info",
                                "class_tree : classes.dex not loaded (!)")
        except Exception as e:
            CommandError("native : {}".format(e))

    def complete_ui(self, *args):
        return self._cmd_completer("ui", *args)

    def do_ui(self, *args):
        """
        := ui
        """
        try:
            if self.vm and self.vmx:
                from core.brains.ui.terminal import TerminalApp
                ui = TerminalApp(self.vm, self.vmx)
                ui.run()
        except Exception as e:
            CommandError("ui : {}".format(e))

    def complete_macro(self, *args):
        return self._cmd_completer("macro", *args)

    def do_macro(self, args):
        """
        := macro
        """
        # Locals
        directory_items = None
        macro = path.join(self.ROOT_DIR, "macro")
        selection = None
        apk_path = None
        json = None

        try:
            print("\n")
            directory_items = listdir(macro)
            for i, item in enumerate(directory_items):
                print(self.t.cyan("\t--> [{}] {}"
                                  .format(i, item)))
            print("\n")
            selection = raw_input(self.t.yellow("[{}] Select config : ".format(datetime.now())))
            try:
                index = int(selection)
            except ValueError:
                index = -1
            print("\n")
            if selection:
                for i, item in enumerate(directory_items):
                    if selection == item or i == index:
                        selection = item
                        break
                with open("".join([macro, "/", selection]), "rb") as config:
                    # Load the config as JSON
                    json = loads(config.read())
                    if json:
                        for k, v in json.items():
                            if k == "apk":
                                if v:
                                    apk_path = str(v)
                                    # Call operate() with the path to apk
                                    self.do_operate("apk {}"
                                                    .format(apk_path))
                                    return
                                else:
                                    CommandError("macro : Path to APK not found in {}"
                                                 .format(selection))
                            else:
                                CommandError("macro : Error loading {} as JSON"
                                             .format(selection))
        except Exception as e:
            CommandError("macro : {}".format(e))
def main():
    for path in samples():
        print(path)
        logging.error("Processing" + path)

        tests_apk = ["is_valid_APK", "get_filename", "get_app_name", "get_app_icon",
                 "get_package", "get_androidversion_code", "get_androidversion_name",
                 "get_files", "get_files_types", "get_files_crc32", "get_files_information",
                 "get_raw", "get_dex", "get_all_dex", "get_main_activity",
                 "get_activities", "get_services", "get_receivers", "get_providers",
                 "get_permissions", "get_details_permissions", "get_requested_aosp_permissions",
                 "get_requested_aosp_permissions_details", "get_requested_third_party_permissions",
                 "get_declared_permissions", "get_declared_permissions_details", "get_max_sdk_version",
                 "get_min_sdk_version", "get_target_sdk_version", "get_libraries", "get_android_manifest_axml",
                 "get_android_manifest_xml", "get_android_resources", "get_signature_name", "get_signature_names",
                 "get_signature", "get_signatures"]

        tests_dex = ["get_api_version", "get_classes_def_item", "get_methods_id_item", "get_fields_id_item",
                     "get_codes_item", "get_string_data_item",
                     "get_debug_info_item", "get_header_item", "get_class_manager", "show",
                     "save", "get_classes_names", "get_classes",
                     "get_all_fields", "get_fields", "get_methods", "get_len_methods",
                     "get_strings", "get_format_type", "create_python_export",
                     "get_BRANCH_DVM_OPCODES", "get_determineNext",
                     "get_determineException", "print_classes_hierarchy",
                     "list_classes_hierarchy", "get_format"]

        try:
            # Testing APK
            a = APK(path)
            for t in tests_apk:
                print(t)
                x = getattr(a, t)
                try:
                    x()
                except Exception as aaa:
                    print(aaa)
                    traceback.print_exc()
                    print(path, aaa, file=sys.stderr)
                    logging.exception("{} .. {}".format(path, t))


            # Testing DEX
            for dex in a.get_all_dex():
                d = DalvikVMFormat(dex)
                dx = Analysis(d)
                d.set_vmanalysis(dx)

                # Test decompilation
                for c in d.get_classes():
                    for m in c.get_methods():
                        mx = dx.get_method(m)
                        ms = DvMethod(mx)
                        try:
                            ms.process(doAST=True)
                        except Exception as aaa:
                            print(aaa)
                            traceback.print_exc()
                            print(path, aaa, file=sys.stderr)
                            logging.exception("{} .. {} .. {}".format(path, c.get_name(), m.get_name()))
                        ms2 = DvMethod(mx)
                        try:
                            ms2.process(doAST=False)
                        except Exception as aaa:
                            print(aaa)
                            traceback.print_exc()
                            print(path, aaa, file=sys.stderr)
                            logging.exception("{} .. {} .. {}".format(path, c.get_name(), m.get_name()))

                # Other tests
                for t in tests_dex:
                    print(t)
                    x = getattr(d, t)
                    try:
                        x()
                    except Exception as aaa:
                        print(aaa)
                        traceback.print_exc()
                        print(path, aaa, file=sys.stderr)
                        logging.exception("{} .. {}".format(path, t))

        except KeyboardInterrupt:
            raise
        except FileNotFoundError:
            pass
        except Exception as e:
            print(e)
            traceback.print_exc()
            print(path, e, file=sys.stderr)
            logging.exception(path)
示例#19
0
            if depth == 0:
                print(m.class_name + " -> " + m.name)
            for item in m.XREFfrom.items:
                if item[0].class_name != class_name or item[
                        0].name != method_name:
                    for x in range(1, depth):
                        sys.stdout.write('--')
                    sys.stdout.write('>' + item[0].class_name + "->" +
                                     item[0].name + "\n")
                    XrefTraverse(methods, item[0].class_name, item[0].name,
                                 depth)


if len(sys.argv) > 2:
    filename = sys.argv[1]
    class_name = sys.argv[2]
    class_name = 'L' + class_name.replace(".", "/") + ";"
    #print class_name
    method_name = '<init>'
    d = DalvikVMFormat(APK(filename, False).get_dex())
    d.create_python_export()
    dx = uVMAnalysis(d)
    gx = GVMAnalysis(dx, None)
    d.set_vmanalysis(dx)
    d.set_gvmanalysis(gx)
    d.create_xref()

    XrefTraverse(d.get_methods(), class_name, method_name, 0)
else:
    print "usage: XrefTree.py [filename] [class_name]"
    print "usage: XrefTree.py filename.apk com.xyz.abc"
示例#20
0
def extract_features(file_path):
    result = {}
    try:
        a = APK(file_path)
        d = DalvikVMFormat(a.get_dex())
        dx = Analysis(d)
        vm = dvm.DalvikVMFormat(a.get_dex())
        vmx = analysis.Analysis(vm)
        d.set_vmanalysis(dx)
        d.set_decompiler(DecompilerDAD(d, dx))
    except Exception as e:
        print e
        return None

    result['android_version_code'] = a.get_androidversion_code()
    result['android_version_name'] = a.get_androidversion_name()
    result['max_sdk'] = a.get_max_sdk_version()
    result['min_sdk'] = a.get_min_sdk_version()
    result['libraries'] = a.get_libraries()
    result['filename'] = a.get_filename()
    result['target_sdk'] = a.get_target_sdk_version()
    result['md5'] = hashlib.md5(a.get_raw()).hexdigest()
    result['sha256'] = hashlib.sha256(a.get_raw()).hexdigest()
    result['permissions'] = a.get_permissions()
    result['activities'] = a.get_activities()
    result['providers'] = a.get_providers()
    result['services'] = a.get_services()
    result['strings'] = d.get_strings()
    result['class_names'] = [c.get_name() for c in d.get_classes()]
    result['method_names'] = [m.get_name() for m in d.get_methods()]
    result['field_names'] = [f.get_name() for f in d.get_fields()]
    # result['is_native_code'] = 1 if analysis.is_native_code(dx) else 0
    result['is_obfuscation'] = 1 if analysis.is_ascii_obfuscation(d) else 0
    # result['is_crypto_code'] = 1 if analysis.is_crypto_code(dx) else 0
    # result['is_dyn_code'] = 1 if analysis.is_dyn_code(dx) else 0
    # result['is_reflection_code'] = 1 if analysis.is_reflection_code(vmx) else 0
    result['is_database'] = 1 if d.get_regex_strings(DB_REGEX) else 0

    s_list = []
    s_list.extend(result['class_names'])
    s_list.extend(result['method_names'])
    s_list.extend(result['field_names'])
    result['entropy_rate'] = entropy_rate(s_list)

    result['feature_vectors'] = {}

    result['feature_vectors']['api_calls'] = []
    for call in API_CALLS:
        status = 1 if dx.get_method_by_name(".", call, ".") else 0
        result['feature_vectors']['api_calls'].append(status)

    result['feature_vectors']['permissions'] = []
    for permission in PERMISSIONS:
        status = 1 if permission in result['permissions'] else 0
        result['feature_vectors']['permissions'].append(status)

    result['feature_vectors']['special_strings'] = []
    for word in SPECIAL_STRINGS:
        status = 1 if d.get_regex_strings(word) else 0
        result['feature_vectors']['special_strings'].append(status)

    result['feature_vectors']['others'] = [
        # result['is_reflection_code'],
        # result['is_crypto_code'],
        # result['is_native_code'],
        result['is_obfuscation'],
        result['is_database'],
        # result['is_dyn_code']
    ]

    return result
示例#21
0
class FCG():  ##/////////////Changed for testing/////////////////////
    def __init__(self, filename):
        self.filename = filename
        # print(os.path.exists(filename))
        # a,d,dx = AnalyzeAPK(filename)
        # print(dx.get_call_graph())

        try:
            self.a = APK(filename)
            self.d = DalvikVMFormat(self.a.get_dex())
            self.d.create_python_export()
            self.dx = Analysis(self.d)
        except zipfile.BadZipfile:
            # if file is not an APK, may be a dex object
            _, self.d, self.dx = AnalyzeDex(self.filename)

        self.d.set_vmanalysis(self.dx)
        self.dx.create_xref()
        self.fcg = self.build_fcg()

    def get_fcg(self):
        return self.fcg

    def get_lock_graph(self):
        graph_list = []
        # print("LockGraphs", self.dx)
        call_graph = self.dx.get_call_graph()
        # print("Call Graphs")
        for m in (self.dx.find_methods(
                classname='Landroid.os.PowerManager.WakeLock'
        )):  ##//////////Work fine but found 3 method so will use when done
            # print("Method=", m.get_method())
            ancestors = nx.ancestors(call_graph, m.get_method())
            ancestors.add(m.get_method())
            graph = call_graph.subgraph(ancestors)
            graph_list.append(graph)
        wake_graph = nx.compose_all(graph_list)
        return wake_graph

    def build_fcg(self):
        """ Using NX and Androguard, build a directed graph NX object so that:
            - node names are analysis.MethodClassAnalysis objects
            - each node has a label that encodes the method behavior
        """
        fcg = self.get_lock_graph()  ##/////////My changes///////////////

        for n in fcg.nodes:
            instructions = []
            try:
                ops = n.get_instructions()
                for i in ops:
                    instructions.append(i.get_name())
                encoded_label = self.color_instructions(instructions)
            except AttributeError:
                encoded_label = np.array([0] * 15)

            fcg.node[n]["label"] = encoded_label
        return fcg

    def color_instructions(self, instructions):
        """ Node label based on coloring technique by Kruegel """

        h = [0] * len(INSTRUCTION_CLASS_COLOR)
        for i in instructions:
            h[INSTRUCTION_SET_COLOR[i]] = 1
        return np.array(h)

    def get_classes_from_label(self, label):
        classes = [
            INSTRUCTION_CLASSES[i] for i in range(len(label)) if label[i] == 1
        ]
        return classes
示例#22
0
def analyze_dex(filepath_or_raw,
                needs_dalvik_vm_format=True,
                needs_vm_analysis=True,
                needs_gvm_analysis=True,
                needs_xref=True,
                needs_dref=True,
                raw=False,
                decompiler="dad"):
    '''
    Open the classes.dex file `needs_dalvik_vm_format`
    and set up an analyzer for it `needs_vm_analysis`.

    Parameters
    ----------
    filepath_or_raw : path to file or raw data
         Set raw to True if `filepath_or_raw` is raw data.
    needs_dalvik_vm_format : bool, optional (default is True)
    needs_vm_analysis : bool, optional (default is True)
    needs_gvm_analysis : bool, optional (default is True)
    needs_xref : bool, optional (default is True)
    needs_dref : bool, optional (default is True)
    raw : bool, optional (default is False)
    decompiler : str, optional (default is "dad")

    Returns
    -------
    tuple<DalvikVMFormat, VMAnalysis, GVMAnalysis>

    Raises
    ------
    DexError
        If an error occurred while creating the analysis objects.
    '''

    dalvik_vm_format, vm_analysis, gvm_analysis = None, None, None
    # every requirement implies the need for the `dalvik_vm_format`
    needs_dalvik_vm_format = any((needs_dalvik_vm_format, needs_vm_analysis,
                                  needs_gvm_analysis, needs_xref, needs_dref))
    cross_ref = any((needs_xref, needs_dref))

    try:
        if needs_dalvik_vm_format:
            if raw == False:
                with open(filepath_or_raw, "rb") as f:
                    dalvik_vm_format = DalvikVMFormat(f.read())
            else:
                dalvik_vm_format = DalvikVMFormat(filepath_or_raw)

            if needs_vm_analysis or cross_ref or needs_gvm_analysis:
                vm_analysis = uVMAnalysis(dalvik_vm_format)
                dalvik_vm_format.set_vmanalysis(vm_analysis)

            if needs_gvm_analysis or cross_ref:
                gvm_analysis = GVMAnalysis(vm_analysis, None)
                dalvik_vm_format.set_gvmanalysis(gvm_analysis)

            if dalvik_vm_format:
                RunDecompiler(dalvik_vm_format, vm_analysis, decompiler)

            # create references, gvm_analysis needed!
            # we optimize through not exporting the references into the python objects
            if needs_xref:
                dalvik_vm_format.create_xref(python_export=False)
            if needs_dref:
                dalvik_vm_format.create_dref(python_export=False)

    except Exception as e:
        # androguard caused error -> propagate as DexError
        raise DexError(caused_by=e), None, sys.exc_info()[2]

    return dalvik_vm_format, vm_analysis, gvm_analysis
示例#23
0
def extract_features(file_path):
    result = {}
    try:
        a = APK(file_path)
        d = DalvikVMFormat(a.get_dex())
        dx = VMAnalysis(d)
        vm = dvm.DalvikVMFormat(a.get_dex())
        vmx = analysis.uVMAnalysis(vm)
        d.set_vmanalysis(dx)
        d.set_decompiler(DecompilerDAD(d, dx))
    except:
        return None

    result['android_version_code'] = a.get_androidversion_code()
    result['android_version_name'] = a.get_androidversion_name()
    result['max_sdk'] = a.get_max_sdk_version()
    result['min_sdk'] = a.get_min_sdk_version()
    result['libraries'] = a.get_libraries()
    result['filename'] = a.get_filename()
    result['target_sdk'] = a.get_target_sdk_version()
    result['md5'] = hashlib.md5(a.get_raw()).hexdigest()
    result['sha256'] = hashlib.sha256(a.get_raw()).hexdigest()
    result['permissions'] = a.get_permissions()
    result['activities'] = a.get_activities()
    result['providers'] = a.get_providers()
    result['services'] = a.get_services()
    #result['strings'] = d.get_strings()
    #result['class_names'] = [c.get_name() for c in d.get_classes()]
    #result['method_names'] = [m.get_name() for m in d.get_methods()]
    #result['field_names'] = [f.get_name() for f in d.get_fields()]
    class_names = [c.get_name() for c in d.get_classes()]
    method_names = [m.get_name() for m in d.get_methods()]
    field_names = [ f.get_name() for f in d.get_fields()]

    result['is_native_code'] = 1 if analysis.is_native_code(dx) else 0
    result['is_obfuscation'] = 1 if analysis.is_ascii_obfuscation(d) else 0
    result['is_crypto_code'] = 1 if analysis.is_crypto_code(dx) else 0
    result['is_dyn_code'] = 1 if analysis.is_dyn_code(dx) else 0
    result['is_reflection_code'] = 1 if analysis.is_reflection_code(vmx) else 0
    result['is_database'] = 1 if d.get_regex_strings(DB_REGEX) else 0

    s_list = []
    #s_list.extend(result['class_names'])
    #s_list.extend(result['method_names'])
    #s_list.extend(result['field_names'])
    s_list.extend(class_names)
    s_list.extend(method_names)
    s_list.extend(method_names)
    result['entropy_rate'] = entropy_rate(s_list)

    result['feature_vectors'] = {}

    # Search for the presence of api calls in a given apk
    result['feature_vectors']['api_calls'] = []
    for call in API_CALLS:
        status = 1 if dx.tainted_packages.search_methods(".", call, ".") else 0
        result['feature_vectors']['api_calls'].append(status)

    # Search for the presence of permissions in a given apk        
    result['feature_vectors']['permissions'] = []
    for permission in PERMISSIONS:
        status = 1 if permission in result['permissions'] else 0
        result['feature_vectors']['permissions'].append(status)

    result['feature_vectors']['special_strings'] = []
    for word in SPECIAL_STRINGS:
        status = 1 if d.get_regex_strings(word) else 0
        result['feature_vectors']['special_strings'].append(status)

    opt_seq = []
    for m in d.get_methods():
        for i in m.get_instructions():
            opt_seq.append(i.get_name())

    optngramlist = [tuple(opt_seq[i:i+NGRAM]) for i in xrange(len(opt_seq) - NGRAM)]
    optngram = Counter(optngramlist)
    optcodes = dict()
    tmpCodes = dict(optngram)
    #for k,v in optngram.iteritems():
    #    if v>=NGRAM_THRE:
            #optcodes[str(k)] = v
    #        optcodes[str(k)] = 1
    tmpCodes = sorted(tmpCodes.items(),key =lambda d:d[1],reverse=True) 
    for value in tmpCodes[:NGRAM_THRE]:
        optcodes[str(value[0])] = 1
    result['feature_vectors']['opt_codes'] = optcodes

    return result
示例#24
0
from androguard.core.bytecodes.apk import APK
from androguard.core.bytecodes.dvm import DalvikVMFormat
from androguard.core.bytecodes.dvm import ClassDefItem

a = APK("C:/Users/jysrm/OneDrive/바탕 화면/study/test.apk")
f = open("new.txt", 'w')

d = DalvikVMFormat(a)

code_item = d.get_codes_item()

code = code_item.show()

f.write(code)

f.close()
示例#25
0
class MyAPK:
    def __init__(self,
                 name_file,
                 conf,
                 file_log,
                 tag,
                 string_to_find,
                 logger,
                 api_monitor_dict=None,
                 network_dict=None,
                 dynamic_time=0,
                 use_smaliparser=True):

        self.name_apk = name_file
        self.name_only_apk = self.name_apk.split("/")[-1].rsplit(".", 1)[0]
        self.conf = conf
        self.apk = APK(name_file)
        self.app_name = self.apk.get_app_name()
        self.package_name = self.apk.get_package()
        self.target_sdk = self.apk.get_target_sdk_version()
        self.dalviks_format = None
        self.analysis_object = None
        self.dict_file_with_string = dict(
        )  # file che contengono la stringa ricercata
        self.string_to_find = string_to_find  # stringa da cercare
        self.is_contain_permission = False  # se contiene i permessi del file conf
        self.url_loaded = list()  # list url that has been loaded
        # se contiene i file ibridi --> probabilmente app ibrida
        self.is_contain_file_hybrid = False
        # pagine_html con iframe se contengono csp [True o False]
        self.find_csp = dict()
        # se contiene i metodi all'interno del file conf.json
        self.is_contains_all_methods = False
        self.zip = zipfile.ZipFile(self.name_apk)  # get zip object from apk
        self.list_file = self.zip.namelist()  # tutti i file all'interno
        self.html_file = FileAnalysis.find_html_file(self.list_file)
        self.file_log = file_log  # name to file log
        self.javascript_enabled = False
        self.internet_enabled = False
        self.file_vulnerable_frame_confusion = list()
        self.file_with_string_iframe = list()
        self.isHybrid = None
        # dict indexes with name method and get encoded methods where function was called
        self.method = dict()
        self.all_url = list()  # all url in the apk
        self.file_download_to_analyze = dict()
        self.search_tag = tag
        self.md5_file_to_url = dict(
        )  # dict with indexes with name and get url remote
        self.file_config_hybrid = None
        self.list_origin_access = list()
        self.logger = logger
        self.api_monitor_dict = api_monitor_dict
        self.network_dict = network_dict
        self.file_hybrid = list()
        self.javascript_interface = False
        self.javascript_file = FileAnalysis.find_js_file(self.list_file)
        self.src_iframe = dict()
        self.page_xss_vuln = dict()
        self.is_vulnerable_frame_confusion = False
        self.http_connection = list()
        self.http_connection_static = list()
        self.all_http_connection = list()
        self.url_dynamic = list()
        self.use_smaliparser = use_smaliparser
        self.use_analyze = not use_smaliparser
        self.method_2_value = dict()
        self.dynamic_javascript_enabled = False
        self.analysis_dynamic_done = api_monitor_dict is not None or network_dict is not None
        self.dynamic_javascript_interface = False
        self.dynamic_time = dynamic_time  # time execution analysis dynamic
        self.all_url_dynamic = list()
        self.load_url_dynamic = list()
        self.app_use_sandbox = False
        self.file_with_sandbox = dict()  # app use sandbox

    def read(self, filename, binary=True):
        with open(filename, 'rb' if binary else 'r') as f:
            return f.read()

    def check_permission(self, list_permission_to_find):
        """
            check permission hybrid app
        """
        use_permission_checker = True
        if not use_permission_checker:
            permission_find = list()
            for permission_to_check in list_permission_to_find:
                if permission_to_check in self.apk.get_permissions():
                    permission_find.append(True)  # contenere tutti i permessi
                    if permission_to_check == "android.permission.INTERNET":
                        self.internet_enabled = True

            # print(permission_to_check)
            self.logger.logger.info("[Permission declared Start]")
            for p in self.apk.get_permissions():
                self.logger.logger.info(p)
            self.logger.logger.info("[Permission End]\n")

            self.is_contain_permission = len(permission_find) == len(
                list_permission_to_find)
        else:

            if "PermissionChecker.jar" in os.listdir("."):
                dir_permission_checker = "PermissionChecker.jar"
            else:
                dir_permission_checker = os.path.join("FCDroid",
                                                      "PermissionChecker.jar")
            try:
                cmd_permission_checker = [
                    "java", "-jar", dir_permission_checker, self.name_apk
                ]
                process = subprocess.Popen(cmd_permission_checker,
                                           stdout=subprocess.PIPE)
                result = process.communicate()[0]
                # error here
                result = json.loads(result)
                # requiredAndUsed = result['requiredAndUsed']

                notRequiredButUsed = result['notRequiredButUsed']
                declared = result['declared']
                # requiredButNotUsed = result['requiredButNotUsed']
                list_permission = list(set().union(notRequiredButUsed,
                                                   declared))
                permission_find = list()
                for permission_to_check in list_permission_to_find:
                    if permission_to_check in list_permission:
                        permission_find.append(
                            True)  # contenere tutti i permessi
                        if permission_to_check == "android.permission.INTERNET":
                            self.internet_enabled = True

                self.logger.logger.info(
                    "[Permission declared and not required but used Start]")
                for p in list_permission:
                    self.logger.logger.info(p)
                self.logger.logger.info("[Permission End]\n")

                self.is_contain_permission = len(permission_find) == len(
                    list_permission_to_find)

            except Exception as e:
                permission_find = list()
                for permission_to_check in list_permission_to_find:
                    if permission_to_check in self.apk.get_permissions():
                        permission_find.append(
                            True)  # contenere tutti i permessi
                        if permission_to_check == "android.permission.INTERNET":
                            self.internet_enabled = True

                # print(permission_to_check)
                self.logger.logger.info("[Permission declared Start]")
                for p in self.apk.get_permissions():
                    self.logger.logger.info(p)
                self.logger.logger.info("[Permission End]\n")

                self.is_contain_permission = len(permission_find) == len(
                    list_permission_to_find)

    def is_hybird(self):
        """
            function to check se apk is hybrid,
            1) if contain file from conf.json (cordova/plugin/phonegap/config)
            2) if present permission internet (inutile)
        """
        if self.isHybrid is None:
            list_file_to_find = self.conf["file_to_check"]
            list_permission_to_find = self.conf["permissions_to_check"]

            self.is_contain_file_hybrid, self.file_hybrid = FileAnalysis.check_file_hybrid(
                self.list_file, list_file_to_find)

            if self.is_contain_file_hybrid:
                self.logger.logger.info("Hybrid file found are: " +
                                        str(self.file_hybrid))

            self.check_permission(list_permission_to_find)

            self.isHybrid = self.is_contain_permission and self.is_contain_file_hybrid

            # using apktool
            FNULL = open(os.devnull, 'w')
            print(bcolors.WARNING + "[*] Starting apktool " + bcolors.ENDC)
            self.logger.logger.info("Starting apktool")
            cmd = [
                "apktool", "d", "-o", "temp_dir_" + self.name_only_apk,
                self.name_apk, "-f"
            ]
            subprocess.call(cmd, stdout=FNULL, stderr=subprocess.STDOUT)

            try:
                if self.isHybrid:
                    # now can search file in temp_dir
                    if os.path.exists("temp_dir_{0}/res/xml/config.xml".format(
                            self.name_only_apk)):
                        file_xml = open(
                            "temp_dir_{0}/res/xml/config.xml".format(
                                self.name_only_apk))
                        file_data_xml = str(file_xml.read())
                        self.file_config_hybrid = file_data_xml
                        # parsing file config
                        self.check_whitelist()

            except OSError as e:
                print(
                    bcolors.FAIL +
                    "File config.xml not found, it is necessary to decompile the application first"
                    + bcolors.ENDC)
                # remove dir
                self.logger.logger.error(
                    "[ERROR file config.xmls] {0} \n".format(e))

        return self.isHybrid

    def check_whitelist(self):
        """
            function that obtain access origin from file 
            config.xml
        """

        # get xml_object ElementTree
        if self.file_config_hybrid is not None and self.isHybrid:
            self.list_origin_access = list()
            root = ET.fromstring(self.file_config_hybrid)

            xmlns = "{http://www.w3.org/ns/widgets}"  # default namespace

            # TODO aggiungere altri elementi della whitelist
            # 1) <allow-navigation href="http://*/*" />
            # Controls which URLs the WebView itself can be navigated to. Applies to top-level navigations only.
            # 2) <allow-intent href="http://*/*" />
            # Controls which URLs the app is allowed to ask the system to open. By default, no external URLs are allowed
            # 3) <access origin="http://google.com" />
            # Controls which network requests (images, XHRs, etc) are allowed to be made (via cordova native hooks).

            for child in root.findall(xmlns + "access"):
                # print( child.tag, child.attrib.get("origin"))
                self.list_origin_access.append(child.attrib.get("origin"))

            self.logger.logger.info("[INIT ACCESS ORIGIN LIST]")
            for value in self.list_origin_access:
                self.logger.logger.info("origin: %s", value)
            self.logger.logger.info("[END ACCESS ORIGIN LIST]\n")

    def analyze_xss_dom(self, file_name, file_content):
        """ 
            search static dom xss based on regex
        """
        # TODO se file_name end with js use TaintJS altrimenti usare questo
        # per usare taint js salvare il contenuto in una dir temporanea e usarlo
        # da li dentro
        try:
            print("file xss dom analyze {0}".format(file_name))

            if file_name.endswith(".js"):
                file_open_temp = "FCDroid/TaintJS/temp_file_to_analyze.js"
                file_to_write = open(file_open_temp, "w")
                file_to_write.write(file_content)
                file_to_write.close()
                cmd_node = [
                    "node", "--max-old-space-size=4096",
                    "FCDroid/TaintJS/app.js", file_open_temp
                ]
                process = subprocess.Popen(cmd_node,
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE)
                out, err = process.communicate()
                out = out.decode('utf-8').strip()
                err = err.decode('utf-8')
                os.remove(file_open_temp)
                # no error
                if err != '':  # no error
                    if out == 'true':  # is vuln
                        self.page_xss_vuln[file_name] = True
                else:

                    page_analyze = XSScanner(file_name, file_content)
                    page_analyze.analyze_page()
                    if len(page_analyze.sink) > 0 or len(
                            page_analyze.source) > 0:
                        self.page_xss_vuln[file_name] = page_analyze
            else:
                soup = BeautifulSoup(file_content, 'html.parser')
                scripts = soup.find_all("script")
                for script in scripts:
                    value = script.get_text().strip()
                    file_open_temp = "FCDroid/TaintJS/temp_file_to_analyze.js"
                    file_to_write = open(file_open_temp, "w")
                    file_to_write.write(value)
                    file_to_write.close()
                    cmd_node = [
                        "node", "--max-old-space-size=4096",
                        "FCDroid/TaintJS/app.js", file_open_temp
                    ]
                    process = subprocess.Popen(cmd_node,
                                               stdout=subprocess.PIPE,
                                               stderr=subprocess.PIPE)
                    out, err = process.communicate()
                    out = out.decode('utf-8').strip()
                    err = err.decode('utf-8')
                    os.remove(file_open_temp)
                    # no error
                    if err != '':  # no error
                        if out == 'true':  # is vuln
                            self.page_xss_vuln[file_name] = True
                    else:

                        page_analyze = XSScanner(file_name, file_content)
                        page_analyze.analyze_page()
                        if len(page_analyze.sink) > 0 or len(
                                page_analyze.source) > 0:
                            self.page_xss_vuln[file_name] = page_analyze
        except Exception:

            page_analyze = XSScanner(file_name, file_content)
            page_analyze.analyze_page()
            if len(page_analyze.sink) > 0 or len(page_analyze.source) > 0:
                self.page_xss_vuln[file_name] = page_analyze

    def find_string(self, file_to_search, remote=False, debug=False):
        """
            find string inside file of apk(html,xml,ecc..) (not yet decompiled)
        """
        debug = True
        # print(self.md5_file_to_url.keys())
        if remote:
            self.logger.logger.info("[START REMOTE FILE ANALYZE]")
        else:
            self.logger.logger.info("[START FILE ANALYZE]")
        for file_to_inspect, insideAPK in file_to_search.items():
            if not remote and debug:
                self.logger.logger.info("File: " + file_to_inspect)
            else:
                if debug:
                    try:
                        m = hashlib.md5()
                        m.update(file_to_inspect.encode('utf-8'))
                        self.logger.logger.info(
                            "Remote File in: {0}".format(file_to_inspect))

                        if m.hexdigest() in self.md5_file_to_url.keys():
                            self.logger.logger.info("URL: {0}".format(
                                self.md5_file_to_url[str(m.hexdigest())]))

                    except KeyError as e:
                        self.logger.logger.warning(
                            "Key error as {0} ".format(e))

            file_to_inspect_split = file_to_inspect.split(
                "?", 1)[0]  # remove parameter

            if remote and not (file_to_inspect_split.endswith(".js")
                               or file_to_inspect_split.endswith(".html")):
                # add extension html on file
                # of default wget add this extension
                file_to_inspect = file_to_inspect + ".html"

            if insideAPK:
                data = self.zip.open(file_to_inspect)
            else:
                data = open(file_to_inspect, "r")

            #######################################################################################################
            # start xss analysis on this file
            try:

                content_file = data.read()
                thread = threading.Thread(name="xss_" + file_to_inspect,
                                          target=self.analyze_xss_dom,
                                          args=(
                                              file_to_inspect,
                                              str(content_file),
                                          ))
                thread.start()
                #######################################################################################################

                file_read = str(content_file)
                soup = BeautifulSoup(file_read, 'lxml')
                try:

                    find_iframe, list_row_string, list_src_iframe, find_string_not_tag, file_with_sandbox = FileAnalysis.find_string(
                        self.string_to_find, self.search_tag, file_to_inspect,
                        file_read, soup, self.logger)

                    self.file_with_sandbox = {
                        **self.file_with_sandbox,
                        **file_with_sandbox
                    }  # merge dict

                    #######################################################################################################
                    # TODO insert in method --> String Analysis
                    if find_iframe and self.string_to_find == "iframe":
                        if not find_string_not_tag:
                            self.dict_file_with_string[
                                file_to_inspect] = list_row_string
                            self.src_iframe[file_to_inspect] = list_src_iframe

                        # TODO search id iframe in file js in script src
                        if not self.search_tag or file_to_inspect_split.endswith(
                                ".js") or find_string_not_tag:
                            self.file_with_string_iframe.append(
                                file_to_inspect)  # append file with iframe
                            print(bcolors.FAIL + "Found " +
                                  self.string_to_find + " in line " +
                                  str(list_row_string) + bcolors.ENDC)
                            self.logger.logger.info(
                                "Found  %s file %s in line %s",
                                self.string_to_find, file_to_inspect,
                                str(list_row_string))

                        else:
                            print(bcolors.FAIL + "Found tag " +
                                  self.string_to_find + ",  " +
                                  str(len(list_row_string)) + " times " +
                                  bcolors.ENDC)
                            self.logger.logger.info(
                                "Found in file %s tag %s , %s times",
                                file_to_inspect, self.string_to_find,
                                str(len(list_row_string)))

                            if len(self.src_iframe[file_to_inspect]) > 0:
                                self.logger.logger.info(
                                    "Founded this src {0} in iframe tag inside file {1}"
                                    .format(
                                        str(self.src_iframe[file_to_inspect]),
                                        file_to_inspect))

                            else:
                                self.logger.logger.info(
                                    "No src founded in iframe tag inside file {0}"
                                    .format(file_to_inspect))

                        #######################################################################################################

                        # TODO aggiungere il content e fare conclusioni su di esso e per i file JavaScript
                        find_csp = soup.find(
                            "meta", {"http-equiv": "Content-Security-Policy"})
                        if find_csp is not None:
                            print(bcolors.OKGREEN +
                                  "Find CSP with content: [" +
                                  find_csp["content"] + "]" + bcolors.ENDC)
                            self.logger.logger.info(
                                "Find CSP with content: [" +
                                find_csp["content"] + "]")
                            self.find_csp[file_to_inspect] = True

                        # only file html
                        elif not file_to_inspect_split.endswith(".js"):
                            print(bcolors.FAIL + "No CSP found!" +
                                  bcolors.ENDC)
                            self.logger.logger.info("No CSP found!")
                            self.find_csp[file_to_inspect] = False
                        elif file_to_inspect_split.endswith(".js"):
                            print(bcolors.FAIL +
                                  "It is a JS file, no CSP found!" +
                                  bcolors.ENDC)
                            self.logger.logger.info(
                                "It is a JS file, no CSP found!, investigate manually\n"
                            )
                            self.find_csp[file_to_inspect] = False

                    else:
                        print(bcolors.OKGREEN + "No " + self.string_to_find +
                              " in " + file_to_inspect + bcolors.ENDC)
                        self.logger.logger.info("No " + self.string_to_find +
                                                " in " + file_to_inspect +
                                                "\n")

                except zipfile.BadZipfile as e:
                    self.logger.error("Error bad zip file {0}".format(e))
                    continue
                except ValueError as e:
                    self.logger.error("Error value error {0}".format(e))
                    continue
            except UnicodeDecodeError as e:
                self.logger.logger.error("Error unicode error {0}".format(e))
                continue
        self.logger.logger.info("[END ANALYZE FILE]")
        return None

    def find_method_used(self):
        """
            funzione per ricercare i metodi che sono usati 
            all'interno dell'apk, tanto lenta
        """
        used_jadx = False
        if used_jadx:

            # Create DalvikVMFormat Object
            self.dalvik_format = DalvikVMFormat(self.apk)
            # Create Analysis Object
            self.analysis_object = Analysis(self.dalvik_format)
            # Load the decompiler
            # Make sure that the jadx executable is found in $PATH
            # or use the argument jadx="/path/to/jadx" to point to the executable
            decompiler = DecompilerJADX(self.dalvik_format,
                                        self.analysis_object)

            # propagate decompiler and analysis back to DalvikVMFormat
            self.dalvik_format.set_decompiler(decompiler)
            self.dalvik_format.set_vmanalysis(self.analysis_object)

            # Now you can do stuff like:
            list_method_analysis = self.analysis_object.get_methods()
            for method_analys in list_method_analysis:
                method_name = method_analys.get_method().get_name()
                # print(method_encoded.get_method().get_source())
                self.method[method_name] = list(method_analys.get_xref_from())

        elif self.use_analyze:
            # return apk, list dex , object analysis
            apk, self.dalvik_format, self.analysis_object = AnalyzeAPK(
                self.name_apk)

            for method_analys in self.analysis_object.get_methods():
                method_name = method_analys.get_method().get_name()
                # from method_name get list dove esso viene chiamato
                self.method[method_name] = list(method_analys.get_xref_from())

        elif self.use_smaliparser:
            # use smali parser, apktool and grep invece di Androguard
            dir_apk_tool = "temp_dir_" + self.name_only_apk + "/"
            list_method_to_analyze = self.conf["method_smali_parser"]
            self.method_2_value, self.all_url = smaliparser.start(
                dir_apk_tool, list_method_to_analyze)

        else:  # TODO to make faster analysis but not work well
            self.dalvik_format = DalvikVMFormat(self.apk)
            for encoded_method in self.dalvik_format.get_methods():
                method_analysis = MethodClassAnalysis(encoded_method)

                method_name = method_analysis.get_method().get_name()
                # print(method_name)
                # from method_name get list dove esso viene chiamato
                self.method[method_name] = list(
                    method_analysis.get_xref_from())
                # print(self.method[method_name])

    def check_method_conf(self):
        """
            function to check se methods inside conf.json method_to_check is used inside apk
        """

        method_to_find = self.conf["method_to_check"]
        method_present = dict()

        try:

            if self.use_smaliparser:
                if "setJavaScriptEnabled" in self.method_2_value.keys():
                    if "0x1" in self.method_2_value["setJavaScriptEnabled"]:
                        self.javascript_enabled = True
                        method_present["setJavaScriptEnabled"] = True
                if "addJavascriptInterface" in self.method_2_value.keys():
                    self.javascript_interface = True
                    method_present["addJavascriptInterface"] = True

            else:
                for mf in method_to_find:
                    method_present[mf] = False
                    for mapk in self.method.keys():
                        if mf in mapk:
                            method_present[mf] = True

                if method_present["setJavaScriptEnabled"]:
                    for value in self.method["setJavaScriptEnabled"]:
                        try:
                            if value[1] is not None:
                                encoded_method = value[1]
                                source_code = FileAnalysis.get_list_source_code(
                                    encoded_method)
                                if FileAnalysis.check_method_used_value(
                                        source_code, "setJavaScriptEnabled",
                                        "1"):
                                    # volendo si possono memorizzare tutti i file che lo settano atrue
                                    self.javascript_enabled = True
                                    break

                        except (TypeError, AttributeError, KeyError) as e:
                            self.logger.logger.error(
                                "Exception during check method used {0}".
                                format(e))
                            continue
            print()
            if self.dynamic_javascript_enabled:
                self.logger.logger.info(
                    "[JavaScript enabled (check dynamically) :" +
                    str(self.dynamic_javascript_enabled) + "]")
            else:
                self.logger.logger.info(
                    "[JavaScript enabled (check static):  " +
                    str(self.javascript_enabled) + "]")

        except Exception as e:
            self.logger.logger.error(
                "File conf.json without method setJavaScriptEnabled {0}".
                format(e))

        try:
            if not self.use_smaliparser:

                if self.dynamic_javascript_interface:

                    self.logger.logger.info(
                        "[Add interface WebView (check dynamically): " +
                        str(self.dynamic_javascript_interface) + "]")
                    self.javascript_interface = self.dynamic_javascript_interface

                else:

                    self.logger.logger.info(
                        "[Add interface WebView (check static): " +
                        str(method_present["addJavascriptInterface"]) + "]")
                    self.javascript_interface = method_present[
                        "addJavascriptInterface"]

            else:

                if self.dynamic_javascript_interface:
                    method_present[
                        "addJavascriptInterface"] = self.dynamic_javascript_interface
                    self.logger.logger.info(
                        "[Add interface WebView (check dynamically): " +
                        str(self.dynamic_javascript_interface) + "]")

                else:
                    method_present[
                        "addJavascriptInterface"] = self.javascript_interface
                    self.logger.logger.info(
                        "[Add interface WebView (check static): " +
                        str(self.javascript_interface) + "]")

        except Exception as e:
            # nothing
            self.logger.logger.error(
                "File conf.json without method addJavascriptInterface {0}\n".
                format(e))

        self.is_contains_all_methods = len(method_present) == len(
            method_to_find)
        return self.is_contains_all_methods

    def find_url_in_apk(self):
        """
            find all url/uri inside apk
        """

        # add url using dynamic analysis
        if self.api_monitor_dict is not None and self.network_dict is not None:
            self.add_url_dynamic()

        ##############################################################################
        # use smali_parser
        if self.use_smaliparser:
            # add url loaded for smali_parsr
            if "loadUrl" in self.method_2_value.keys():
                all_url_loaded = self.method_2_value["loadUrl"]

                # da queste devo filtrare ottenendo solo quelle http/https
                temp_url_loaded = list(
                    filter(
                        lambda x: x is not None and
                        (x.startswith("http") or x.startswith("https")),
                        all_url_loaded))
                self.url_loaded = list(set().union(self.url_loaded,
                                                   temp_url_loaded))

        else:
            # ALL string inside apk
            # use AndroGuard
            # url regularp expression
            # url_re = "(http:\/\/|https:\/\/|file:\/\/\/)?[-a-zA-Z0-9@:%._\+~#=]\.[a-z]([-a-zA-Z0-9@:%_\+.~#?&//=]*)"
            url_re = "^(http:\/\/|https:\/\/)\w+"
            list_string_analysis = list()  # list of string analysis object
            # se uso aalysis object
            if self.analysis_object is not None:
                list_string_analysis = self.analysis_object.find_strings(
                    url_re)  # --> gen object

            else:
                list_string = self.dalvik_format.get_regex_strings(url_re)

                # get all string inside apk
                for string_value in list_string:
                    list_string_analysis.append(StringAnalysis(string_value))

            ##################################################################################
            temp_string_value = list()
            # string- tuple with classAnalysis e encodeMethod that use the string
            dict_class_method_analysis = dict()
            for string_analysis in list_string_analysis:
                temp_string_value.append(
                    string_analysis.get_value())  # tutte le url
                dict_class_method_analysis[string_analysis.get_value()] = list(
                    string_analysis.get_xref_from()
                )  # url e relativo codice dove le ho trovate

            ##################################################################################
            # per ogni file, otteniamo una lista di  tupla
            # class analysis e encoded_method
            for key in dict_class_method_analysis.keys():
                for value in dict_class_method_analysis[key]:
                    # class_analysis = value[0]
                    try:
                        if value[1] is not None:
                            encoded_method = value[1]
                            # split the instruction in a list
                            source_code = FileAnalysis.get_list_source_code(
                                encoded_method)
                            if source_code is not None:
                                self.all_url.append(key)  # appendo l'url
                                if FileAnalysis.check_method_used_value(
                                        source_code, "loadUrl", key):
                                    self.url_loaded.append(
                                        key
                                    )  # appendo url se caricata dentro loadUrl

                    except (TypeError, AttributeError, KeyError) as e:
                        self.logger.logger.error(
                            "Exception during find url in apk {0}".format(e))
                        continue

        #######################################################################################################
        # debug part
        if len(self.url_loaded) > 0:
            # print(self.url_loaded)
            self.logger.logger.info(
                "[START URL LOADED INSIDE LOADURL FUNCTION]")
            self.url_loaded = list(set(self.url_loaded))
            for u in self.url_loaded:
                if u.startswith("http://"):
                    self.http_connection_static.append(u)
                self.logger.logger.info(
                    "Url inside load function: {0}".format(u))
            self.logger.logger.info("[END URL LOADED INSIDE LOADURL FUNCTION]")

            md5_file_to_url, file_download_to_analyze = utility.download_page_with_wget(
                self.name_only_apk, self.url_loaded)
            for key in md5_file_to_url.keys():
                if key not in self.md5_file_to_url.keys():
                    self.md5_file_to_url[key] = md5_file_to_url[key]

            for key in file_download_to_analyze.keys():
                if key not in self.file_download_to_analyze.keys():
                    self.file_download_to_analyze[
                        key] = file_download_to_analyze[key]

            # self.download_page_loaded_with_wget()
            self.find_string(self.file_download_to_analyze, remote=True)

        if len(self.all_url) > 0:
            self.all_url = list(set(self.all_url))
            self.logger.logger.info("[START ALL URL INSIDE APK]")
            for u in self.all_url:
                if u.startswith("http://"):
                    self.all_http_connection.append(u)
                self.logger.logger.info("Url inside apk {0}".format(u))
            self.logger.logger.info("[END ALL URL INSIDE APK]")

        html_dir = "temp_html_code/html_downloaded_{0}/".format(
            self.name_only_apk)

        # TODO eliminare
        save_page_html = False
        if os.path.exists(html_dir) and len(
                os.listdir(html_dir)) > 0 and save_page_html:
            # zip -r squash.zip dir1
            subprocess.call([
                "zip", "-r", "temp_html_code/html_{0}.zip".format(
                    self.name_only_apk), html_dir
            ],
                            stdout=subprocess.DEVNULL,
                            stderr=subprocess.DEVNULL)

        # delete dir o provare a zip
        subprocess.Popen(["rm", "-rf", html_dir],
                         stdout=subprocess.DEVNULL,
                         stderr=subprocess.DEVNULL)

    # check vulnerability
    def vulnerable_frame_confusion(self):
        """ 
            check if app is vulnerable on frame confusion
            1) iframe nella stringa di ricerca
            2) metodi addJavascriptInterface e setJavaScriptEnabled usati
            3) permesso internet
            4) almeno un file html con l'iframe all'interno e senza csp
        """

        # se esiste almeno un file con iframe senza csp --> vulnerble
        # se è false --> vulnerabile
        csp_in_file_iframe = True
        app_use_sandbox = True
        # print("File in dict_file_with_string: {}".format(self.dict_file_with_string.keys()))
        # print("File in find_csp: {}".format(self.find_csp.keys()))
        # print("File in file_with_sandbox: {}".format(self.file_with_sandbox.keys()))

        for file_with_iframe in self.dict_file_with_string.keys():
            csp_in_file_iframe = csp_in_file_iframe and self.find_csp[
                file_with_iframe]
            app_use_sandbox = app_use_sandbox and self.file_with_sandbox[
                file_with_iframe]

            if not self.find_csp[
                    file_with_iframe] or not self.file_with_sandbox[
                        file_with_iframe]:
                self.file_vulnerable_frame_confusion.append(file_with_iframe)

        # print("sandbox in app {}".format(self.app_use_sandbox))
        # se vero whitelist implementato male
        white_list_bug = len(
            self.list_origin_access) == 0 or "*" in self.list_origin_access
        self.is_vulnerable_frame_confusion = (
            "iframe" in self.string_to_find and self.check_method_conf()
            and (len(self.dict_file_with_string) > 0
                 or len(self.file_with_string_iframe) > 0)
            and self.is_contain_permission and not csp_in_file_iframe
            and white_list_bug and not self.app_use_sandbox)

    def add_url_dynamic(self):
        """
            function that aggiunge le url caricate 
            diamicamente attraverso che sono state trovate precendetemente 
            dall'analisi dinamica
        """

        #######################################################################################################
        function_load_url = ["loadUrl"]  # funzioni che caricano url in Android
        url_api_monitor = list()
        for keys in self.api_monitor_dict.keys():

            if keys in function_load_url:
                url_api_monitor = list(set().union(
                    url_api_monitor, self.api_monitor_dict[keys]["args"]))
            # dynamic interface and javascript enabled
            if keys == "addJavascriptInterface":
                self.dynamic_javascript_interface = True

            # TODO check --> considero javascriptenabled se ho solo l'interface abilitata
            if keys == "setJavaScriptEnabled" and True in self.api_monitor_dict[
                    keys]["args"]:
                self.dynamic_javascript_enabled = True

        # get all http/https/file in load function
        self.url_dynamic = filter(
            lambda x: x.startswith("http://") or x.startswith("https://") or x.
            startswith("file://"), url_api_monitor)

        self.load_url_dynamic = self.url_dynamic
        #######################################################################################################
        # TODO mettere la funzione evaluateJavaScript o loadUrl javascript: --> come se fosse un file javascript
        javascript_load_url = filter(lambda x: x.startswith("javascript:"),
                                     url_api_monitor)

        # method that exec js in recent api
        javascript_evaluate = list()
        method_evaluate_js = ["evaluateJavascript"]
        for keys in self.api_monitor_dict.keys():
            if keys in method_evaluate_js:
                javascript_evaluate = list(set().union(
                    javascript_evaluate, self.api_monitor_dict[keys]["args"]))

        # now write this code in a file and analyze them
        javascript_code_exec = list(set().union(javascript_load_url,
                                                javascript_evaluate))

        name_file = "code_js_loaded_"
        i = 1
        list_file_js_dynamic = dict()
        dir_write = os.path.join("temp_html_code",
                                 "html_downloaded_" + self.name_only_apk)

        if not os.path.isdir(dir_write):
            os.makedirs(dir_write)

        for code in javascript_code_exec:
            file_js = os.path.join(dir_write, name_file + "{0}.js".format(i))
            file = open(file_js, "w")
            file.write(code)
            file.close()
            list_file_js_dynamic[file_js] = False
            self.javascript_file[file_js] = False

        self.logger.logger.info("[Start javascript code dynamic]")
        self.find_string(list_file_js_dynamic)
        self.logger.logger.info("[End javascript code dynamic]\n")

        #######################################################################################################
        # TODO mettere metodi cordova

        #######################################################################################################
        # ora devo filtrare solo le url che sono http/https
        url_network = list()
        for keys in self.network_dict.keys():
            # TODO check
            url_list_new = list()
            for url in self.network_dict[keys]["url"]:
                # search ip
                ip = re.findall(r"[0-9]+(?:\.[0-9]+){3}", url)
                if ip != None and len(ip) > 0:
                    # change ip with host
                    # get only first element of every list --> every list are max 1 element
                    url_new = url.replace(ip[0],
                                          self.network_dict[keys]["host"][0])
                    url_list_new.append(url_new)
                else:
                    url_list_new.append(url)
            # add new url
            self.network_dict[keys]["url"] = url_list_new
            url_network = list(set().union(url_network,
                                           self.network_dict[keys]["url"]))

        ##########################################################################################################
        # remove url google
        # url effettivamente caricate nell'applicazione
        self.url_dynamic = list(set().union(self.url_dynamic, url_network))
        self.all_url_dynamic = self.url_dynamic
        url_dynamic_to_remove = list()
        for url_dyn in self.url_dynamic:
            for url_to_check in self.conf["url_to_remove"]:
                if url_to_check in url_dyn:
                    url_dynamic_to_remove.append(url_dyn)

        # TODO maybe to add
        url_dynamic_to_remove = list(set(url_dynamic_to_remove))
        for url_to_remove in url_dynamic_to_remove:
            self.url_dynamic.remove(url_to_remove)

        #######################################################################################################
        self.url_loaded = list(set().union(self.url_loaded, self.url_dynamic))

        self.all_url = list(set().union(self.all_url, self.url_loaded))
        self.logger.logger.info("[Init add url dynamic ]")
        for u in self.url_dynamic:
            if u.startswith("http://"):
                self.http_connection.append(u)
            if u in self.load_url_dynamic:
                self.logger.logger.info(
                    "Url dynamic inside loadUrl{0}".format(u))
            else:
                self.logger.logger.info("Url dynamic {0}".format(u))

        self.logger.logger.info("[End url dynamic]\n")
def get_apis(path):
    methods = set()
    error_file = open("error_files.txt", "w")

    """
    Get the APIs from an application.
    Parameters:
      path - The path of the application to be decompiled
    Returns:
      A sorted list of APIs with parameters
    """
    try:
        # You can see the documents of androguard to get the further details
        # of the decompilation procedures.
        # 获取APK文件对象
        # application:表示APK对象,在其中可以找到有关 APK 的信息,例如包名、权限、AndroidManifest.xml、resources
        # application_dex:DalvikVMFormat 对象数组,DalvikVMFormat 对应 apk 文件中的 dex 文件,从 dex 文件中我们可以获取类、方法和字符串。
        # application_x:表示 Analysis 对象,其包含链接了关于 classes.dex 信息的特殊的类,甚至可以一次处理许多 dex 文件。
        application = APK(path)
        application_dex = DalvikVMFormat(application.get_dex())
        application_x = Analysis(application_dex)

        # 获得class 对象
        classesList = [classes.get_name() for classes in application_dex.get_classes()]
        # print("classesList:", classesList)
        # 获得methods方法
        for method in application_dex.get_methods():
            methodAnalysis = application_x.get_method(method)
            if method.get_code() is None:
                continue

            for basicBlocks in methodAnalysis.get_basic_blocks().get():
                # 获得jvm指令
                for instructions in basicBlocks.get_instructions():
                    #  这是一个包含方法,变量或其他任何内容的字符串
                    output = instructions.get_output()
                    # print("output", output)

                    # Here we use regular expression to check if it is a function
                    # call. A function call comprises four parts: a class name, a
                    # function name, zero or more parameters, and a return type.
                    # The pattern is actually simple:
                    #
                    #      CLASS NAME: starts with a character L and ends in a right
                    #                  arrow.
                    #   FUNCTION NAME: starts with the right arrow and ends in a
                    #                  left parenthesis.
                    #      PARAMETERS: are between the parentheses.
                    #     RETURN TYPE: is the rest of the string.
                    #
                    # 这里拿到的classList是应用本身的类,第二个匹配的组(一个括号一个组)是调用的类不是应用本身的类,是系统的类
                    # 这里就是通过系统接口调用来做判断。
                    match = re.search(r'(L[^;]*;)->[^\(]*\([^\)]*\).*', output)
                    # print("----")
                    # if match:
                    #     log(match.group() + "----" + match.group(1), "->" + (match.group(1) not in classesList))
                    # print(match.group() + "----" + match.group(1), "->", (match.group(1) not in classesList))
                    # print("isInClassList:", match.group(1), "->", (match.group(1) not in classesList))

                    # match.group():Landroid/app/IntentService;-><init>(Ljava/lang/String;)V
                    # match.group(1):Landroid/app/IntentService;
                    if match and match.group(1) not in classesList:
                        # print(match.group() + "----" + match.group(1))
                        methods.add(match.group())
        methods = list(methods)

    except Exception as e:
        print(e)
        print("path", path)
        error_file.write(path)

    return methods
示例#27
0
        ):  # inserisce la virgola fin tanto che non � l'ultimo oggetto
            toReturn += ","

    #toReturn += "]\n}"
    toReturn += "]"
    return toReturn


# cattura del percorso del file apk
apkToBeAnalyzed = sys.argv[1]

#variabile che rappresenta il file apk
a = APK(apkToBeAnalyzed)

#variabile che rappresenta il file dex
dexFile = DalvikVMFormat(a.get_dex())

#variabile che rappresenta il file dex dopo essere stato analizzato
dexAnalyzed = analysis.uVMAnalysis(dexFile)

#print a.show()
#print "package name " + a.get_package()
#print a.get_permissions()
#analysis.show_Permissions(dexAnalyzed)
#print "\n"

# mostra dove vengono usati i permessi
permissions = dexAnalyzed.get_permissions([])

permissionDictionary = toDictionary(dexFile, permissions)
示例#28
0
from androguard.core.analysis.analysis import VMAnalysis
from androguard.core.bytecodes.apk import APK
from androguard.core.bytecodes.dvm import DalvikVMFormat
from core.analysis import *
if __name__ == '__main__':
    a = APK("1_1.apk")
    print len(a.get_activities())
    print a.get_main_activity()
    d = DalvikVMFormat(a.get_dex())
    dx = VMAnalysis(d)
    print dx.get_method_signature()
示例#29
0
    if apkf.get_element('activity', 'exported', name=activity) == 'true':
        exported_activities.append(activity)
    else:
        filters = apkf.get_intent_filters("activity", activity)
        if len(filters) > 0:
            exported_activities.append(activity)

for receiver in receivers:
    if apkf.get_element('receiver', 'exported', name=receiver) == 'true':
        exported_receivers.append(receiver)
    else:
        filters = apkf.get_intent_filters("receiver", receiver)
        if len(filters) > 0:
            exported_receivers.append(receiver)

dexf = DalvikVMFormat(apkf.get_dex())

for item in dexf.get_classes_def_item().get_obj():
    if "BroadcastReceiver" in str(item):
        dynamic_exported_receivers.append(item)

for service in services:
    if apkf.get_element('service', 'exported', name=service) == 'true':
        exported_services.append(service)
    else:
        filters = apkf.get_intent_filters("service", service)
        if len(filters) > 0:
            exported_services.append(service)

if int(apkf.get_target_sdk_version()) < 17:
    exported_providers = providers
示例#30
0
    def run(self):
        """Run androguard to extract static android information
                @return: list of static features
        """
        self.key = "apkinfo"
        apkinfo = {}

        if "file" not in self.task["category"]:
            return

        from androguard.core.bytecodes.apk import APK
        from androguard.core.bytecodes.dvm import DalvikVMFormat
        from androguard.core.analysis.analysis import uVMAnalysis
        from androguard.core.analysis import analysis

        f = File(self.task["target"])
        if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type():
            if not os.path.exists(self.file_path):
                raise CuckooProcessingError(
                    "Sample file doesn't exist: \"%s\"" % self.file_path)

            try:
                a = APK(self.file_path)
                if a.is_valid_APK():
                    manifest = {}
                    apkinfo["files"] = self._apk_files(a)
                    manifest["package"] = a.get_package()
                    # manifest["permissions"]=a.get_details_permissions_new()
                    manifest["main_activity"] = a.get_main_activity()
                    manifest["activities"] = a.get_activities()
                    manifest["services"] = a.get_services()
                    manifest["receivers"] = a.get_receivers()
                    # manifest["receivers_actions"]=a.get__extended_receivers()
                    manifest["providers"] = a.get_providers()
                    manifest["libraries"] = a.get_libraries()
                    apkinfo["manifest"] = manifest
                    # apkinfo["certificate"] = a.get_certificate()
                    static_calls = {}
                    if self.check_size(apkinfo["files"]):
                        vm = DalvikVMFormat(a.get_dex())
                        vmx = uVMAnalysis(vm)

                        static_calls["all_methods"] = self.get_methods(vmx)
                        static_calls[
                            "is_native_code"] = analysis.is_native_code(vmx)
                        static_calls["is_dynamic_code"] = analysis.is_dyn_code(
                            vmx)
                        static_calls[
                            "is_reflection_code"] = analysis.is_reflection_code(
                                vmx)

                        # static_calls["dynamic_method_calls"]= analysis.get_show_DynCode(vmx)
                        # static_calls["reflection_method_calls"]= analysis.get_show_ReflectionCode(vmx)
                        # static_calls["permissions_method_calls"]= analysis.get_show_Permissions(vmx)
                        # static_calls["crypto_method_calls"]= analysis.get_show_CryptoCode(vmx)
                        # static_calls["native_method_calls"]= analysis.get_show_NativeMethods(vmx)
                    else:
                        log.warning("Dex size bigger than: %s",
                                    self.options.decompilation_threshold)
                    apkinfo["static_method_calls"] = static_calls
            except (IOError, OSError, zipfile.BadZipfile) as e:
                raise CuckooProcessingError("Error opening file %s" % e)

        return apkinfo
示例#31
0
    def run(self):
        """Run androguard to extract static android information
                @return: list of static features
        """
        self.key = "apkinfo"
        apkinfo = {}

        if "file" not in self.task["category"] or not HAVE_ANDROGUARD:
            return

        f = File(self.task["target"])
        #if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type():
        if not os.path.exists(self.file_path):
            raise CuckooProcessingError("Sample file doesn't exist: \"%s\"" %
                                        self.file_path)

        try:
            a = APK(self.file_path)
            if a.is_valid_APK():
                manifest = {}

                apkinfo["files"] = self._apk_files(a)
                manifest["package"] = a.get_package()
                apkinfo["hidden_payload"] = []

                for file in apkinfo["files"]:
                    if self.file_type_check(file):
                        apkinfo["hidden_payload"].append(file)

                apkinfo["files_flaged"] = self.files_name_map

                manifest["permissions"] = get_permissions(a)
                manifest["main_activity"] = a.get_main_activity()
                manifest["activities"] = a.get_activities()
                manifest["services"] = a.get_services()
                manifest["receivers"] = a.get_receivers()
                manifest["receivers_actions"] = get_extended_receivers(a)
                manifest["providers"] = a.get_providers()
                manifest["libraries"] = list(a.get_libraries())
                apkinfo["manifest"] = manifest

                apkinfo["icon"] = get_apk_icon(self.file_path)
                certificate = get_certificate(self.file_path)
                if certificate:
                    apkinfo["certificate"] = certificate

                #vm = DalvikVMFormat(a.get_dex())
                #strings = vm.get_strings()
                strings = self._get_strings(self.file_path)
                apkinfo["interesting_strings"] = find_strings(strings)
                apkinfo["dex_strings"] = strings

                static_calls = {}
                if self.options.decompilation:
                    if self.check_size(apkinfo["files"]):
                        vm = DalvikVMFormat(a.get_dex())
                        vmx = Analysis(vm)
                        vmx.create_xref()

                        static_calls["all_methods"] = get_methods(vmx)
                        static_calls[
                            "permissions_method_calls"] = get_show_Permissions(
                                vmx)

                        static_calls[
                            "native_method_calls"] = get_show_NativeMethods(
                                vmx)
                        static_calls["is_native_code"] = bool(
                            static_calls["native_method_calls"]
                        )  # True if not empty, False if empty

                        static_calls[
                            "dynamic_method_calls"] = get_show_DynCode(vmx)
                        static_calls["is_dynamic_code"] = bool(
                            static_calls["dynamic_method_calls"])

                        static_calls[
                            "reflection_method_calls"] = get_show_ReflectionCode(
                                vmx)
                        static_calls["is_reflection_code"] = bool(
                            static_calls["reflection_method_calls"])

                        static_calls[
                            "crypto_method_calls"] = get_show_CryptoCode(vmx)
                        static_calls["is_crypto_code"] = bool(
                            static_calls["crypto_method_calls"])

                        classes = list()
                        for cls in vm.get_classes():
                            classes.append(cls.name)

                        static_calls["classes"] = classes

                    else:
                        log.warning(
                            "Aborted decompilation, static extraction of calls not perforemd",
                        )

                apkinfo["static_method_calls"] = static_calls

        except (IOError, OSError, BadZipfile) as e:
            raise CuckooProcessingError("Error opening file %s" % e)
        return apkinfo
示例#32
0
def analyze_dex(filepath_or_raw, needs_dalvik_vm_format=True, needs_vm_analysis=True, needs_gvm_analysis=True,
                 needs_xref=True, needs_dref=True, raw=False, decompiler="dad"):
    '''
    Open the classes.dex file `needs_dalvik_vm_format`
    and set up an analyzer for it `needs_vm_analysis`.

    Parameters
    ----------
    filepath_or_raw : path to file or raw data
         Set raw to True if `filepath_or_raw` is raw data.
    needs_dalvik_vm_format : bool, optional (default is True)
    needs_vm_analysis : bool, optional (default is True)
    needs_gvm_analysis : bool, optional (default is True)
    needs_xref : bool, optional (default is True)
    needs_dref : bool, optional (default is True)
    raw : bool, optional (default is False)
    decompiler : str, optional (default is "dad")

    Returns
    -------
    tuple<DalvikVMFormat, VMAnalysis, GVMAnalysis>

    Raises
    ------
    DexError
        If an error occurred while creating the analysis objects.
    '''

    dalvik_vm_format, vm_analysis, gvm_analysis = None, None, None
    # every requirement implies the need for the `dalvik_vm_format`
    needs_dalvik_vm_format = any((needs_dalvik_vm_format, needs_vm_analysis, needs_gvm_analysis, needs_xref, needs_dref))
    cross_ref = any((needs_xref, needs_dref))

    try:
        if needs_dalvik_vm_format:
            if raw == False:
                with open(filepath_or_raw, "rb") as f:
                    dalvik_vm_format = DalvikVMFormat(f.read())
            else:
                dalvik_vm_format = DalvikVMFormat(filepath_or_raw)

            if needs_vm_analysis or cross_ref or needs_gvm_analysis:
                vm_analysis = uVMAnalysis(dalvik_vm_format)
                dalvik_vm_format.set_vmanalysis(vm_analysis)

            if needs_gvm_analysis or cross_ref:
                gvm_analysis = GVMAnalysis(vm_analysis, None)
                dalvik_vm_format.set_gvmanalysis(gvm_analysis)

            if dalvik_vm_format:
                RunDecompiler(dalvik_vm_format, vm_analysis, decompiler)

            # create references, gvm_analysis needed!
            # we optimize through not exporting the references into the python objects
            if needs_xref:
                dalvik_vm_format.create_xref(python_export = False)
            if needs_dref:
                dalvik_vm_format.create_dref(python_export = False)

    except Exception as e:
        # androguard caused error -> propagate as DexError
        raise DexError(caused_by = e), None, sys.exc_info()[2]

    return dalvik_vm_format, vm_analysis, gvm_analysis
示例#33
0
class Run(Lobotomy):
    def __init__(self):
        Lobotomy.__init__(self)
        self.t = Terminal()
        self.logger = Logger()
        self.util = Util()
        self.apk = None
        self.package = None
        self.vm = None
        self.vmx = None
        self.gmx = None
        self.components = None
        self.dex = None
        self.strings = None
        self.permissions = None
        self.permissions_details = None
        self.files = None
        self.attack_surface = None

    def find_dex(self):
        """
        Return True is classes.dex is found within the target APK.

        Args:
            None

        Returns:
            None
        """
        if self.files:
            for f in self.files:
                if "classes" in f:
                    return True
                    break

    def process_vm(self):
        """
        Process the application's classes.dex

        Args:
            None

        Results:
            None
        """
        # Make sure classes.dex exists
        if self.find_dex():
            self.dex = self.apk.get_dex()
            # Analyze classes.dex
            # TODO Throw in a progress bar, this can take awhile
            if self.dex:
                self.logger.log("info", "Loading classes.dex ...")
                from androguard.core.bytecodes.dvm import DalvikVMFormat
                from androguard.core.analysis.analysis import VMAnalysis
                from androguard.core.analysis.ganalysis import GVMAnalysis
                # Create a new virtual machine instance
                self.vm = DalvikVMFormat(self.dex)
                if self.vm:
                    print(self.t.yellow("\n\t--> Loaded classes.dex (!)\n"))
                    self.logger.log("info", "Analyzing classes.dex ...")
                    # Analyze the virtual machine instance
                    self.vmx = VMAnalysis(self.vm)
                    self.gmx = GVMAnalysis(self.vmx, None)
                    if self.vmx and self.gmx:
                        print(self.t.yellow("\n\t--> Analyzed classes.dex (!)\n"))
                        self.vm.set_vmanalysis(self.vmx)
                        self.vm.set_gvmanalysis(self.gmx)
                        # Generate xref(s)
                        self.vm.create_xref()
                        self.vm.create_dref()
                    else:
                        CommandError("Cannot analyze VM instance (!)")
                else:
                    CommandError("Cannot load VM instance (!)")
        else:
            CommandError("classes.dex not found (!)")

    def do_operate(self, args):
        """
        := operate apk path_to_apk
        := operate dex path_to_classes.dex
        """
        try:
            if args.split()[0] == "apk":
                if args.split()[1]:
                    self.logger.log("info", "Loading : {} ...".format(args.split()[1].split("/")[-1]))
                    from androguard.core.bytecodes.apk import APK
                    self.apk = APK(args.split()[1])
                    if self.apk:
                        print(self.t.yellow("\n\t--> Loaded : {} (!)\n".format(args.split()[1].split("/")[-1])))
                        self.package = self.apk.get_package()
                        from core.brains.apk.components import Components
                        # Load activies, services, broadcast receivers, and
                        # content providers
                        self.components = Components(self.apk)
                        self.components.enumerate_components()
                        self.permissions = self.apk.get_permissions()
                        self.files = self.apk.get_files()
                        self.files_type = self.apk.get_files_types()
                        # Process virtual machine
                        self.process_vm()
                    else:
                        CommandError("APK not loaded (!)")
            else:
                CommandError("Unkown command (!)")
        except ImportError as e:
            CommandError(e.message)
        except IndexError as e:
            CommandError("Not enough arguments (!)")

    def do_surgical(self, args):
        """
        := surgical
        """

        try:
            if self.vm and self.vmx:
                from .surgical import Run
                run = Run(self.vm, self.vmx)
                run.prompt = self.t.yellow("(surgical) ")
                run.ruler = self.t.yellow("-")
                run.cmdloop()
            else:
                CommandError("classes.dex not loaded (!)")
        except Exception as e:
            CommandError(e.message)

    def do_attacksurface(self, args):
        """
        := attacksurface
        """
        try:
            if self.apk and self.components:
                self.logger.log("info", "Loading attacksurface module ...")
                from core.brains.apk.attacksurface import AttackSurface
                self.attack_surface = AttackSurface(self.apk, self.components)
                self.attack_surface.run()
        except ImportError as e:
            CommandError(e.message)

    def do_permissions(self, args):
        """
        := permissions list
        """
        try:
            if self.permissions:
                if args.split()[0] == "list":
                    self.logger.log("info", "Loading permissions ... \n")
                    for p in self.permissions:
                        print(self.t.yellow("\t--> {}".format(p)))
                    print("\n")
            else:
                CommandError("Permissions not found (!)")
        except Exception as e:
            CommandError(e.message)

    def do_files(self, args):
        """
        := files all
        := files assets
        := files libs
        := files res
        """
        try:
            if self.files:
                if args.split()[0]:
                    if args.split()[0] == "assets":
                        self.logger.log("info", "Loading files ... \n")
                        for f in self.files:
                            if f.startswith("assets"):
                                print(self.t.yellow("\t--> {}".format(f)))
                        print("\n")
                    elif args.split()[0] == "libs":
                        self.logger.log("info", "Loading files ... \n")
                        for f in self.files:
                            if f.startswith("lib"):
                                print(self.t.yellow("\t--> {}".format(f)))
                        print("\n")
                    elif args.split()[0] == "res":
                        self.logger.log("info", "Loading files ... \n")
                        for f in self.files:
                            if f.startswith("res"):
                                print(self.t.yellow("\t--> {}".format(f)))
                        print("\n")
                    elif args.split()[0] == "all":
                        self.logger.log("info", "Loading files ... \n")
                        for f in self.files:
                            print(self.t.yellow("\t--> {}".format(f)))
                        print("\n")
            else:
                CommandError("Files not populated (!)")
        except Exception as e:
            CommandError(e.message)

    def do_strings(self, args):
        """
        List and search for strings found in classes.dex

        := strings list
        := strings search
        """

        # Locals
        strings = None

        try:
            if args.split()[0] == "list":
                if self.vm:
                    strings = self.vm.get_strings()
                    if strings:
                        for s in strings:
                            print(self.t.cyan("--> {}".format(s.encode("utf-8"))))
                    else:
                        CommandError("Strings not found (!)")
                else:
                    CommandError("classes.dex not loaded (!)")
            elif args.split()[0] == "search":
                if self.vm:
                    strings = self.vm.get_strings()
                    if strings:
                        target = raw_input(self.t.yellow("\n\t--> Enter string : \n"))
                        for s in strings:
                            if target in s:
                                print(self.t.cyan("\t\t --> {}".format(s)))
                        print("\n")
                    else:
                        CommandError("Strings not found (!)")
                else:
                    CommandError("classes.dex not loaded (!)")
            else:
                CommandError("Command not found (!)")
        except Exception as e:
            # We might be see an exception like this:
            # 'utf8' codec can't decode byte 0xc0 in position 0: invalid start byte
            raise e
            CommandError(e.message)

    def do_components(self, args):
        """
        := components list
        """
        try:
            if args.split()[0] == "list":
                if self.apk:
                    self.logger.log("info", "Enumerating components ...\n")
                    if self.components.activities:
                        for a in self.components.activities:
                            print(self.t.yellow("\t--> activity : {}".format(a)))
                        print("\n")
                    if self.components.services:
                        for s in self.components.services:
                            print(self.t.yellow("\t--> service : {}".format(s)))
                        print("\n")
                    if self.components.receivers:
                        for r in self.components.receivers:
                            print(self.t.yellow("\t--> receiver : {}".format(s)))
                        print("\n")
                    if self.components.providers:
                        for r in self.components.providers:
                            print(self.t.yellow("\t--> provider : {}".format(s)))
                        print("\n")
                else:
                    CommandError("APK not loaded (!)")
            else:
                CommandError("Command not found (!)")
        except Exception as e:
            CommandError(e.message)

    def do_interact(self, args):
        """
        Drop into an interactive IPython session.

        := interact
        """
        try:
            if self.vm and self.vmx:
                from core.brains.interact.interact import Interact
                i = Interact(self.vm, self.vmx)
                i.run()
            else:
                CommandError("classes.dex not loaded (!)")
        except Exception as e:
            CommandError(e.message)

    def do_macro(self, args):
        """
        """
        return
示例#34
0
    def process_vm(self, apk=False, dex=False):
        """
        Process the application's classes.dex

        Args:
            param1 = boolean
            param2 = boolean

        Results:
            None
        """
        try:
            if apk:
                # Make sure the APK contains a classes.dex file
                if self.find_dex():
                    self.dex = self.apk.get_dex()
                    if self.dex:
                        self.logger.log("info", "Loading classes.dex ...")
                        from androguard.core.bytecodes.dvm import DalvikVMFormat
                        from androguard.core.analysis.analysis import VMAnalysis
                        from androguard.core.analysis.ganalysis import GVMAnalysis
                        # Create a DalvikVMFormat instance ...
                        # In this case self.dex will be a file type
                        self.vm = DalvikVMFormat(self.dex)
                        if self.vm:
                            print(self.t.yellow("\n\t--> Loaded classes.dex (!)\n"))
                            self.logger.log("info", "Analyzing classes.dex ...")
                            # Analyze the DalvikVMFormat instance and return
                            # analysis instances of VMAnalysis and GVMAnalysis
                            self.vmx = VMAnalysis(self.vm)
                            self.gmx = GVMAnalysis(self.vmx, None)
                            if self.vmx and self.gmx:
                                print(self.t.yellow("\n\t--> Analyzed classes.dex (!)\n"))
                                # Set the analysis properties on the
                                # DalvikVMFormat instance
                                self.vm.set_vmanalysis(self.vmx)
                                self.vm.set_gvmanalysis(self.gmx)
                                # Generate xref(s) and dref(s)
                                self.vm.create_xref()
                                self.vm.create_dref()
                                return
                            else:
                                CommandError("process_vm : Cannot analyze VM instance (!)")
                                return
                        else:
                            CommandError("process_vm : Cannot load VM instance (!)")
                            return
                    else:
                        CommandError("process_vm : classes.dex not found (!)")
                        return
            if dex:
                if self.dex:
                    from androguard.core.bytecodes.dvm import DalvikVMFormat
                    from androguard.core.analysis.analysis import VMAnalysis
                    from androguard.core.analysis.ganalysis import GVMAnalysis
                    # Analyze the DalvikVMFormat instance and return
                    # analysis instances of VMAnalysis and GVMAnalysis
                    self.vm = DalvikVMFormat(self.util.read(self.dex))
                    if self.vm:
                        print(self.t.yellow("\n\t--> Loaded {} (!)\n"
                                            .format(self.dex
                                                    .split("/")[-1])))
                        self.logger.log("info", "Analyzing {} ..."
                                        .format(self.dex
                                                .split("/")[-1]))
                        # Set the analysis properties on the
                        # DalvikVMFormat instance
                        self.vmx = VMAnalysis(self.vm)
                        self.gmx = GVMAnalysis(self.vmx, None)
                        if self.vmx and self.gmx:
                            print(self.t.yellow("\n\t--> Analyzed {} (!)\n"
                                                .format(self.dex
                                                        .split("/")[-1])))
                            # Set the analysis properties on the
                            # DalvikVMFormat instance
                            self.vm.set_vmanalysis(self.vmx)
                            self.vm.set_gvmanalysis(self.gmx)
                            # Generate xref(s) and dref(s)
                            self.vm.create_xref()
                            self.vm.create_dref()
                            return
                        else:
                            CommandError("process_vm :" +
                                         "Cannot analyze VM instance (!)")
                            return
                    else:
                        CommandError("process_vm :" +
                                     "Cannot load VM instance (!)")
                        return
                else:
                    CommandError("process_vm : classes.dex not found (!)")
                    return
        except Exception as e:
            CommandError("process_vm : {}".format(e))
def extract_features(file_path):
    result = {}
    try:
        a = APK(file_path)
        d = DalvikVMFormat(a.get_dex())
        dx = Analysis(d)
        vm = dvm.DalvikVMFormat(a.get_dex())
        #vmx = analysis.uVMAnalysis(vm)
        d.set_vmanalysis(dx)
        d.set_decompiler(DecompilerDAD(d, dx))
    except:
        return None

    result['android_version_code'] = a.get_androidversion_code()
    result['android_version_name'] = a.get_androidversion_name()
    result['max_sdk'] = a.get_max_sdk_version()
    result['min_sdk'] = a.get_min_sdk_version()
    #result['libraries'] = a.get_libraries()
    result['filename'] = a.get_filename()
    result['target_sdk'] = a.get_target_sdk_version()
    result['md5'] = hashlib.md5(a.get_raw()).hexdigest()
    result['sha256'] = hashlib.sha256(a.get_raw()).hexdigest()
    result['permissions'] = a.get_permissions()
    result['activities'] = a.get_activities()
    result['providers'] = a.get_providers()
    result['services'] = a.get_services()
    result['strings'] = d.get_strings()
    result['class_names'] = [c.get_name() for c in d.get_classes()]
    result['method_names'] = [m.get_name() for m in d.get_methods()]
    result['field_names'] = [f.get_name() for f in d.get_fields()]
    #result['is_native_code'] = 1 if analysis.is_native_code(dx) else 0
    result['is_obfuscation'] = 1 if analysis.is_ascii_obfuscation(d) else 0
    #result['is_crypto_code'] = 1 if analysis.is_crypto_code(dx) else 0
    '''result['is_dyn_code'] = 1 if analysis.is_dyn_code(dx) else 0
    result['is_reflection_code'] = 1 if analysis.is_reflection_code(vmx) else 0'''
    result['is_database'] = 1 if d.get_regex_strings(DB_REGEX) else 0
    arr = []
    s = a.get_elements("action", "name")
    for i in s:
        arr.append(i)

    result['intents'] = arr

    s_list = []
    s_list.extend(result['class_names'])
    s_list.extend(result['method_names'])
    s_list.extend(result['field_names'])
    result['entropy_rate'] = entropy_rate(s_list)

    result['feature_vectors'] = {}

    # Search for the presence of api calls in a given apk
    result['feature_vectors']['api_calls'] = []
    for call in API_CALLS:
        status = 1 if dx.get_method(call) else 0
        result['feature_vectors']['api_calls'].append(status)

    # Search for the presence of permissions in a given apk
    result['feature_vectors']['permissions'] = []
    for permission in PERMISSIONS:
        status = 1 if permission in result['permissions'] else 0
        result['feature_vectors']['permissions'].append(status)

    #Search for the presence of intents in a given apk
    result['feature_vectors']['intents'] = []
    n = len(INTENTS)
    m = len(result['intents'])
    for i in range(n):
        stri = INTENTS[i]
        flg = False
        for j in range(m):
            if stri in result['intents'][j]:
                flg = True
                break
        if flg:
            status = 1
        else:
            status = 0
        result['feature_vectors']['intents'].append(status)

    #Check for special strings in code
    result['feature_vectors']['special_strings'] = []
    for word in SPECIAL_STRINGS:
        status = 1 if d.get_regex_strings(word) else 0
        result['feature_vectors']['special_strings'].append(status)

    return result
示例#36
0
class Run(Lobotomy):
    def __init__(self, ROOT_DIR):
        Lobotomy.__init__(self)
        self.ROOT_DIR = ROOT_DIR
        self.t = Terminal()
        self.logger = Logger()
        self.util = Util()
        self.apk = None
        self.package = None
        self.vm = None
        self.vmx = None
        self.gmx = None
        self.components = None
        self.dex = None
        self.strings = None
        self.permissions = None
        self.permissions_details = None
        self.files = None
        self.attack_surface = None

    def find_dex(self):
        """
        Return True is classes.dex is found within the target APK.

        Args:
            None

        Returns:
            None
        """
        if self.files:
            for f in self.files:
                if "classes" in f:
                    return True
                    break

    def process_vm(self, apk=False, dex=False):
        """
        Process the application's classes.dex

        Args:
            param1 = boolean
            param2 = boolean

        Results:
            None
        """
        try:
            if apk:
                # Make sure the APK contains a classes.dex file
                if self.find_dex():
                    self.dex = self.apk.get_dex()
                    if self.dex:
                        self.logger.log("info", "Loading classes.dex ...")
                        from androguard.core.bytecodes.dvm import DalvikVMFormat
                        from androguard.core.analysis.analysis import VMAnalysis
                        from androguard.core.analysis.ganalysis import GVMAnalysis
                        # Create a DalvikVMFormat instance ...
                        # In this case self.dex will be a file type
                        self.vm = DalvikVMFormat(self.dex)
                        if self.vm:
                            print(self.t.yellow("\n\t--> Loaded classes.dex (!)\n"))
                            self.logger.log("info", "Analyzing classes.dex ...")
                            # Analyze the DalvikVMFormat instance and return
                            # analysis instances of VMAnalysis and GVMAnalysis
                            self.vmx = VMAnalysis(self.vm)
                            self.gmx = GVMAnalysis(self.vmx, None)
                            if self.vmx and self.gmx:
                                print(self.t.yellow("\n\t--> Analyzed classes.dex (!)\n"))
                                # Set the analysis properties on the
                                # DalvikVMFormat instance
                                self.vm.set_vmanalysis(self.vmx)
                                self.vm.set_gvmanalysis(self.gmx)
                                # Generate xref(s) and dref(s)
                                self.vm.create_xref()
                                self.vm.create_dref()
                                return
                            else:
                                CommandError("process_vm : Cannot analyze VM instance (!)")
                                return
                        else:
                            CommandError("process_vm : Cannot load VM instance (!)")
                            return
                    else:
                        CommandError("process_vm : classes.dex not found (!)")
                        return
            if dex:
                if self.dex:
                    from androguard.core.bytecodes.dvm import DalvikVMFormat
                    from androguard.core.analysis.analysis import VMAnalysis
                    from androguard.core.analysis.ganalysis import GVMAnalysis
                    # Analyze the DalvikVMFormat instance and return
                    # analysis instances of VMAnalysis and GVMAnalysis
                    self.vm = DalvikVMFormat(self.util.read(self.dex))
                    if self.vm:
                        print(self.t.yellow("\n\t--> Loaded {} (!)\n"
                                            .format(self.dex
                                                    .split("/")[-1])))
                        self.logger.log("info", "Analyzing {} ..."
                                        .format(self.dex
                                                .split("/")[-1]))
                        # Set the analysis properties on the
                        # DalvikVMFormat instance
                        self.vmx = VMAnalysis(self.vm)
                        self.gmx = GVMAnalysis(self.vmx, None)
                        if self.vmx and self.gmx:
                            print(self.t.yellow("\n\t--> Analyzed {} (!)\n"
                                                .format(self.dex
                                                        .split("/")[-1])))
                            # Set the analysis properties on the
                            # DalvikVMFormat instance
                            self.vm.set_vmanalysis(self.vmx)
                            self.vm.set_gvmanalysis(self.gmx)
                            # Generate xref(s) and dref(s)
                            self.vm.create_xref()
                            self.vm.create_dref()
                            return
                        else:
                            CommandError("process_vm :" +
                                         "Cannot analyze VM instance (!)")
                            return
                    else:
                        CommandError("process_vm :" +
                                     "Cannot load VM instance (!)")
                        return
                else:
                    CommandError("process_vm : classes.dex not found (!)")
                    return
        except Exception as e:
            CommandError("process_vm : {}".format(e))

    def do_operate(self, args):
        """
        := operate apk path_to_apk
        := operate dex path_to_classes.dex
        """
        try:
            if args.split()[0] == "apk":
                if args.split()[1]:
                    self.logger.log("info", "Loading : {} ..."
                                    .format(args.split()[1].split("/")[-1]))
                    from androguard.core.bytecodes.apk import APK
                    self.apk = APK(args.split()[1])
                    if self.apk:
                        print(self.t.yellow("\n\t--> Loaded : {} (!)\n"
                                            .format(args.split()[1]
                                                    .split("/")[-1])))
                        self.package = self.apk.get_package()
                        from core.brains.apk.components import Components
                        # Load activies, services, broadcast receivers, and
                        # content providers
                        self.components = Components(self.apk)
                        self.components.enumerate_components()
                        self.permissions = self.apk.get_permissions()
                        self.files = self.apk.get_files()
                        self.files_type = self.apk.get_files_types()
                        # Process DVM
                        self.process_vm(apk=True)
                    else:
                        CommandError("APK not loaded (!)")
            elif args.split()[0] == "dex":
                self.logger.log("info", "Loading : {} ..."
                                .format(args.split()[1].split("/")[-1]))
                if args.split()[1]:
                    self.dex = args.split()[1]
                    # Process DVM
                    self.process_vm(dex=True)
            else:
                CommandError("Unkown command (!)")
        except ImportError as e:
            CommandError(e.message)
        except IndexError as e:
            CommandError("Not enough arguments (!)")

    def do_surgical(self, args):
        """
        := surgical
        """

        try:
            if self.vm and self.vmx:
                from .surgical import Run
                run = Run(self.vm, self.vmx)
                run.prompt = self.t.yellow("(surgical) ")
                run.ruler = self.t.yellow("-")
                run.cmdloop()
            else:
                CommandError("classes.dex not loaded (!)")
        except Exception as e:
            CommandError(e.message)

    def do_attacksurface(self, args):
        """
        := attacksurface
        """
        try:
            if self.apk and self.components:
                self.logger.log("info", "Loading attacksurface module ...")
                from core.brains.apk.attacksurface import AttackSurface
                self.attack_surface = AttackSurface(self.apk, self.components)
                self.attack_surface.run()
                # Helps with visual spacing after the results are printed
                print("\n")
        except ImportError as e:
            CommandError(e.message)

    def do_permissions(self, args):
        """
        := permissions list
        """
        try:
            if self.permissions:
                if args.split()[0] == "list":
                    self.logger.log("info", "Loading permissions ... \n")
                    for p in self.permissions:
                        print(self.t.yellow("\t--> {}".format(p)))
                    print("\n")
            else:
                CommandError("Permissions not found (!)")
        except Exception as e:
            CommandError(e.message)

    def do_binja(self, args):
        """
        := binja
        """
        rpc = None
        functions = None

        try:
            import xmlrpclib
            rpc = xmlrpclib.ServerProxy('http://localhost:6666/lobotomy')
            functions = rpc.jni()
            if functions:
                self.logger.log("info", "Found JNI methods (!)")
                print("\n")
                for f in functions:
                    print(self.t.cyan("\t--> {}".format(f)))
                print("\n")
            else:
                self.logger.info("Registered JNI functions not found (!)")
        except Exception as e:
            CommandError("binja : {}".format(e))

    def do_files(self, args):
        """
        := files all
        := files assets
        := files libs
        := files res
        """
        try:
            if self.files:
                if args.split()[0]:
                    if args.split()[0] == "assets":
                        self.logger.log("info", "Loading files ... \n")
                        for f in self.files:
                            if f.startswith("assets"):
                                print(self.t.yellow("\t--> {}".format(f)))
                        print("\n")
                    elif args.split()[0] == "libs":
                        self.logger.log("info", "Loading files ... \n")
                        for f in self.files:
                            if f.startswith("lib"):
                                print(self.t.yellow("\t--> {}".format(f)))
                        print("\n")
                    elif args.split()[0] == "res":
                        self.logger.log("info", "Loading files ... \n")
                        for f in self.files:
                            if f.startswith("res"):
                                print(self.t.yellow("\t--> {}".format(f)))
                        print("\n")
                    elif args.split()[0] == "all":
                        self.logger.log("info", "Loading files ... \n")
                        for f in self.files:
                            print(self.t.yellow("\t--> {}".format(f)))
                        print("\n")
            else:
                CommandError("Files not populated (!)")
        except Exception as e:
            CommandError(e.message)

    def do_strings(self, args):
        """
        List and search for strings found in classes.dex

        := strings list
        := strings search
        """

        # Locals
        strings = None

        try:
            if args.split()[0] == "list":
                if self.vm:
                    strings = self.vm.get_strings()
                    if strings:
                        for s in strings:
                            print(self.t.cyan("--> {}"
                                              .format(s.encode("utf-8"))))
                    else:
                        CommandError("Strings not found (!)")
                else:
                    CommandError("classes.dex not loaded (!)")
            elif args.split()[0] == "search":
                if self.vm:
                    strings = self.vm.get_strings()
                    if strings:
                        target = raw_input(self.t.yellow("\n\t--> Enter string : "))
                        for s in strings:
                            if target in s:
                                print(self.t.cyan("\t\t --> {}".format(s)))
                        print("\n")
                    else:
                        CommandError("Strings not found (!)")
                else:
                    CommandError("classes.dex not loaded (!)")
            else:
                CommandError("Command not found (!)")
        except Exception as e:
            # We might be see an exception like this:
            # 'utf8' codec can't decode byte 0xc0 in position 0:
            # invalid start byte
            raise e
            CommandError(e.message)

    def do_components(self, args):
        """
        := components list
        """
        try:
            if args.split()[0] == "list":
                if self.apk:
                    self.logger.log("info", "Enumerating components ...\n")
                    if self.components.activities:
                        for a in self.components.activities:
                            print(self.t.yellow("\t--> activity : {}"
                                                .format(a)))
                        print("\n")
                    if self.components.services:
                        for s in self.components.services:
                            print(self.t.yellow("\t--> service : {}"
                                                .format(s)))
                        print("\n")
                    if self.components.receivers:
                        for r in self.components.receivers:
                            print(self.t.yellow("\t--> receiver : {}"
                                                .format(r)))
                        print("\n")
                    if self.components.providers:
                        for r in self.components.providers:
                            print(self.t.yellow("\t--> provider : {}"
                                                .format(s)))
                        print("\n")
                else:
                    CommandError("APK not loaded (!)")
            else:
                CommandError("Command not found (!)")
        except Exception as e:
            CommandError(e.message)

    def do_interact(self, args):
        """
        Drop into an interactive IPython session.

        := interact
        """
        try:
            if self.vm and self.vmx:
                from core.brains.interact.interact import Interact
                i = Interact(self.vm, self.vmx)
                i.run()
            else:
                CommandError("classes.dex not loaded (!)")
        except Exception as e:
            CommandError(e.message)

    def do_class_tree(self, args):
        """
        := class_tree
        """
        try:
            if self.vm:
                for c in self.vm.get_classes():
                    print("\n")
                    print(self.t.yellow("\t--> class : {}".format(c.name)))
                    for f in c.get_fields():
                        print(self.t.white("\t\t--> field : {}".format(f.name)))
                    for m in c.get_methods():
                        print(self.t.cyan("\t\t\t--> method : {}".format(m.name)))
                print("\n")
            else:
                CommandError("class_tree : classes.dex not loaded (!)")
        except Exception as e:
            CommandError("class_tree : {}".format(e))

    def do_native(self, args):
        """
        := native
        """
        native_methods = list()

        try:
            if self.vm:
                for method in self.vm.get_methods():
                    if method.get_access_flags() & 0x100:
                        native_methods.append((method.get_class_name(),
                                               method.get_name()))
                if native_methods:
                    print("\n")
                    for n in native_methods:
                        print(self.t.cyan("\t--> {} : {}".format(n[0], n[1])))
                    print("\n")
            else:
                self.logger.log("info",
                                "class_tree : classes.dex not loaded (!)")
        except Exception as e:
            CommandError("native : {}".format(e))

    def do_ui(self, args):
        """
        := ui
        """
        try:
            if self.vm and self.vmx:
                from core.brains.ui.terminal import TerminalApp
                ui = TerminalApp(self.vm, self.vmx)
                ui.run()
        except Exception as e:
            CommandError("ui : {}".format(e))

    def do_macro(self, args):
        """
        := macro
        """
        # Locals
        directory_items = None
        macro = path.join(self.ROOT_DIR, "macro")
        selection = None
        apk_path = None
        json = None

        try:
            print("\n")
            directory_items = listdir(macro)
            for i in range(0, len(directory_items)):
                print(self.t.cyan("\t--> [{}] {}"
                                  .format(i, directory_items[i])))
            print("\n")
            selection = raw_input(self.t.yellow("\t--> Select config : "))
            print("\n")
            if selection:
                for f in directory_items:
                    if selection == f:
                        with open("".join([macro, "/", f]), "rb") as config:
                            # Load the config as JSON
                            json = loads(config.read())
                            if json:
                                for k, v in json.items():
                                    if k == "apk":
                                        if v:
                                            apk_path = str(v)
                                            # Call operate() with the path to
                                            # apk
                                            self.do_operate("apk {}"
                                                            .format(apk_path))
                                            return
                                        else:
                                            CommandError("macro : Path to APK not found in {}"
                                                         .format(selection))
                            else:
                                CommandError("macro : Error loading {} as JSON"
                                             .format(selection))
        except Exception as e:
            CommandError("macro : {}".format(e))
示例#37
0
    def run(self):
        """Run androguard to extract static android information
                @return: list of static features
        """
        self.key = "apkinfo"
        apkinfo = {}

        if "file" not in self.task["category"] or not HAVE_ANDROGUARD:
            return

        f = File(self.task["target"])
        #if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type():
        if not os.path.exists(self.file_path):
            raise CuckooProcessingError("Sample file doesn't exist: \"%s\"" % self.file_path)

        try:
            a = APK(self.file_path)
            if a.is_valid_APK():
                manifest = {}

                apkinfo["files"] = self._apk_files(a)
                manifest["package"] = a.get_package()
                apkinfo["hidden_payload"] = []

                for file in apkinfo["files"]:
                    if self.file_type_check(file):
                       apkinfo["hidden_payload"].append(file)

                apkinfo["files_flaged"] = self.files_name_map

                manifest["permissions"]= get_permissions(a)
                manifest["main_activity"] = a.get_main_activity()
                manifest["activities"] = a.get_activities()
                manifest["services"] = a.get_services()
                manifest["receivers"] = a.get_receivers()
                manifest["receivers_actions"] = get_extended_receivers(a)
                manifest["providers"] = a.get_providers()
                manifest["libraries"] = a.get_libraries()
                apkinfo["manifest"] = manifest

                apkinfo["icon"] = get_apk_icon(self.file_path)
                certificate = get_certificate(self.file_path)
                if certificate:
                    apkinfo["certificate"] = certificate


                #vm = DalvikVMFormat(a.get_dex())
                #strings = vm.get_strings()
                strings = self._get_strings(self.file_path)
                apkinfo["interesting_strings"] = find_strings(strings)
                apkinfo["dex_strings"] = strings

                static_calls = {}
                if self.options.decompilation:
                    if self.check_size(apkinfo["files"]):
                        vm = DalvikVMFormat(a.get_dex())
                        vmx = uVMAnalysis(vm)

                        static_calls["all_methods"] = get_methods(vmx)
                        static_calls["is_native_code"] = analysis.is_native_code(vmx)
                        static_calls["is_dynamic_code"] = analysis.is_dyn_code(vmx)
                        static_calls["is_reflection_code"] = analysis.is_reflection_code(vmx)
                        static_calls["is_crypto_code"] = is_crypto_code(vmx)

                        static_calls["dynamic_method_calls"] = get_show_DynCode(vmx)
                        static_calls["reflection_method_calls"] = get_show_ReflectionCode(vmx)
                        static_calls["permissions_method_calls"] = get_show_Permissions(vmx)
                        static_calls["crypto_method_calls"] = get_show_CryptoCode(vmx)
                        static_calls["native_method_calls"] = get_show_NativeMethods(vmx)

                        classes = list()
                        for cls in vm.get_classes():
                            classes.append(cls.name)

                        static_calls["classes"] = classes

                else:
                    log.warning("Dex size bigger than: %s",
                                self.options.decompilation_threshold)

                apkinfo["static_method_calls"] = static_calls

        except (IOError, OSError, BadZipfile) as e:
            raise CuckooProcessingError("Error opening file %s" % e)

        return apkinfo
示例#38
0
def main():
    for path in samples():
        print(path)
        logging.error("Processing" + path)

        tests_apk = [
            "is_valid_APK", "get_filename", "get_app_name", "get_app_icon",
            "get_package", "get_androidversion_code",
            "get_androidversion_name", "get_files", "get_files_types",
            "get_files_crc32", "get_files_information", "get_raw", "get_dex",
            "get_all_dex", "get_main_activity", "get_activities",
            "get_services", "get_receivers", "get_providers",
            "get_permissions", "get_details_permissions",
            "get_requested_aosp_permissions",
            "get_requested_aosp_permissions_details",
            "get_requested_third_party_permissions",
            "get_declared_permissions", "get_declared_permissions_details",
            "get_max_sdk_version", "get_min_sdk_version",
            "get_target_sdk_version", "get_libraries",
            "get_android_manifest_axml", "get_android_manifest_xml",
            "get_android_resources", "get_signature_name",
            "get_signature_names", "get_signature", "get_signatures"
        ]

        tests_dex = [
            "get_api_version",
            "get_classes_def_item",
            "get_methods_id_item",
            "get_fields_id_item",
            "get_codes_item",
            "get_string_data_item",
            "get_debug_info_item",
            "get_header_item",
            "get_class_manager",
            "show",
            # "save",  # FIXME broken
            "get_classes_names",
            "get_classes",
            "get_all_fields",
            "get_fields",
            "get_methods",
            "get_len_methods",
            "get_strings",
            "get_format_type",
            "create_python_export",
            "get_BRANCH_DVM_OPCODES",
            "get_determineNext",
            "get_determineException",
            "print_classes_hierarchy",
            "list_classes_hierarchy",
            "get_format"
        ]

        try:
            # Testing APK
            a = APK(path)
            for t in tests_apk:
                print(t)
                x = getattr(a, t)
                try:
                    x()
                except Exception as aaa:
                    print(aaa)
                    traceback.print_exc()
                    print(path, aaa, file=sys.stderr)
                    logging.exception("{} .. {}".format(path, t))

            # Testing DEX
            dx = Analysis()
            for dex in a.get_all_dex():
                d = DalvikVMFormat(dex)
                dx.add(d)

                # Test decompilation
                for c in d.get_classes():
                    for m in c.get_methods():
                        mx = dx.get_method(m)
                        ms = DvMethod(mx)
                        try:
                            ms.process(doAST=True)
                        except Exception as aaa:
                            print(aaa)
                            traceback.print_exc()
                            print(path, aaa, file=sys.stderr)
                            logging.exception("{} .. {} .. {}".format(
                                path, c.get_name(), m.get_name()))
                        ms2 = DvMethod(mx)
                        try:
                            ms2.process(doAST=False)
                        except Exception as aaa:
                            print(aaa)
                            traceback.print_exc()
                            print(path, aaa, file=sys.stderr)
                            logging.exception("{} .. {} .. {}".format(
                                path, c.get_name(), m.get_name()))

                # DEX tests
                for t in tests_dex:
                    print(t)
                    x = getattr(d, t)
                    try:
                        x()
                    except Exception as aaa:
                        print(aaa)
                        traceback.print_exc()
                        print(path, aaa, file=sys.stderr)
                        logging.exception("{} .. {}".format(path, t))

            # Analysis Tests
            try:
                dx.create_xref()
            except Exception as aaa:
                print(aaa)
                traceback.print_exc()
                print(path, aaa, file=sys.stderr)
                logging.exception("{} .. {} at Analysis".format(path, t))

            # MethodAnalysis tests
            for m in dx.methods.values():
                for bb in m.get_basic_blocks():
                    try:
                        list(bb.get_instructions())
                    except Exception as aaa:
                        print(aaa)
                        traceback.print_exc()
                        print(path, aaa, file=sys.stderr)
                        logging.exception("{} .. {} at BasicBlock {}".format(
                            path, t, m))

        except KeyboardInterrupt:
            raise
        except FileNotFoundError:
            pass
        except Exception as e:
            print(e)
            traceback.print_exc()
            print(path, e, file=sys.stderr)
            logging.exception(path)
示例#39
0
from androguard.core.bytecodes.apk import APK
from androguard.core.bytecodes.dvm import DalvikVMFormat
from androguard.core.analysis.analysis import Analysis
from androguard.decompiler.decompiler import DecompilerJADX
from androguard.core.androconf import show_logging
import logging

# Enable log output
show_logging(level=logging.DEBUG)

# Load our example APK
a = APK("examples/android/TestsAndroguard/bin/TestActivity.apk")

# Create DalvikVMFormat Object
d = DalvikVMFormat(a)
# Create Analysis Object
dx = Analysis(d)

# Load the decompiler
# Set the path to the jadx executable!
decompiler = DecompilerJADX(d, dx, jadx="/home/vagrant/jadx/build/jadx/bin/jadx")

# propagate decompiler and analysis back to DalvikVMFormat
d.set_decompiler(decompiler)
d.set_vmanalysis(dx)

# Now you can do stuff like:
for m in d.get_methods()[:10]:
    print(m)
    print(decompiler.get_source_method(m))
示例#40
0
class PDG():
    def __init__(self, filename):
        """

        :type self: object
        """
        self.filename = filename
        try:
            self.a = APK(filename)
            self.d = DalvikVMFormat(self.a.get_dex())
            self.d.create_python_export()
            self.dx = Analysis(self.d)
        except zipfile.BadZipfile:
            # if file is not an APK, may be a dex object
            _, self.d, self.dx = AnalyzeDex(self.filename)

        self.d.set_vmanalysis(self.dx)
        self.dx.create_xref()
        self.fcg = self.dx.get_call_graph()
        self.icfg = self.build_icfg()

    def get_graph(self):
        return self.icfg

    def build_icfg(self):
        icfg = nx.DiGraph()
        methods = self.d.get_methods()
        for method in methods:
            for bb in self.dx.get_method(method).basic_blocks.get():
                children = []
                label = self.get_bb_label(bb)
                children = self.get_children(bb, self.dx)
                icfg.add_node(label)
                icfg.add_edges_from([(label, child) for child in children])
        return icfg

    def get_bb_label(self, bb):
        """ Return the descriptive name of a basic block
        """
        return self.get_method_label(bb.method) + (bb.name, )

    def get_method_label(self, method):
        """ Return the descriptive name of a method
        """
        return (method.get_class_name(), method.get_name(),
                method.get_descriptor())

    def get_children(self, bb, dx):
        """ Return the labels of the basic blocks that are children of the
        input basic block in and out of its method
        """
        return self.get_bb_intra_method_children(
            bb) + self.get_bb_extra_method_children(bb, dx)

    def get_bb_intra_method_children(self, bb):
        """ Return the labels of the basic blocks that are children of the
        input basic block within a method
        """
        child_labels = []
        for c_in_bb in bb.get_next():
            next_bb = c_in_bb[2]
            child_labels.append(self.get_bb_label(next_bb))
        return child_labels

    def get_bb_extra_method_children(self, bb, dx):
        """ Given a basic block, find the calls to external methods and
        return the label of the first basic block in these methods
        """

        call_labels = []
        # iterate over calls from bb method to external methods
        try:
            xrefs = dx.get_method_analysis(bb.method).get_xref_to()
        except AttributeError:
            return call_labels
        for xref in xrefs:
            remote_method_offset = xref[2]
            if self.call_in_bb(bb, remote_method_offset):
                try:
                    remote_method = dx.get_method(
                        self.d.get_method_by_idx(remote_method_offset))
                    if remote_method:
                        remote_bb = next(remote_method.basic_blocks.get())
                        call_labels.append(self.get_bb_label(remote_bb))
                except StopIteration:
                    pass
        return call_labels

    def call_in_bb(self, bb, idx):
        return bb.get_start() <= idx <= bb.get_end()
示例#41
0
    def run(self):
        """Run androguard to extract static android information
                @return: list of static features
        """
        self.key = "apkinfo"
        apkinfo = {}

        if "file" not in self.task["category"] or not HAVE_ANDROGUARD:
            return

        #f = File(self.task["target"])
        #if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type():
        if not os.path.exists(self.file_path):
            raise CuckooProcessingError("Sample file doesn't exist: \"%s\"" % self.file_path)

        apkinfo["APKiD"] = self._scan_APKiD(self.file_path)

        try:
            a = APK(self.file_path)
            if a.is_valid_APK():
                manifest = {}

                apkinfo["files"] = self._apk_files(a)
                apkinfo["encrypted_assets"] = self.find_encrypted_assets(a)
                manifest["package"] = a.get_package()
                apkinfo["hidden_payload"] = []

                for file in apkinfo["files"]:
                    if self.file_type_check(file):
                       apkinfo["hidden_payload"].append(file)

                apkinfo["files_flaged"] = self.files_name_map

                manifest["permissions"]= get_permissions(a)
                manifest["main_activity"] = a.get_main_activity()
                manifest["activities"] = a.get_activities()
                manifest["services"] = a.get_services()
                manifest["receivers"] = a.get_receivers()
                manifest["receivers_actions"] = get_extended_receivers(a)
                manifest["receivers_info"] = get_receivers_info(a)
                manifest["providers"] = a.get_providers()
                manifest["libraries"] = a.get_libraries()
                apkinfo["manifest"] = manifest

                apkinfo["icon"] = get_apk_icon(self.file_path)
                certificate = get_certificate(self.file_path)
                if certificate:
                    apkinfo["certificate"] = certificate


                #vm = DalvikVMFormat(a.get_dex())
                #strings = vm.get_strings()

                strings = self._get_strings(self.file_path)
                for subdir, dirs, files in os.walk(self.dropped_path):
                    for file in files:
                        path = os.path.join(subdir, file)
                        try:
                            extra_strings = self._get_strings(path)
                            strings = list(set(extra_strings + strings))
                        except:
                            pass

                apkinfo["dex_strings"] = strings

                static_calls = {}
                if self.options.decompilation:
                    if self.check_size(apkinfo["files"]):
                        vm = DalvikVMFormat(a.get_dex())
                        vmx = uVMAnalysis(vm)
                        # Be less verbose about androguard logging messages.
                        logging.getLogger("andro.runtime").setLevel(logging.CRITICAL)

                        static_calls["all_methods"] = get_methods(vmx)
                        static_calls["is_native_code"] = analysis.is_native_code(vmx)
                        static_calls["is_dynamic_code"] = analysis.is_dyn_code(vmx)
                        static_calls["is_reflection_code"] = analysis.is_reflection_code(vmx)
                        static_calls["is_crypto_code"] = is_crypto_code(vmx)

                        static_calls["dynamic_method_calls"] = get_show_DynCode(vmx)
                        static_calls["reflection_method_calls"] = get_show_ReflectionCode(vmx)
                        static_calls["permissions_method_calls"] = get_show_Permissions(vmx)
                        static_calls["crypto_method_calls"] = get_show_CryptoCode(vmx)
                        static_calls["native_method_calls"] = get_show_NativeMethods(vmx)

                        classes = list()
                        for cls in vm.get_classes():
                            classes.append(cls.name)

                        static_calls["classes"] = classes

                else:
                    log.warning("Dex size bigger than: %s",
                                self.options.decompilation_threshold)

                apkinfo["static_method_calls"] = static_calls

        except (IOError, OSError, BadZipfile) as e:
            raise CuckooProcessingError("Error opening file %s" % e)

        return apkinfo
示例#42
0
class Run(Lobotomy):
    def __init__(self, ROOT_DIR):
        Lobotomy.__init__(self)
        self.ROOT_DIR = ROOT_DIR
        self.t = Terminal()
        self.logger = Logger()
        self.util = Util()
        self.apk = None
        self.package = None
        self.vm = None
        self.vmx = None
        self.gmx = None
        self.components = None
        self.dex = None
        self.strings = None
        self.permissions = None
        self.permissions_details = None
        self.files = None
        self.attack_surface = None

    def _cmd_completer(self, name, text, line, begidx, endidx):
        fn = getattr(self, 'do_'+name)
        if not hasattr(fn.im_func, "_expected_args"):
            return []
        a = [arg for arg in fn.im_func._expected_args if arg.startswith(text)]
        return a

    def find_dex(self):
        """
        Return True is classes.dex is found within the target APK.

        Args:
            None

        Returns:
            None
        """
        if self.files:
            for f in self.files:
                if "classes" in f:
                    return True
                    break

    def process_vm(self, apk=False, dex=False):
        """
        Process the application's classes.dex

        Args:
            param1 = boolean
            param2 = boolean

        Results:
            None
        """
        try:
            if apk:
                # Make sure the APK contains a classes.dex file
                if self.find_dex():
                    self.dex = self.apk.get_dex()
                    if self.dex:
                        self.logger.log("info", "Loading classes.dex ...")
                        from androguard.core.bytecodes.dvm import DalvikVMFormat
                        from androguard.core.analysis.analysis import VMAnalysis
                        from androguard.core.analysis.ganalysis import GVMAnalysis
                        # Create a DalvikVMFormat instance ...
                        # In this case self.dex will be a file type
                        self.vm = DalvikVMFormat(self.dex)
                        if self.vm:
                            print(self.t.yellow("\n\t--> Loaded classes.dex (!)\n"))
                            self.logger.log("info", "Analyzing classes.dex ...")
                            # Analyze the DalvikVMFormat instance and return
                            # analysis instances of VMAnalysis and GVMAnalysis
                            self.vmx = VMAnalysis(self.vm)
                            self.gmx = GVMAnalysis(self.vmx, None)
                            if self.vmx and self.gmx:
                                print(self.t.yellow("\n\t--> Analyzed classes.dex (!)\n"))
                                # Set the analysis properties on the
                                # DalvikVMFormat instance
                                self.vm.set_vmanalysis(self.vmx)
                                self.vm.set_gvmanalysis(self.gmx)
                                # Generate xref(s) and dref(s)
                                self.vm.create_xref()
                                self.vm.create_dref()
                                return
                            else:
                                CommandError("process_vm : Cannot analyze VM instance (!)")
                                return
                        else:
                            CommandError("process_vm : Cannot load VM instance (!)")
                            return
                    else:
                        CommandError("process_vm : classes.dex not found (!)")
                        return
            if dex:
                if self.dex:
                    from androguard.core.bytecodes.dvm import DalvikVMFormat
                    from androguard.core.analysis.analysis import VMAnalysis
                    from androguard.core.analysis.ganalysis import GVMAnalysis
                    # Analyze the DalvikVMFormat instance and return
                    # analysis instances of VMAnalysis and GVMAnalysis
                    self.vm = DalvikVMFormat(self.util.read(self.dex))
                    if self.vm:
                        print(self.t.yellow("\n\t--> Loaded {} (!)\n"
                                            .format(self.dex
                                                    .split("/")[-1])))
                        self.logger.log("info", "Analyzing {} ..."
                                        .format(self.dex
                                                .split("/")[-1]))
                        # Set the analysis properties on the
                        # DalvikVMFormat instance
                        self.vmx = VMAnalysis(self.vm)
                        self.gmx = GVMAnalysis(self.vmx, None)
                        if self.vmx and self.gmx:
                            print(self.t.yellow("\n\t--> Analyzed {} (!)\n"
                                                .format(self.dex
                                                        .split("/")[-1])))
                            # Set the analysis properties on the
                            # DalvikVMFormat instance
                            self.vm.set_vmanalysis(self.vmx)
                            self.vm.set_gvmanalysis(self.gmx)
                            # Generate xref(s) and dref(s)
                            self.vm.create_xref()
                            self.vm.create_dref()
                            return
                        else:
                            CommandError("process_vm :" +
                                         "Cannot analyze VM instance (!)")
                            return
                    else:
                        CommandError("process_vm :" +
                                     "Cannot load VM instance (!)")
                        return
                else:
                    CommandError("process_vm : classes.dex not found (!)")
                    return
        except Exception as e:
            CommandError("process_vm : {}".format(e))

    def complete_operate(self, *args):
        return self._cmd_completer("operate", *args)

    @cmd_arguments(["apk", "dex"])
    def do_operate(self, *args):
        """
        := operate apk path_to_apk
        := operate dex path_to_classes.dex
        """
        # Locals
        arg0 = args[0].split(" ")[0]
        arg1 = args[0].split(" ")[1]

        try:
            if arg0 == "apk":
                if arg1:
                    self.logger.log("info", "Loading : {} ..."
                                    .format(arg1.split("/")[-1]))
                    from androguard.core.bytecodes.apk import APK
                    self.apk = APK(arg1)
                    if self.apk:
                        print(self.t.yellow("\n\t--> Loaded : {} (!)\n"
                                            .format(arg1.split("/")[-1])))
                        self.package = self.apk.get_package()
                        from core.brains.apk.components import Components
                        # Load activies, services, broadcast receivers, and
                        # content providers
                        self.components = Components(self.apk)
                        self.components.enumerate_components()
                        self.permissions = self.apk.get_permissions()
                        self.files = self.apk.get_files()
                        self.files_type = self.apk.get_files_types()
                        # Process DVM
                        self.process_vm(apk=True)
                    else:
                        CommandError("APK not loaded (!)")
            elif arg0 == "dex":
                if arg1:
                    self.logger.log("info", "Loading : {} ..."
                                    .format(arg1.split("/")[-1]))
                    self.dex = arg1
                    self.process_vm(dex=True)
        except ImportError as e:
            CommandError("operate : {}".format(e))

    def complete_surgical(self, *args):
        return self._cmd_completer("surgical", *args)

    def do_surgical(self, *args):
        """
        := surgical
        """
        try:
            if self.vm and self.vmx:
                from .surgical import Run
                run = Run(self.vm, self.vmx)
                run.prompt = self.t.yellow("(surgical) ")
                run.ruler = self.t.yellow("-")
                run.cmdloop()
            else:
                CommandError("classes.dex not loaded (!)")
        except Exception as e:
            CommandError("surgical : {}".format(e))

    def complete_attacksurface(self, *args):
        return self._cmd_completer("attacksurface", *args)

    def do_attacksurface(self, *args):
        """
        := attacksurface
        """
        try:
            if self.apk and self.components:
                self.logger.log("info", "Loading attacksurface module ...")
                from core.brains.apk.attacksurface import AttackSurface
                self.attack_surface = AttackSurface(self.apk, self.components)
                self.attack_surface.run()
                # Helps with visual spacing after the results are printed
                print("\n")
        except ImportError as e:
            CommandError("attacksurface : {}".format(e))

    def complete_permissions(self, *args):
        return self._cmd_completer("permissions", *args)

    @cmd_arguments(["list"])
    def do_permissions(self, *args):
        """
        := permissions list
        """
        # Locals
        arg0 = args[0]

        try:
            if self.permissions:
                if args[0] == "list":
                    self.logger.log("info", "Loading permissions ... \n")
                    for p in self.permissions:
                        print(self.t.yellow("\t--> {}".format(p)))
                    print("\n")
            else:
                CommandError("Permissions not found (!)")
        except Exception as e:
            CommandError("permissions : {}".format(e))

    def complete_binja(self, *args):
        return self._cmd_completer("binja", *args)

    def do_binja(self, *args):
        """
        := binja
        """
        try:
            from .binja import Run
            run = Run(self.files, self.apk)
            run.prompt = self.t.cyan("(binja) ")
            run.ruler = self.t.cyan("-")
            run.cmdloop()
        except Exception as e:
            CommandError("binja : {}".format(e))



    def complete_files(self, *args):
        return self._cmd_completer("files", *args)

    @cmd_arguments(["all", "assets", "libs", "res"])
    def do_files(self, *args):
        """
        := files all
        := files assets
        := files libs
        := files res
        """
        # Locals
        arg0 = args[0]

        try:
            if self.files:
                if arg0 == "assets":
                    self.logger.log("info", "Loading files ... \n")
                    for f in self.files:
                        if f.startswith("assets"):
                            print(self.t.yellow("\t--> {}".format(f)))
                    print("\n")
                elif arg0 == "libs":
                    self.logger.log("info", "Loading files ... \n")
                    for f in self.files:
                        if f.startswith("lib"):
                            print(self.t.yellow("\t--> {}".format(f)))
                    print("\n")
                elif arg0 == "res":
                    self.logger.log("info", "Loading files ... \n")
                    for f in self.files:
                        if f.startswith("res"):
                            print(self.t.yellow("\t--> {}".format(f)))
                    print("\n")
                elif arg0 == "all":
                    self.logger.log("info", "Loading files ... \n")
                    for f in self.files:
                        print(self.t.yellow("\t--> {}".format(f)))
                    print("\n")
            else:
                CommandError("Files not populated (!)")
        except Exception as e:
            CommandError("files : {}".format(e))

    def complete_strings(self, *args):
        return self._cmd_completer("strings", *args)

    @cmd_arguments(["list", "search"])
    def do_strings(self, *args):
        """
        List and search for strings found in classes.dex

        := strings list
        := strings search
        """
        # Locals
        arg0 = args[0]
        strings = None

        try:
            if arg0 == "list":
                if self.vm:
                    strings = self.vm.get_strings()
                    if strings:
                        for s in strings:
                            print(self.t.cyan("--> {}".format(s.encode("utf-8", errors="ignore"))))
                    else:
                        CommandError("Strings not found (!)")
                else:
                    CommandError("classes.dex not loaded (!)")
            elif arg0 == "search":
                if self.vm:
                    strings = self.vm.get_strings()
                    if strings:
                        target = raw_input(self.t.yellow("\n\t--> Enter string : "))
                        for s in strings:
                            if target in s:
                                print(self.t.cyan("\t\t --> {}".format(s.encode("utf-8", errors="ignore"))))
                        print("\n")
                    else:
                        CommandError("Strings not found (!)")
                else:
                    CommandError("classes.dex not loaded (!)")
        except Exception as e:
            CommandError("strings : {}".format(e))

    def complete_components(self, *args):
        return self._cmd_completer("components", *args)

    @cmd_arguments(["list"])
    def do_components(self, *args):
        """
        := components list
        """
        # Locals
        arg0 = args[0]

        try:
            if arg0 == "list":
                if self.apk:
                    self.logger.log("info", "Enumerating components ...\n")
                    if self.components.activities:
                        for a in self.components.activities:
                            print(self.t.yellow("\t--> activity : {}"
                                                .format(a)))
                        print("\n")
                    if self.components.services:
                        for s in self.components.services:
                            print(self.t.yellow("\t--> service : {}"
                                                .format(s)))
                        print("\n")
                    if self.components.receivers:
                        for r in self.components.receivers:
                            print(self.t.yellow("\t--> receiver : {}"
                                                .format(r)))
                        print("\n")
                    if self.components.providers:
                        for r in self.components.providers:
                            print(self.t.yellow("\t--> provider : {}"
                                                .format(s)))
                        print("\n")
                else:
                    CommandError("APK not loaded (!)")
        except Exception as e:
            CommandError("components : {}".format(e))

    def complete_interact(self, *args):
        return self._cmd_completer("interact", *args)

    def do_interact(self, *args):
        """
        Drop into an interactive IPython session.

        := interact
        """
        try:
            if self.vm and self.vmx:
                from core.brains.interact.interact import Interact
                i = Interact(self.vm, self.vmx)
                i.run()
            else:
                CommandError("classes.dex not loaded (!)")
        except Exception as e:
            CommandError("interact : {}".format(e.message))

    def complete_class_tree(self, *args):
        return self._cmd_completer("class_tree", *args)

    def do_class_tree(self, *args):
        """
        := class_tree
        """
        try:
            if self.vm:
                for c in self.vm.get_classes():
                    # We don't care about Android support classes or resource
                    # classes
                    if c.name.startswith("Landroid") or \
                            c.name.split("/")[-1].startswith("R") or \
                            "google" in c.name or \
                            "android" in c.name or \
                            "log4j" in c.name:
                        continue
                    print("\n")
                    print(self.t.yellow("\t--> class : {} {}".format(c.get_access_flags_string(), c.name)))
                    for f in c.get_fields():
                        print(self.t.white("\t\t--> field : {} {} {}".format(f.get_access_flags_string(), f.get_descriptor(), f.name)))
                    for m in c.get_methods():
                        print(self.t.cyan("\t\t\t--> method : {} {} {}".format(m.get_access_flags_string(), m.name, m.get_descriptor())))
                print("\n")
            else:
                CommandError("class_tree : classes.dex not loaded (!)")
        except Exception as e:
            CommandError("class_tree : {}".format(e))

    def complete_native(self, *args):
        return self._cmd_completer("native", *args)

    def do_native(self, *args):
        """
        := native
        """
        # Locals
        native_methods = list()

        try:
            if self.vm:
                for method in self.vm.get_methods():
                    if method.get_access_flags() & 0x100:
                        native_methods.append((method.get_class_name(),
                                               method.get_name()))
                if native_methods:
                    print("\n")
                    for n in native_methods:
                        print(self.t.cyan("\t--> {} : {}".format(n[0], n[1])))
                    print("\n")
            else:
                self.logger.log("info",
                                "class_tree : classes.dex not loaded (!)")
        except Exception as e:
            CommandError("native : {}".format(e))

    def complete_ui(self, *args):
        return self._cmd_completer("ui", *args)

    def do_ui(self, *args):
        """
        := ui
        """
        try:
            if self.vm and self.vmx:
                from core.brains.ui.terminal import TerminalApp
                ui = TerminalApp(self.vm, self.vmx)
                ui.run()
        except Exception as e:
            CommandError("ui : {}".format(e))

    def complete_macro(self, *args):
        return self._cmd_completer("macro", *args)

    def do_macro(self, args):
        """
        := macro
        """
        # Locals
        directory_items = None
        macro = path.join(self.ROOT_DIR, "macro")
        selection = None
        apk_path = None
        json = None

        try:
            print("\n")
            directory_items = listdir(macro)
            for i, item in enumerate(directory_items):
                print(self.t.cyan("\t--> [{}] {}"
                                  .format(i, item)))
            print("\n")
            selection = raw_input(self.t.yellow("[{}] Select config : ".format(datetime.now())))
            try:
                index = int(selection)
            except ValueError:
                index = -1
            print("\n")
            if selection:
                for i, item in enumerate(directory_items):
                    if selection == item or i == index:
                        selection = item
                        break
                with open("".join([macro, "/", selection]), "rb") as config:
                    # Load the config as JSON
                    json = loads(config.read())
                    if json:
                        for k, v in json.items():
                            if k == "apk":
                                if v:
                                    apk_path = str(v)
                                    # Call operate() with the path to apk
                                    self.do_operate("apk {}"
                                                    .format(apk_path))
                                    return
                                else:
                                    CommandError("macro : Path to APK not found in {}"
                                                 .format(selection))
                            else:
                                CommandError("macro : Error loading {} as JSON"
                                             .format(selection))
        except Exception as e:
            CommandError("macro : {}".format(e))
示例#43
0
                    else:
                        pass
            except:
                print("except error")

    except PermissionError:
        pass


dir_path = 'G:/dataset_share/images/drebin(mal)/'
filename = '000a067df9235aea987cd1e6b7768bcc1053e640b267c5b1f0deefc18be5dbe1.apk'
img_path = 'G:/dataset_share/androguard/drebin(mal)_img/'
apk_path = dir_path + filename

apk = APK(apk_path)
dalvik = DalvikVMFormat(apk)

code_item = dalvik.get_codes_item()
code_item_str = code_item.show()

binary = int(code_item_str, 16)
cnt = 0

try:
    photo_image = PIL.Image.frombytes(
        'P', (299, 299),
        binary.to_bytes(int(len(code_item_str) / 2), sys.byteorder))

    img_name = filename.split('.')
    img_name = img_name[0] + '.png'
示例#44
0
def XrefTraverse(methods, class_name, method_name, depth):
    depth += 1
    for m in methods:
        if m.class_name == class_name and m.name == method_name:
            if depth == 0:
                print (m.class_name + " -> " + m.name)
            for item in m.XREFfrom.items:
                if item[0].class_name != class_name or item[0].name != method_name:                    
                    for x in range(1, depth):
                        sys.stdout.write('--')
                    sys.stdout.write ('>' + item[0].class_name + "->" + item[0].name + "\n")
                    XrefTraverse(methods, item[0].class_name, item[0].name, depth)

if len(sys.argv) > 2:
    filename = sys.argv[1]
    class_name = sys.argv[2]
    class_name = 'L' + class_name.replace(".", "/") + ";"
    #print class_name
    method_name = '<init>'
    d = DalvikVMFormat(APK(filename, False).get_dex())
    d.create_python_export()
    dx = uVMAnalysis(d)
    gx = GVMAnalysis(dx, None)
    d.set_vmanalysis(dx)
    d.set_gvmanalysis(gx)
    d.create_xref()

    XrefTraverse(d.get_methods(), class_name, method_name, 0)
else:
    print "usage: XrefTree.py [filename] [class_name]"
    print "usage: XrefTree.py filename.apk com.xyz.abc"