Skip to content

misc

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 get_default_session.

Parameters:

Name Type Description Default
_file Union[str, bytes]

the filename of the android application or a buffer which represents the application

required
session Union[Session, None]

A session (default: None)

None
raw bool

boolean if raw bytes are supplied instead of a filename

False

Returns:

Type Description
tuple[APK, list[DEX], Analysis]

the androguard.core.apk.APK, list of androguard.core.dex.DEX, and androguard.core.analysis.analysis.Analysis objects

Source code in androguard/misc.py
def AnalyzeAPK(
    _file: Union[str, bytes],
    session: Union[Session, None] = None,
    raw: bool = False,
) -> tuple[apk.APK, list[dex.DEX], Analysis]:
    """
    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 [get_default_session][androguard.misc.get_default_session].

    :param _file: the filename of the android application or a buffer which represents the application
    :param session: A session (default: None)
    :param raw: boolean if raw bytes are supplied instead of a filename
    :returns: the `androguard.core.apk.APK`, list of `androguard.core.dex.DEX`, and `androguard.core.analysis.analysis.Analysis` objects
    """
    logger.debug("AnalyzeAPK")

    if session:
        logger.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:
        logger.debug("Analysing without session")
        a = apk.APK(_file, raw=raw)
        # FIXME: probably it is not necessary to keep all DEXs, as
        # they are already part of Analysis. But when using sessions, it works
        # this way...
        d = []
        dx = Analysis()
        for dex_bytes in a.get_all_dex():
            df = dex.DEX(dex_bytes, using_api=a.get_target_sdk_version())
            dx.add(df)
            d.append(df)
            df.set_decompiler(decompiler.DecompilerDAD(df, dx))

        dx.create_xref()

        return a, d, dx

AnalyzeDex(filename, session=None, raw=False) #

Analyze an android dex file and setup all stuff for a more quickly analysis !

Parameters:

Name Type Description Default
filename str

the filename of the android dex file or a buffer which represents the dex file

required
session Session

A session (Default None)

None
raw bool

If set, filenam`` will be used as the odex's data (bytes). Defaults toFalse`

False

Returns:

Type Description
tuple[str, DEX, Analysis]

a tuple of (sha256hash, DEX, Analysis)

Source code in androguard/misc.py
def AnalyzeDex(
    filename: str, session: Session = None, raw: bool = False
) -> tuple[str, dex.DEX, Analysis]:
    """
    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
    :param session: A session (Default `None`)
    :param raw: If set, `filenam`` will be used as the odex's data (bytes). Defaults to `False`

    :returns: a tuple of (sha256hash, `DEX`, `Analysis`)
    """
    logger.debug("AnalyzeDex")

    if not session:
        session = get_default_session()

    if raw:
        data = filename
    else:
        with open(filename, "rb") as fd:
            data = fd.read()

    return session.addDEX(filename, data)

clean_file_name(filename, unique=True, replace='_', force_nt=False) #

Return a filename version, which has no characters in it which are forbidden. On Windows these are for example <, /, ?, ...

The intention of this function is to allow distribution of files to different OSes.

Parameters:

Name Type Description Default
filename str

string to clean

required
unique bool

check if the filename is already taken and append an integer to be unique (default: True)

True
replace str

replacement character. (default: '_')

'_'
force_nt bool

Force shortening of paths like on NT systems (default: False)

False

Returns:

Type Description
str

clean string

Source code in androguard/misc.py
def clean_file_name(
    filename: str,
    unique: bool = True,
    replace: str = "_",
    force_nt: bool = False,
) -> str:
    """
    Return a filename version, which has no characters in it which are forbidden.
    On Windows these are for example <, /, ?, ...

    The intention of this function is to allow distribution of files to different OSes.

    :param filename: string to clean
    :param unique: check if the filename is already taken and append an integer to be unique (default: `True`)
    :param replace: replacement character. (default: '_')
    :param force_nt: Force shortening of paths like on NT systems (default: `False`)
    :returns: clean string
    """

    if re.match(r'[<>:"/\\|?* .\x00-\x1f]', replace):
        raise ValueError("replacement character is not allowed!")

    path, fname = os.path.split(filename)
    # For Windows see: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
    # Other operating systems seems to be more tolerant...

    # Not allowed filenames, attach replace character if necessary
    if re.match(r'(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])', fname):
        fname += replace

    # reserved characters
    fname = re.sub(r'[<>:"/\\|?*\x00-\x1f]', replace, fname)
    # Do not end with dot or space
    fname = re.sub(r'[ .]$', replace, fname)

    # It is a sensible default, to assume that there is a hard 255 char limit per filename
    # See https://en.wikipedia.org/wiki/Comparison_of_file_systems
    # If you are using a filesystem with less, you have other problems ;)
    #
    # We simply make a hard cut after 255 chars. To leave some space for an extension, which might get added later,
    # There is room for improvement here, so feel free to implement a better method!
    PATH_MAX_LENGTH = 230  # give extra space for other stuff...
    # Check filename length limit, usually a problem on older Windows versions
    if len(fname) > PATH_MAX_LENGTH:
        if "." in fname:
            f, ext = fname.rsplit(".", 1)
            fname = "{}.{}".format(f[: PATH_MAX_LENGTH - (len(ext) + 1)], ext)
        else:
            fname = fname[:PATH_MAX_LENGTH]

    if force_nt or os.name == 'nt':
        # Special behaviour... On Windows, there is also a problem with the maximum path length in explorer.exe
        # maximum length is limited to 260 chars, so use 250 to have room for other stuff
        if len(os.path.abspath(os.path.join(path, fname))) > 250:
            fname = fname[: 250 - (len(os.path.abspath(path)) + 1)]

    if unique:
        counter = 0
        origname = fname
        while os.path.isfile(os.path.join(path, fname)):
            if "." in fname:
                # assume extension
                f, ext = origname.rsplit(".", 1)
                fname = "{}_{}.{}".format(f, counter, ext)
            else:
                fname = "{}_{}".format(origname, counter)
            counter += 1

    return os.path.join(path, fname)

get_default_session() #

Return the default Session from the configuration or create a new one, if the session in the configuration is None.

Returns:

Type Description
Session

androguard.session.Session object

Source code in androguard/misc.py
def get_default_session() -> Session:
    """
    Return the default [Session][androguard.session.Session] from the configuration
    or create a new one, if the session in the configuration is `None`.

    :returns: `androguard.session.Session` object
    """
    if androconf.CONF["SESSION"] is None:
        androconf.CONF["SESSION"] = Session()
    return androconf.CONF["SESSION"]