Python源码示例:androguard.core.bytecodes.apk.APK

示例1
def sign_apk(filename, keystore, storepass):
    """
    Use jarsigner to sign an APK file.

    :param filename: APK file on disk to sign (path)
    :param keystore: path to keystore
    :param storepass: your keystorage passphrase
    """
    from subprocess import Popen, PIPE, STDOUT
    # TODO use apksigner instead of jarsigner
    cmd = Popen([androconf.CONF["BIN_JARSIGNER"], "-sigalg", "MD5withRSA",
                 "-digestalg", "SHA1", "-storepass", storepass, "-keystore",
                 keystore, filename, "alias_name"],
                stdout=PIPE,
                stderr=STDOUT)
    stdout, stderr = cmd.communicate() 
示例2
def addAPK(self, filename, data):
        """
        Add an APK file to the Session and run analysis on it.

        :param filename: (file)name of APK file
        :param data: binary data of the APK file
        :return: a tuple of SHA256 Checksum and APK Object
        """
        digest = hashlib.sha256(data).hexdigest()
        log.debug("add APK:%s" % digest)
        apk = APK(data, True)
        self.analyzed_apk[digest] = [apk]
        self.analyzed_files[filename].append(digest)
        self.analyzed_digest[digest] = filename

        dx = Analysis()
        self.analyzed_vms[digest] = dx

        for dex in apk.get_all_dex():
            # we throw away the output... FIXME?
            self.addDEX(filename, dex, dx)

        log.debug("added APK:%s" % digest)
        return digest, apk 
示例3
def androaxml_main(inp, outp=None, resource=None):
    ret_type = androconf.is_android(inp)
    if ret_type == "APK":
        a = apk.APK(inp)
        if resource:
            if resource not in a.files:
                print("The APK does not contain a file called '{}'".format(resource), file=sys.stderr)
                sys.exit(1)

            axml = AXMLPrinter(a.get_file(resource)).get_xml_obj()
        else:
            axml = a.get_android_manifest_xml()
    elif ".xml" in inp:
        axml = AXMLPrinter(read(inp)).get_xml_obj()
    else:
        print("Unknown file type")
        sys.exit(1)

    buff = etree.tostring(axml, pretty_print=True, encoding="utf-8")
    if outp:
        with open(outp, "wb") as fd:
            fd.write(buff)
    else:
        sys.stdout.write(highlight(buff.decode("UTF-8"), get_lexer_by_name("xml"), TerminalFormatter())) 
示例4
def __init__(self, name):
        """

        :param name: filename to load
        """
        self.vma = analysis.Analysis()

        # Proper detection which supports multidex inside APK
        ftype = androconf.is_android(name)
        if ftype == 'APK':
            for d in apk.APK(name).get_all_dex():
                self.vma.add(dvm.DalvikVMFormat(d))
        elif ftype == 'DEX':
            self.vma.add(dvm.DalvikVMFormat(read(name)))
        elif ftype == 'DEY':
            self.vma.add(dvm.DalvikOdexVMFormat(read(name)))
        else:
            raise ValueError("Format not recognised for filename '%s'" % name)

        self.classes = dict((dvclass.orig_class.get_name(), dvclass.orig_class) for dvclass in self.vma.get_classes())
        # TODO why not?
        # util.merge_inner(self.classes) 
示例5
def __init__(self,apkFile):
    self.sha256 = self.sha256CheckSum(apkFile)
    print "[-]Parsing APK"
    self.a = apk.APK(apkFile)
    print "[-]Baksmaling DEX files"
    self.bakmali(apkFile)
    self.manifest = self.a.get_android_manifest_axml().get_xml_obj()
    self.application = self.manifest.findall("application")[0]
    print "[+]Gathering Information"
    self.extractActivitiesWithExcludeFromRecents()
    self.extractActivitiesWithoutSecureFlag()
    print "   [-]Package Properties"
    self.extractPackageProperties()
    print "   [-]Exported Components"
    self.extractExportedComponents()
    print "   [-]Permissions"
    self.extractPermissions()
    print "   [-]Files"
    self.extractFiles()

  #Return the Android Code Name for the particular Api Level. 
示例6
def _analyze(self):
        for i in self.__files:
            ret_type = androconf.is_android( i )
            if ret_type == "APK":
                x = apk.APK( i )
                bc = dvm.DalvikVMFormat( x.get_dex() )
            elif ret_type == "DEX":
                bc = dvm.DalvikVMFormat( read(i) )
            elif ret_type == "DEY":
                bc = dvm.DalvikOdexVMFormat( read(i) )
            elif ret_type == "ELF":
                from androguard.core.binaries import elf
                bc = elf.ELF( read(i) )
            else:
                raise( "Unknown format" )

            self.__bc.append( (i, BC( bc )) ) 
示例7
def filter_file(self, log, fileraw):
    """
      This method is called in order to filer a specific app

      :param log: an object which corresponds to a unique app
      :param fileraw: the raw app (a string)

      :rtype: a set with 2 elements, the return value (boolean) if it is necessary to
      continue the analysis and the file type
    """
    file_type = androconf.is_android_raw(fileraw)
    if file_type == "APK" or file_type == "DEX" or file_type == "DEY" or file_type == "AXML" or file_type == "ARSC":
      if file_type == "APK":
        if androconf.is_valid_android_raw(fileraw):
          return (True, "APK")
      else:
        return (True, file_type)
    return (False, None) 
示例8
def __init__(self, app_path, output_dir=None):
        """
        create an App instance
        :param app_path: local file path of app
        :return:
        """
        assert app_path is not None
        self.logger = logging.getLogger(self.__class__.__name__)

        self.app_path = app_path

        self.output_dir = output_dir
        if output_dir is not None:
            if not os.path.isdir(output_dir):
                os.makedirs(output_dir)

        from androguard.core.bytecodes.apk import APK
        self.apk = APK(self.app_path)
        self.package_name = self.apk.get_package()
        self.main_activity = self.apk.get_main_activity()
        self.permissions = self.apk.get_permissions()
        self.activities = self.apk.get_activities()
        self.possible_broadcasts = self.get_possible_broadcasts()
        self.dumpsys_main_activity = None
        self.hashes = self.get_hashes() 
示例9
def get_hashes(self, block_size=2 ** 8):
        """
        Calculate MD5,SHA-1, SHA-256
        hashes of APK input file
        @param block_size:
        """
        md5 = hashlib.md5()
        sha1 = hashlib.sha1()
        sha256 = hashlib.sha256()
        f = open(self.app_path, 'rb')
        while True:
            data = f.read(block_size)
            if not data:
                break
            md5.update(data)
            sha1.update(data)
            sha256.update(data)
        return [md5.hexdigest(), sha1.hexdigest(), sha256.hexdigest()] 
示例10
def get_app_name(app_path, app_dir, tools_dir, is_apk):
    """Get app name."""
    if is_apk:
        a = apk.APK(app_path)
        real_name = a.get_app_name()
        return real_name
    else:
        strings_path = os.path.join(app_dir,
                                    'app/src/main/res/values/')
        eclipse_path = os.path.join(app_dir,
                                    'res/values/')
        if os.path.exists(strings_path):
            strings_dir = strings_path
        elif os.path.exists(eclipse_path):
            strings_dir = eclipse_path
    if not os.path.exists(strings_dir):
        logger.warning('Cannot find values folder.')
        return ''
    return get_app_name_from_values_folder(strings_dir) 
示例11
def check_apk(self, apk):
        """
            Check if a signature matches the application

            @param apk : an L{APK} object
            @rtype : None if no signatures match, otherwise the name of the signature
        """
        if self.debug:
            print "loading apk..",
            sys.stdout.flush()

        classes_dex = apk.get_dex()
        ret, l = self.p._check_dalvik( classes_dex )

        if ret == None:
            #ret, l1 = self.p._check_bin( apk )
            l1 = []
            l.extend( l1 )

        return ret, l 
示例12
def check_one_directory(directory):
    for root, dirs, files in os.walk( directory, followlinks=True ):
        if files != []:
            for f in files:
                real_filename = root
                if real_filename[-1] != "/":
                    real_filename += "/"
                real_filename += f

                print "filename: %s ..." % real_filename
                ret_type = androconf.is_android( real_filename )
                if ret_type == "APK":
                    a = apk.APK( real_filename )
                    d1 = dvm.DalvikVMFormat( a.get_dex() )
                elif ret_type == "DEX":
                    d1 = dvm.DalvikVMFormat( read(real_filename) )

                dx1 = analysis.VMAnalysis( d1 )
                check_one_file( d1, dx1 ) 
示例13
def main(options, arguments):
    if options.input != None and options.database != None:
        ret_type = androconf.is_android( options.input )
        if ret_type == "APK":
            a = apk.APK( options.input )
            d1 = dvm.DalvikVMFormat( a.get_dex() )
        elif ret_type == "DEX":
            d1 = dvm.DalvikVMFormat( read(options.input) )

        dx1 = analysis.VMAnalysis( d1 )

        check_one_file(d1, dx1)

    elif options.directory != None and options.database != None:
      check_one_directory( options.directory )

    elif options.database != None and options.listdatabase != None:
        db = DBFormat( options.database )
        db.show()

    elif options.version != None:
        print "Androappindb version %s" % androconf.ANDROGUARD_VERSION 
示例14
def main(options, arguments):
    if options.input != None:
        buff = ""

        ret_type = androconf.is_android(options.input)
        if ret_type == "APK":
            a = apk.APK(options.input)
            buff = a.get_android_manifest_xml().toprettyxml(encoding="utf-8")
        elif ".xml" in options.input:
            ap = apk.AXMLPrinter(read(options.input))
            buff = minidom.parseString(ap.get_buff()).toprettyxml(
                encoding="utf-8")
        else:
            print "Unknown file type"
            return

        if options.output != None:
            fd = codecs.open(options.output, "w", "utf-8")
            fd.write(buff)
            fd.close()
        else:
            print buff

    elif options.version != None:
        print "Androaxml version %s" % androconf.ANDROGUARD_VERSION 
示例15
def filter_file(self, log, fileraw):
        """
      This method is called in order to filer a specific app

      :param log: an object which corresponds to a unique app
      :param fileraw: the raw app (a string)

      :rtype: a set with 2 elements, the return value (boolean) if it is necessary to
      continue the analysis and the file type
    """
        file_type = androconf.is_android_raw(fileraw)
        if file_type == "APK" or file_type == "DEX" or file_type == "DEY" or file_type == "AXML" or file_type == "ARSC":
            if file_type == "APK":
                if androconf.is_valid_android_raw(fileraw):
                    return (True, "APK")
            else:
                return (True, file_type)
        return (False, None) 
示例16
def _analyze(self) :
        for i in self.__files :
            ret_type = androconf.is_android( i )
            if ret_type == "APK" :
                x = apk.APK( i )
                bc = dvm.DalvikVMFormat( x.get_dex() )
            elif ret_type == "DEX" :
                bc = dvm.DalvikVMFormat( open(i, "rb").read() )
            elif ret_type == "DEY" :
                bc = dvm.DalvikOdexVMFormat( open(i, "rb").read() )
            elif ret_type == "ELF" :
                from androguard.core.binaries import elf
                bc = elf.ELF( open(i, "rb").read() )
            else :
                raise( "Unknown format" )

            if isinstance(bc, list) :
                for j in bc :
                    self.__bc.append( (j[0], BC( jvm.JVMFormat(j[1]) ) ) )
            else :
                self.__bc.append( (i, BC( bc )) ) 
示例17
def filter_file(self, log, fileraw):
    """
      This method is called in order to filer a specific app

      :param log: an object which corresponds to a unique app
      :param fileraw: the raw app (a string)

      :rtype: a set with 2 elements, the return value (boolean) if it is necessary to
      continue the analysis and the file type
    """
    file_type = androconf.is_android_raw(fileraw)
    if file_type == "APK" or file_type == "DEX" or file_type == "DEY" or file_type == "AXML" or file_type == "ARSC":
      if file_type == "APK":
        if androconf.is_valid_android_raw(fileraw):
          return (True, "APK")
      else:
        return (True, file_type)
    return (False, None) 
示例18
def getsig(apkpath):
    """Get the unique ID for the signing certificate of an APK.

    This uses a strange algorithm that was devised at the very
    beginning of F-Droid.  Since it is only used for checking
    signature compatibility, it does not matter much that it uses MD5.

    To get the same MD5 has that fdroidclient gets, we encode the .RSA
    certificate in a specific format and pass it hex-encoded to the
    md5 digest algorithm.  This is not the same as the standard X.509
    certificate fingerprint.

    :param apkpath: path to the apk
    :returns: A string containing the md5 of the signature of the apk or None
              if an error occurred.

    """

    cert_encoded = common.get_first_signer_certificate(apkpath)
    if not cert_encoded:
        return None
    return hashlib.md5(hexlify(cert_encoded)).hexdigest()  # nosec just used as ID for signing key 
示例19
def apk_parse_release_filename(apkname):
    """Parses the name of an APK file according the F-Droids APK naming
    scheme and returns the tokens.

    WARNING: Returned values don't necessarily represent the APKs actual
    properties, the are just paresed from the file name.

    :returns: A triplet containing (appid, versionCode, signer), where appid
        should be the package name, versionCode should be the integer
        represion of the APKs version and signer should be the first 7 hex
        digists of the sha256 signing key fingerprint which was used to sign
        this APK.
    """
    m = apk_release_filename_with_sigfp.match(apkname)
    if m:
        return m.group('appid'), m.group('vercode'), m.group('sigfp')
    m = apk_release_filename.match(apkname)
    if m:
        return m.group('appid'), m.group('vercode'), None
    return None, None, None 
示例20
def add(self, filename, raw_data=None, dx=None):
        """
        Generic method to add a file to the session.

        This is the main method to use when adding files to a Session!

        If an APK file is supplied, all DEX files are analyzed too.
        For DEX and ODEX files, only this file is analyzed (what else should be
        analyzed).

        Returns the SHA256 of the analyzed file.

        :param filename: filename to load
        :param raw_data: bytes of the file, or None to load the file from filename
        :param dx: An already exiting :class:`~androguard.core.analysis.analysis.Analysis` object
        :return: the sha256 of the file or None on failure
        """
        if not raw_data:
            log.debug("Loading file from '{}'".format(filename))
            with open(filename, "rb") as fp:
                raw_data = fp.read()

        ret = androconf.is_android_raw(raw_data)
        log.debug("Found filetype: '{}'".format(ret))
        if not ret:
            return None

        if ret == "APK":
            digest, _ = self.addAPK(filename, raw_data)
        elif ret == "DEX":
            digest, _, _ = self.addDEX(filename, raw_data, dx)
        elif ret == "DEY":
            digest, _, _ = self.addDEY(filename, raw_data, dx)
        else:
            return None

        return digest 
示例21
def get_filename_by_class(self, current_class):
        """
        Returns the filename of the DEX file where the class is in.

        Returns the first filename this class was present.
        For example, if you analyzed an APK, this should return the filename of
        the APK and not of the DEX file.

        :param current_class: ClassDefItem
        :returns: None if class was not found or the filename
        """
        for digest, dx in self.analyzed_vms.items():
            if dx.is_class_present(current_class.get_name()):
                return self.analyzed_digest[digest]
        return None 
示例22
def get_all_apks(self):
        """
        Yields a list of tuples of SHA256 hash of the APK and APK objects
        of all analyzed APKs in the Session.
        """
        for digest, a in self.analyzed_apk.items():
            yield digest, a 
示例23
def get_objects_apk(self, filename=None, digest=None):
        """
        Returns APK, DalvikVMFormat and Analysis of a specified APK.

        You must specify either `filename` or `digest`.
        It is possible to use both, but in this case only `digest` is used.

        example::

            s = Session()
            digest = s.add("some.apk")
            a, d, dx = s.get_objects_apk(digest=digest)

        example::

            s = Session()
            filename = "some.apk"
            digest = s.add(filename)
            a, d, dx = s.get_objects_apk(filename=filename)

        :param filename: the filename of the APK file, only used of digest is None
        :param digest: the sha256 hash, as returned by :meth:`add` for the APK
        :returns: a tuple of (APK, [DalvikVMFormat], Analysis)
        """
        if not filename and not digest:
            raise ValueError("Must give at least filename or digest!")

        if digest is None:
            digests = self.analyzed_files.get(filename)
            # Negate to reduce tree
            if not digests:
                return None, None, None
            digest = digests[0]

        a = self.analyzed_apk[digest][0]
        dx = self.analyzed_vms[digest]
        return a, dx.vms, dx 
示例24
def axml(input_, output, file_, resource):
    """
    Parse the AndroidManifest.xml.

    Parsing is either direct or from a given APK and prints in XML format or
    saves to file.

    This tool can also be used to process any AXML encoded file, for example
    from the layout directory.

    Example:

    \b
        $ androguard axml AndroidManifest.xml
    """
    if file_ is not None and input_ is not None:
        print("Can not give --input and positional argument! "
              "Please use only one of them!")
        sys.exit(1)

    if file_ is None and input_ is None:
        print("Give one file to decode!")
        sys.exit(1)

    if file_ is not None:
        androaxml_main(file_, output, resource)
    elif input_ is not None:
        androaxml_main(input_, output, resource) 
示例25
def cg(output,
       show,
       verbose,
       classname,
       methodname,
       descriptor,
       accessflag,
       no_isolated,
       apk):
    """
    Create a call graph and export it into a graph format.

    Example:

    \b
        $ androguard cg APK
    """
    androcg_main(verbose=verbose,
                 APK=apk,
                 classname=classname,
                 methodname=methodname,
                 descriptor=descriptor,
                 accessflag=accessflag,
                 no_isolated=no_isolated,
                 show=show,
                 output=output) 
示例26
def decompile(input_, file_, output, format_, jar, limit, decompiler):
    """
    Decompile an APK and create Control Flow Graphs.

    Example:

    \b
        $ androguard resources.arsc
    """
    from androguard import session
    if file_ and input_:
        print("Can not give --input and positional argument! "
              "Please use only one of them!", file=sys.stderr)
        sys.exit(1)

    if not input_ and not file_:
        print("Give one file to decode!", file=sys.stderr)
        sys.exit(1)

    if input_:
        fname = input_
    else:
        fname = file_

    s = session.Session()
    with open(fname, "rb") as fd:
        s.add(fname, fd.read())
    export_apps_to_format(fname, s, output, limit,
                          jar, decompiler, format_) 
示例27
def apkid(apks):
    """Return the packageName/versionCode/versionName per APK as JSON."""
    import json
    import logging
    logging.getLogger("androguard.axml").setLevel(logging.ERROR)
    results = dict()
    for apk in apks:
        results[apk] = androguard.core.bytecodes.apk.get_apkid(apk)
    print(json.dumps(results, indent=2)) 
示例28
def filter_file(self, log, fileraw):
        """
        This method is called in order to filer a specific app

        :param log: an object which corresponds to a unique app
        :param bytes fileraw: the raw file as bytes
        :rtype: a tuple with 2 elements, the return value (boolean) if it is necessary to
                continue the analysis and the file type
        """
        file_type = androconf.is_android_raw(fileraw)
        if file_type in ["APK", "DEX", "DEY", "AXML", "ARSC"]:
            return True, file_type
        return False, None 
示例29
def analysis_apk(self, log, apkobj):
        """
        This method is called in order to know if the analysis must continue

        :param log: an object which corresponds to a unique app
        :param androguard.core.bytecodes.apk.APK apkobj: a :class:`APK` object

        :returns: True if a DEX file should be analyzed as well
        :rtype: bool
        """
        return True 
示例30
def analysis_app(self, log, apkobj, dexobj, adexobj):
        """
        This method is called if you wish to analyse the final app

        :param log: an object which corresponds to a unique app
        :param androguard.core.bytecodes.apk.APK apkobj: a :class:`APK` object
        :param androguard.core.bytecodes.dvm.DalvikVMFormat dexobj: a :class:`DalvikVMFormat` object
        :param androguard.core.analysis.analysis.Analysis adexobj: a :class:`Analysis` object
        """
        pass