def dex_2_smali(app_dir, tools_dir):
    """Run dex2smali."""
    try:
        logger.info('DEX -> SMALI')
        dexes = get_dex_files(app_dir)
        for dex_path in dexes:
            logger.info('Converting %s to Smali Code',
                        filename_from_path(dex_path))
            if (len(settings.BACKSMALI_BINARY) > 0
                    and is_file_exists(settings.BACKSMALI_BINARY)):
                bs_path = settings.BACKSMALI_BINARY
            else:
                bs_path = os.path.join(tools_dir, 'baksmali-2.3.4.jar')
            output = os.path.join(app_dir, 'smali_source/')
            smali = [
                settings.JAVA_BINARY,
                '-jar',
                bs_path,
                'd',
                dex_path,
                '-o',
                output,
            ]
            trd = threading.Thread(target=subprocess.call, args=(smali, ))
            trd.daemon = True
            trd.start()
    except Exception:
        logger.exception('Converting DEX to SMALI')
def code_analysis(app_dir, typ):
    """Perform the code analysis."""
    try:
        logger.info('Static Android Code Analysis Started')
        root = Path(settings.BASE_DIR) / 'StaticAnalyzer' / 'views'
        code_rules = root / 'android' / 'rules' / 'android_rules.yaml'
        api_rules = root / 'android' / 'rules' / 'android_apis.yaml'
        code_findings = {}
        api_findings = {}
        email_n_file = []
        url_n_file = []
        url_list = []
        app_dir = Path(app_dir)
        if typ == 'apk':
            src = app_dir / 'java_source'
        elif typ == 'studio':
            src = app_dir / 'app' / 'src' / 'main' / 'java'
            kt = app_dir / 'app' / 'src' / 'main' / 'kotlin'
            if not src.exists() and kt.exists():
                src = kt
        elif typ == 'eclipse':
            src = app_dir / 'src'
        src = src.as_posix() + '/'
        logger.info('Code Analysis Started on - %s', filename_from_path(src))

        # Code and API Analysis
        code_findings = scan(code_rules.as_posix(), {'.java', '.kt'}, [src],
                             settings.SKIP_CLASS_PATH)
        api_findings = scan(api_rules.as_posix(), {'.java', '.kt'}, [src],
                            settings.SKIP_CLASS_PATH)

        skp = settings.SKIP_CLASS_PATH
        # Extract URLs and Emails
        for pfile in Path(src).rglob('*'):
            if ((pfile.suffix in ('.java', '.kt')
                 and any(skip_path in pfile.as_posix()
                         for skip_path in skp) is False)):
                content = None
                try:
                    content = pfile.read_text('utf-8', 'ignore')
                    # Certain file path cannot be read in windows
                except Exception:
                    continue
                relative_java_path = pfile.as_posix().replace(src, '')
                urls, urls_nf, emails_nf = url_n_email_extract(
                    content, relative_java_path)
                url_list.extend(urls)
                url_n_file.extend(urls_nf)
                email_n_file.extend(emails_nf)
        logger.info('Finished Code Analysis, Email and URL Extraction')
        code_an_dic = {
            'api': api_findings,
            'findings': code_findings,
            'urls_list': url_list,
            'urls': url_n_file,
            'emails': email_n_file,
        }
        return code_an_dic
    except Exception:
        logger.exception('Performing Code Analysis')
def apkid_analysis(app_dir, apk_file, apk_name):
    """APKiD Analysis of DEX files"""
    apkid_res = {}
    if not settings.APKID_ENABLED:
        return apkid_res
    if not os.path.exists(apk_file):
        logger.error("APKiD - APK not found")
        return {'error': True}
    dest_dir = os.path.join(app_dir, "apkid")
    file_name = filename_from_path(apk_file)
    report_file = file_name + "_apkid.json"
    report = os.path.join(dest_dir, report_file)
    temporary_apk = os.path.join(dest_dir, file_name)
    if os.path.exists(dest_dir):
        shutil.rmtree(dest_dir)
    os.mkdir(dest_dir)
    shutil.copy2(apk_file, dest_dir)
    from apkid import apkid
    from apkid import __version__ as apkid_ver
    logger.info("Running APKiD %s on: %s", apkid_ver, file_name)
    result = apkid.scan(dest_dir, 30, True, dest_dir, True)
    with open(report, 'r') as f:
        result = json.load(f)
    for filep, res in result.items():
        try:
            dex_file = filep.rsplit("!", 1)[1]
        except Exception:
            #dex_file = filename_from_path(filep)
            dex_file = apk_name
        apkid_res[dex_file] = res
    shutil.rmtree(dest_dir)
    return apkid_res
def apkid_analysis(app_dir, apk_file, apk_name):
    """APKiD Analysis of DEX files"""
    apkid_res = {}
    if not settings.APKID_ENABLED:
        return apkid_res
    if not os.path.exists(apk_file):
        logger.error("APKiD - APK not found")
        return {'error': True}
    dest_dir = os.path.join(app_dir, "apkid")
    file_name = filename_from_path(apk_file)
    report_file = file_name + "_apkid.json"
    report = os.path.join(dest_dir, report_file)
    temporary_apk = os.path.join(dest_dir, file_name)
    if os.path.exists(dest_dir):
        shutil.rmtree(dest_dir)
    os.mkdir(dest_dir)
    shutil.copy2(apk_file, dest_dir)
    from apkid import apkid
    from apkid import __version__ as apkid_ver
    logger.info("Running APKiD %s on: %s", apkid_ver,
                file_name)
    result = apkid.scan(dest_dir, 30, True, dest_dir, True)
    with open(report, 'r') as f:
        result = json.load(f)
    for filep, res in result.items():
        try:
            dex_file = filep.rsplit("!", 1)[1]
        except Exception:
            #dex_file = filename_from_path(filep)
            dex_file = apk_name
        apkid_res[dex_file] = res
    shutil.rmtree(dest_dir)
    return apkid_res
Ejemplo n.º 5
0
def dex_2_jar(app_path, app_dir, tools_dir):
    """Run dex2jar."""
    try:
        logger.info("DEX -> JAR")
        working_dir = None
        args = []

        if settings.JAR_CONVERTER == "d2j":
            logger.info("Using JAR converter - dex2jar")
            dexes = get_dex_files(app_dir)
            for idx, dex in enumerate(dexes):
                logger.info("Converting " + filename_from_path(dex) +
                            " to JAR")
                if len(settings.DEX2JAR_BINARY) > 0 and isFileExists(
                        settings.DEX2JAR_BINARY):
                    d2j = settings.DEX2JAR_BINARY
                else:
                    if platform.system() == "Windows":
                        win_fix_java(tools_dir)
                        d2j = os.path.join(tools_dir, 'd2j2/d2j-dex2jar.bat')
                    else:
                        inv = os.path.join(tools_dir, 'd2j2/d2j_invoke.sh')
                        d2j = os.path.join(tools_dir, 'd2j2/d2j-dex2jar.sh')
                        subprocess.call(["chmod", "777", d2j])
                        subprocess.call(["chmod", "777", inv])
                args = [
                    d2j, dex, '-f', '-o',
                    app_dir + 'classes' + str(idx) + '.jar'
                ]
                subprocess.call(args)

        elif settings.JAR_CONVERTER == "enjarify":
            logger.info("Using JAR converter - Google enjarify")
            if len(settings.ENJARIFY_DIRECTORY) > 0 and isDirExists(
                    settings.ENJARIFY_DIRECTORY):
                working_dir = settings.ENJARIFY_DIRECTORY
            else:
                working_dir = os.path.join(tools_dir, 'enjarify/')
            if platform.system() == "Windows":
                win_fix_python3(tools_dir)
                enjarify = os.path.join(working_dir, 'enjarify.bat')
                args = [
                    enjarify, app_path, "-f", "-o", app_dir + 'classes.jar'
                ]
            else:
                if len(settings.PYTHON3_PATH) > 2:
                    python3 = os.path.join(settings.PYTHON3_PATH, "python3")
                else:
                    python3 = get_python()
                args = [
                    python3, "-O", "-m", "enjarify.main", app_path, "-f", "-o",
                    app_dir + 'classes.jar'
                ]
            subprocess.call(args, cwd=working_dir)
    except:
        PrintException("Converting Dex to JAR")
def jar_2_java(app_dir, tools_dir):
    """Conver jar to java."""
    try:
        logger.info('JAR -> JAVA')
        jar_files = get_jar_files(app_dir)
        output = os.path.join(app_dir, 'java_source/')
        for jar_path in jar_files:
            logger.info(
                'Decompiling %s to Java Code',
                filename_from_path(jar_path))
            if settings.DECOMPILER == 'jd-core':
                ext_jdcore = settings.JD_CORE_DECOMPILER_BINARY
                if (len(ext_jdcore) > 0
                        and is_file_exists(ext_jdcore)):
                    jd_path = ext_jdcore
                else:
                    jd_path = os.path.join(tools_dir, 'jd-core.jar')
                args = [settings.JAVA_BINARY,
                        '-jar',
                        jd_path,
                        jar_path,
                        output]
            elif settings.DECOMPILER == 'cfr':
                ext_cfr = settings.CFR_DECOMPILER_BINARY
                if (len(ext_cfr) > 0
                        and is_file_exists(ext_cfr)):
                    jd_path = ext_cfr
                else:
                    jd_path = os.path.join(tools_dir, 'cfr-0.144.jar')
                args = [settings.JAVA_BINARY,
                        '-jar',
                        jd_path,
                        jar_path,
                        '--outputdir',
                        output,
                        '--silent',
                        'true']
            elif settings.DECOMPILER == 'procyon':
                ext_proc = settings.PROCYON_DECOMPILER_BINARY
                if (len(ext_proc) > 0
                        and is_file_exists(ext_proc)):
                    pd_path = ext_proc
                else:
                    pd_path = os.path.join(
                        tools_dir, 'procyon-decompiler-0.5.34.jar')
                args = [settings.JAVA_BINARY,
                        '-jar',
                        pd_path,
                        jar_path,
                        '-o',
                        output]
            subprocess.call(args)
    except Exception:
        logger.exception('Converting JAR to JAVA')
Ejemplo n.º 7
0
def apkid_analysis(app_dir, apk_file):
    """APKiD Analysis of DEX files"""
    apkid_res = {}
    if not settings.APKID_ENABLED:
        return apkid_res
    if not os.path.exists(apk_file):
        logger.error("APKiD - APK not found")
        return {'error': True}
    from apkid import apkid
    from apkid import __version__ as apkid_ver
    logger.info("Running APKiD %s on: %s", apkid_ver,
                filename_from_path(apk_file))
    result = apkid.scan_apk(apk_file, 30, True)
    for filep, res in result.items():
        dex_file = filep.rsplit("!", 1)[1]
        apkid_res[dex_file] = res
    return apkid_res
Ejemplo n.º 8
0
def jar_2_java(app_dir, tools_dir):
    """Conver jar to java."""
    try:
        logger.info("JAR -> JAVA")
        jar_files = get_jar_files(app_dir)
        output = os.path.join(app_dir, 'java_source/')
        for jar_path in jar_files:
            logger.info("Decompiling {} to Java Code".format(
                filename_from_path(jar_path)))
            if settings.DECOMPILER == 'jd-core':
                if (len(settings.JD_CORE_DECOMPILER_BINARY) > 0
                        and isFileExists(settings.JD_CORE_DECOMPILER_BINARY)):
                    jd_path = settings.JD_CORE_DECOMPILER_BINARY
                else:
                    jd_path = os.path.join(tools_dir, 'jd-core.jar')
                args = [
                    settings.JAVA_PATH + 'java', '-jar', jd_path, jar_path,
                    output
                ]
            elif settings.DECOMPILER == 'cfr':
                if (len(settings.CFR_DECOMPILER_BINARY) > 0
                        and isFileExists(settings.CFR_DECOMPILER_BINARY)):
                    jd_path = settings.CFR_DECOMPILER_BINARY
                else:
                    jd_path = os.path.join(tools_dir, 'cfr-0.144.jar')
                args = [
                    settings.JAVA_PATH + 'java', '-jar', jd_path, jar_path,
                    '--outputdir', output, '--silent', 'true'
                ]
            elif settings.DECOMPILER == "procyon":
                if (len(settings.PROCYON_DECOMPILER_BINARY) > 0
                        and isFileExists(settings.PROCYON_DECOMPILER_BINARY)):
                    pd_path = settings.PROCYON_DECOMPILER_BINARY
                else:
                    pd_path = os.path.join(tools_dir,
                                           'procyon-decompiler-0.5.34.jar')
                args = [
                    settings.JAVA_PATH + 'java', '-jar', pd_path, jar_path,
                    '-o', output
                ]
            subprocess.call(args)
    except:
        PrintException("Converting JAR to JAVA")
def dex_2_smali(app_dir, tools_dir):
    """Run dex2smali"""
    try:
        logger.info("DEX -> SMALI")
        dexes = get_dex_files(app_dir)
        for dex_path in dexes:
            logger.info("Converting " +
                        filename_from_path(dex_path) + " to Smali Code")
            if len(settings.BACKSMALI_BINARY) > 0 and isFileExists(settings.BACKSMALI_BINARY):
                bs_path = settings.BACKSMALI_BINARY
            else:
                bs_path = os.path.join(tools_dir, 'baksmali-2.2.7.jar')
            output = os.path.join(app_dir, 'smali_source/')
            args = [
                settings.JAVA_PATH + 'java',
                '-jar', bs_path, 'd', dex_path, '-o', output
            ]
            subprocess.call(args)
    except:
        PrintException("Converting DEX to SMALI")
def apkid_analysis(app_dir, apk_file, apk_name):
    """APKiD Analysis of DEX files"""
    apkid_res = {}
    if not settings.APKID_ENABLED:
        return apkid_res
    if not os.path.exists(apk_file):
        logger.error("APKiD - APK not found")
        return {'error': True}
    from apkid import __version__ as apkid_ver
    from apkid.apkid import Scanner, Options
    logger.info("Running APKiD")
    dest_dir = os.path.join(app_dir, "apkid")
    options = Options(
        timeout=30,
        verbose=None,
        json=True,
        output_dir=dest_dir,
        typing=None,
        entry_max_scan_size=100 * 1024 * 1024,
        scan_depth=2,
        recursive=True
    )
    rules = options.rules_manager.load()
    scanner = Scanner(rules, options)
    scanner.scan(apk_file)
    file_name = filename_from_path(apk_file)
    report_file = file_name + "_apkid.json"
    report = os.path.join(dest_dir, report_file)
    with open(report, 'r') as flip:
        result = json.load(flip)
    for filep, res in result.items():
        try:
            dex_file = filep.rsplit("!", 1)[1]
        except Exception:
            dex_file = apk_name
        apkid_res[dex_file] = res
    return apkid_res
def dex_2_jar(app_path, app_dir, tools_dir):
    """Run dex2jar."""
    try:
        logger.info('DEX -> JAR')
        working_dir = None
        args = []

        if settings.JAR_CONVERTER == 'd2j':
            logger.info('Using JAR converter - dex2jar')
            dexes = get_dex_files(app_dir)
            for idx, dex in enumerate(dexes):
                logger.info('Converting %s to JAR', filename_from_path(dex))
                if (len(settings.DEX2JAR_BINARY) > 0
                        and is_file_exists(settings.DEX2JAR_BINARY)):
                    d2j = settings.DEX2JAR_BINARY
                else:
                    if platform.system() == 'Windows':
                        win_fix_java(tools_dir)
                        d2j = os.path.join(tools_dir, 'd2j2/d2j-dex2jar.bat')
                    else:
                        inv = os.path.join(tools_dir, 'd2j2/d2j_invoke.sh')
                        d2j = os.path.join(tools_dir, 'd2j2/d2j-dex2jar.sh')
                        os.chmod(d2j, 0o777)
                        os.chmod(inv, 0o777)
                args = [
                    d2j,
                    dex,
                    '-f',
                    '-o',
                    app_dir + 'classes' + str(idx) + '.jar',
                ]
                subprocess.call(args)

        elif settings.JAR_CONVERTER == 'enjarify':
            logger.info('Using JAR converter - Google enjarify')
            if (len(settings.ENJARIFY_DIRECTORY) > 0
                    and is_dir_exists(settings.ENJARIFY_DIRECTORY)):
                working_dir = settings.ENJARIFY_DIRECTORY
            else:
                working_dir = os.path.join(tools_dir, 'enjarify/')
            if platform.system() == 'Windows':
                win_fix_python3(tools_dir)
                enjarify = os.path.join(working_dir, 'enjarify.bat')
                args = [
                    enjarify, app_path, '-f', '-o', app_dir + 'classes.jar'
                ]
            else:
                if len(settings.PYTHON3_PATH) > 2:
                    python3 = os.path.join(settings.PYTHON3_PATH, 'python3')
                else:
                    python3 = get_python()
                args = [
                    python3,
                    '-O',
                    '-m',
                    'enjarify.main',
                    app_path,
                    '-f',
                    '-o',
                    app_dir + 'classes.jar',
                ]
            subprocess.call(args, cwd=working_dir)
    except Exception:
        logger.exception('Converting Dex to JAR')
Ejemplo n.º 12
0
def code_analysis(app_dir, perms, typ):
    """Perform the code analysis."""
    try:
        logger.info('Static Android Code Analysis Started')
        api_rules = android_apis.APIS
        code_rules = android_rules.RULES
        code_findings = {}
        api_findings = {}
        email_n_file = []
        url_n_file = []
        url_list = []
        logger.info("code_findings-%s" % code_findings)
        if typ == 'apk':
            java_src = os.path.join(app_dir, 'java_source/')
        elif typ == 'studio':
            java_src = os.path.join(app_dir, 'app/src/main/java/')
        elif typ == 'eclipse':
            java_src = os.path.join(app_dir, 'src/')
        logger.info('Code Analysis Started on - %s',
                    filename_from_path(java_src))
        # pylint: disable=unused-variable
        # Needed by os.walk
        for dir_name, _sub_dir, files in os.walk(java_src):
            for jfile in files:
                jfile_path = os.path.join(java_src, dir_name, jfile)
                if '+' in jfile:
                    p_2 = os.path.join(java_src, dir_name,
                                       jfile.replace('+', 'x'))
                    shutil.move(jfile_path, p_2)
                    jfile_path = p_2
                repath = dir_name.replace(java_src, '') + '/'
                if (jfile.endswith('.java') and any(
                        re.search(cls, repath)
                        for cls in settings.SKIP_CLASSES) is False):
                    dat = ''
                    with io.open(
                            jfile_path,
                            mode='r',
                            encoding='utf8',
                            errors='ignore',
                    ) as file_pointer:
                        dat = file_pointer.read()

                    # Code Analysis
                    relative_java_path = jfile_path.replace(java_src, '')
                    code_rule_matcher(code_findings, list(perms.keys()), dat,
                                      relative_java_path, code_rules)
                    # API Check
                    api_rule_matcher(api_findings, list(perms.keys()), dat,
                                     relative_java_path, api_rules)
                    # Extract URLs and Emails
                    urls, urls_nf, emails_nf = url_n_email_extract(
                        dat, relative_java_path)
                    url_list.extend(urls)
                    url_n_file.extend(urls_nf)
                    email_n_file.extend(emails_nf)
        logger.info('Finished Code Analysis, Email and URL Extraction')
        code_an_dic = {
            'api': api_findings,
            'findings': code_findings,
            'urls_list': url_list,
            'urls': url_n_file,
            'emails': email_n_file,
        }
        return code_an_dic
    except Exception:
        logger.exception('Performing Code Analysis')
Ejemplo n.º 13
0
def code_analysis(app_dir, perms, typ):
    """Perform the code analysis."""
    try:
        logger.info("Static Android Code Analysis Started")
        api_rules = android_apis.APIS
        code_rules = android_rules.RULES
        code_findings = {}
        api_findings = {}
        email_n_file = []
        url_n_file = []
        url_list = []
        domains = {}

        if typ == "apk":
            java_src = os.path.join(app_dir, 'java_source/')
        elif typ == "studio":
            java_src = os.path.join(app_dir, 'app/src/main/java/')
        elif typ == "eclipse":
            java_src = os.path.join(app_dir, 'src/')
        logger.info("Code Analysis Started on - " +
                    filename_from_path(java_src))
        # pylint: disable=unused-variable
        # Needed by os.walk
        for dir_name, sub_dir, files in os.walk(java_src):
            for jfile in files:
                jfile_path = os.path.join(java_src, dir_name, jfile)
                if "+" in jfile:
                    p_2 = os.path.join(java_src, dir_name,
                                       jfile.replace("+", "x"))
                    shutil.move(jfile_path, p_2)
                    jfile_path = p_2
                repath = dir_name.replace(java_src, '')
                if (jfile.endswith('.java') and any(
                        re.search(cls, repath)
                        for cls in settings.SKIP_CLASSES) is False):
                    dat = ''
                    with io.open(jfile_path,
                                 mode='r',
                                 encoding="utf8",
                                 errors="ignore") as file_pointer:
                        dat = file_pointer.read()

                    # Code Analysis
                    # print "[INFO] Doing Code Analysis on - " + jfile_path
                    relative_java_path = jfile_path.replace(java_src, '')
                    code_rule_matcher(code_findings, list(perms.keys()), dat,
                                      relative_java_path, code_rules)
                    # API Check
                    api_rule_matcher(api_findings, list(perms.keys()), dat,
                                     relative_java_path, api_rules)
                    # Extract URLs and Emails
                    urls, urls_nf, emails_nf = url_n_email_extract(
                        dat, relative_java_path)
                    url_list.extend(urls)
                    url_n_file.extend(urls_nf)
                    email_n_file.extend(emails_nf)
        # Domain Extraction and Malware Check
        logger.info("Performing Malware Check on extracted Domains")
        domains = malware_check(list(set(url_list)))
        logger.info("Finished Code Analysis, Email and URL Extraction")
        code_an_dic = {
            'api': api_findings,
            'findings': code_findings,
            'urls': url_n_file,
            'domains': domains,
            'emails': email_n_file,
        }
        return code_an_dic
    except:
        PrintException("Performing Code Analysis")
def code_analysis(app_dir, perms, typ):
    """Perform the code analysis."""
    try:
        logger.info("Static Android Code Analysis Started")
        api_rules = android_apis.APIS
        code_rules = android_rules.RULES
        code_findings = {}
        api_findings = {}
        email_n_file = []
        url_n_file = []
        url_list = []
        domains = {}

        if typ == "apk":
            java_src = os.path.join(app_dir, 'java_source/')
        elif typ == "studio":
            java_src = os.path.join(app_dir, 'app/src/main/java/')
        elif typ == "eclipse":
            java_src = os.path.join(app_dir, 'src/')
        logger.info("Code Analysis Started on - " + filename_from_path(java_src))
        # pylint: disable=unused-variable
        # Needed by os.walk
        for dir_name, sub_dir, files in os.walk(java_src):
            for jfile in files:
                jfile_path = os.path.join(java_src, dir_name, jfile)
                if "+" in jfile:
                    p_2 = os.path.join(java_src, dir_name,
                                       jfile.replace("+", "x"))
                    shutil.move(jfile_path, p_2)
                    jfile_path = p_2
                repath = dir_name.replace(java_src, '')
                if (
                        jfile.endswith('.java') and
                        any(re.search(cls, repath)
                            for cls in settings.SKIP_CLASSES) is False
                ):
                    dat = ''
                    with io.open(
                        jfile_path,
                        mode='r',
                        encoding="utf8",
                        errors="ignore"
                    ) as file_pointer:
                        dat = file_pointer.read()

                    # Code Analysis
                    # print "[INFO] Doing Code Analysis on - " + jfile_path
                    relative_java_path = jfile_path.replace(java_src, '')
                    code_rule_matcher(
                        code_findings, list(perms.keys()), dat, relative_java_path, code_rules)
                    # API Check
                    api_rule_matcher(api_findings, list(perms.keys()),
                                     dat, relative_java_path, api_rules)
                     # Extract URLs and Emails
                    urls, urls_nf, emails_nf = url_n_email_extract(dat, relative_java_path)
                    url_list.extend(urls)
                    url_n_file.extend(urls_nf)
                    email_n_file.extend(emails_nf)
        logger.info("Finished Code Analysis, Email and URL Extraction")
        code_an_dic = {
            'api': api_findings,
            'findings': code_findings,
            'urls_list': url_list,
            'urls': url_n_file,
            'emails': email_n_file,
        }
        return code_an_dic
    except:
        PrintException("Performing Code Analysis")