# Buggy code
def static_analyzer(request, api=False):
    """Do static analysis on an request and save to db."""
    try:
        if api:
            typ = request.POST["scan_type"]
            checksum = request.POST["hash"]
            filename = request.POST["file_name"]
            rescan = str(request.POST.get("re_scan", 0))
        else:
            typ = request.GET["type"]
            checksum = request.GET["checksum"]
            filename = request.GET["name"]
            rescan = str(request.GET.get("rescan", 0))
        # Input validation
        app_dic = {}
        match = re.match("^[0-9a-f]{32}$", checksum)
        if (
            (match)
            and (filename.lower().endswith(".apk") or filename.lower().endswith(".zip"))
            and (typ in ["zip", "apk"])
        ):
            app_dic["dir"] = settings.BASE_DIR  # BASE DIR
            app_dic["app_name"] = filename  # APP ORGINAL NAME
            app_dic["md5"] = checksum  # MD5
            app_dic["app_dir"] = os.path.join(
                settings.UPLD_DIR, app_dic["md5"] + "/"
            )  # APP DIRECTORY
            app_dic["tools_dir"] = os.path.join(
                app_dic["dir"], "StaticAnalyzer/tools/"
            )  # TOOLS DIR
            # DWD_DIR = settings.DWD_DIR # not needed? Var is never used.
            logger.info("Starting Analysis on : " + app_dic["app_name"])

            if typ == "apk":
                # Check if in DB
                # pylint: disable=E1101
                db_entry = StaticAnalyzerAndroid.objects.filter(MD5=app_dic["md5"])
                if db_entry.exists() and rescan == "0":
                    context = get_context_from_db_entry(db_entry)
                else:
                    app_dic["app_file"] = app_dic["md5"] + ".apk"  # NEW FILENAME
                    app_dic["app_path"] = (
                        app_dic["app_dir"] + app_dic["app_file"]
                    )  # APP PATH

                    # ANALYSIS BEGINS
                    app_dic["size"] = (
                        str(file_size(app_dic["app_path"])) + "MB"
                    )  # FILE SIZE
                    app_dic["sha1"], app_dic["sha256"] = hash_gen(app_dic["app_path"])

                    app_dic["files"] = unzip(app_dic["app_path"], app_dic["app_dir"])
                    app_dic["certz"] = get_hardcoded_cert_keystore(app_dic["files"])

                    logger.info("APK Extracted")

                    # Manifest XML
                    app_dic["parsed_xml"] = get_manifest(
                        app_dic["app_path"],
                        app_dic["app_dir"],
                        app_dic["tools_dir"],
                        "",
                        True,
                    )

                    # Get icon
                    res_path = os.path.join(app_dic["app_dir"], "res")
                    app_dic["icon_hidden"] = True
                    # Even if the icon is hidden, try to guess it by the
                    # default paths
                    app_dic["icon_found"] = False
                    app_dic["icon_path"] = ""
                    # TODO: Check for possible different names for resource
                    # folder?
                    if os.path.exists(res_path):
                        icon_dic = get_icon(app_dic["app_path"], res_path)
                        if icon_dic:
                            app_dic["icon_hidden"] = icon_dic["hidden"]
                            app_dic["icon_found"] = bool(icon_dic["path"])
                            app_dic["icon_path"] = icon_dic["path"]

                    # Set Manifest link
                    app_dic["mani"] = (
                        "../ManifestView/?md5=" + app_dic["md5"] + "&type=apk&bin=1"
                    )
                    man_data_dic = manifest_data(app_dic["parsed_xml"])

                    man_an_dic = manifest_analysis(app_dic["parsed_xml"], man_data_dic)
                    bin_an_buff = []
                    bin_an_buff += elf_analysis(app_dic["app_dir"])
                    bin_an_buff += res_analysis(app_dic["app_dir"])
                    cert_dic = cert_info(app_dic["app_dir"], app_dic["tools_dir"])
                    apkid_results = apkid_analysis(
                        app_dic["app_dir"], app_dic["app_path"]
                    )
                    dex_2_jar(
                        app_dic["app_path"], app_dic["app_dir"], app_dic["tools_dir"]
                    )
                    dex_2_smali(app_dic["app_dir"], app_dic["tools_dir"])
                    jar_2_java(app_dic["app_dir"], app_dic["tools_dir"])
                    code_an_dic = code_analysis(
                        app_dic["app_dir"], man_an_dic["permissons"], "apk"
                    )
                    logger.info("Generating Java and Smali Downloads")
                    gen_downloads(
                        app_dic["app_dir"], app_dic["md5"], app_dic["icon_path"]
                    )

                    # Get the strings
                    app_dic["strings"] = strings_jar(
                        app_dic["app_file"], app_dic["app_dir"]
                    )
                    app_dic["zipped"] = "&type=apk"

                    logger.info("Connecting to Database")
                    try:
                        # SAVE TO DB
                        if rescan == "1":
                            logger.info("Updating Database...")
                            update_db_entry(
                                app_dic,
                                man_data_dic,
                                man_an_dic,
                                code_an_dic,
                                cert_dic,
                                bin_an_buff,
                                apkid_results,
                            )
                        elif rescan == "0":
                            logger.info("Saving to Database")
                            create_db_entry(
                                app_dic,
                                man_data_dic,
                                man_an_dic,
                                code_an_dic,
                                cert_dic,
                                bin_an_buff,
                                apkid_results,
                            )
                    except:
                        PrintException("[ERROR] Saving to Database Failed")
                    context = get_context_from_analysis(
                        app_dic,
                        man_data_dic,
                        man_an_dic,
                        code_an_dic,
                        cert_dic,
                        bin_an_buff,
                        apkid_results,
                    )
                context["average_cvss"], context["security_score"] = score(
                    context["findings"]
                )
                context["dynamic_analysis_done"] = os.path.exists(
                    os.path.join(app_dic["app_dir"], "logcat.txt")
                )

                context["VT_RESULT"] = None
                if settings.VT_ENABLED:
                    vt = VirusTotal.VirusTotal()
                    context["VT_RESULT"] = vt.get_result(
                        os.path.join(app_dic["app_dir"], app_dic["md5"]) + ".apk",
                        app_dic["md5"],
                    )
                template = "static_analysis/static_analysis.html"
                if api:
                    return context
                else:
                    return render(request, template, context)
            elif typ == "zip":
                # Check if in DB
                # pylint: disable=E1101
                cert_dic = {}
                cert_dic["cert_info"] = ""
                cert_dic["issued"] = ""
                cert_dic["sha256Digest"] = False
                bin_an_buff = []
                app_dic["strings"] = ""
                app_dic["zipped"] = ""
                # Above fields are only available for APK and not ZIP
                db_entry = StaticAnalyzerAndroid.objects.filter(MD5=app_dic["md5"])
                if db_entry.exists() and rescan == "0":
                    context = get_context_from_db_entry(db_entry)
                else:
                    app_dic["app_file"] = app_dic["md5"] + ".zip"  # NEW FILENAME
                    app_dic["app_path"] = (
                        app_dic["app_dir"] + app_dic["app_file"]
                    )  # APP PATH
                    logger.info("Extracting ZIP")
                    app_dic["files"] = unzip(app_dic["app_path"], app_dic["app_dir"])
                    # Check if Valid Directory Structure and get ZIP Type
                    pro_type, valid = valid_android_zip(app_dic["app_dir"])
                    if valid and pro_type == "ios":
                        logger.info("Redirecting to iOS Source Code Analyzer")
                        if api:
                            return {"type": "ios"}
                        else:
                            return HttpResponseRedirect(
                                "/StaticAnalyzer_iOS/?name="
                                + app_dic["app_name"]
                                + "&type=ios&checksum="
                                + app_dic["md5"]
                            )
                    app_dic["certz"] = get_hardcoded_cert_keystore(app_dic["files"])
                    app_dic["zipped"] = pro_type
                    logger.info("ZIP Type - " + pro_type)
                    if valid and (pro_type in ["eclipse", "studio"]):
                        # ANALYSIS BEGINS
                        app_dic["size"] = (
                            str(file_size(app_dic["app_path"])) + "MB"
                        )  # FILE SIZE
                        app_dic["sha1"], app_dic["sha256"] = hash_gen(
                            app_dic["app_path"]
                        )

                        # Manifest XML
                        app_dic["persed_xml"] = get_manifest(
                            "",
                            app_dic["app_dir"],
                            app_dic["tools_dir"],
                            pro_type,
                            False,
                        )

                        # Set manifest view link
                        app_dic["mani"] = (
                            "../ManifestView/?md5="
                            + app_dic["md5"]
                            + "&type="
                            + pro_type
                            + "&bin=0"
                        )

                        man_data_dic = manifest_data(app_dic["persed_xml"])

                        man_an_dic = manifest_analysis(
                            app_dic["persed_xml"], man_data_dic
                        )

                        # Get icon
                        eclipse_res_path = os.path.join(app_dic["app_dir"], "res")
                        studio_res_path = os.path.join(
                            app_dic["app_dir"], "app", "src", "main", "res"
                        )
                        if os.path.exists(eclipse_res_path):
                            res_path = eclipse_res_path
                        elif os.path.exists(studio_res_path):
                            res_path = studio_res_path
                        else:
                            res_path = ""

                        app_dic["icon_hidden"] = man_an_dic["icon_hidden"]
                        app_dic["icon_found"] = False
                        app_dic["icon_path"] = ""
                        if res_path:
                            app_dic["icon_path"] = find_icon_path_zip(
                                res_path, man_data_dic["icons"]
                            )
                            if app_dic["icon_path"]:
                                app_dic["icon_found"] = True

                        if app_dic["icon_path"]:
                            if os.path.exists(app_dic["icon_path"]):
                                shutil.copy2(
                                    app_dic["icon_path"],
                                    os.path.join(
                                        settings.DWD_DIR, app_dic["md5"] + "-icon.png"
                                    ),
                                )

                        code_an_dic = code_analysis(
                            app_dic["app_dir"], man_an_dic["permissons"], pro_type
                        )
                        logger.info("Connecting to Database")
                        try:
                            # SAVE TO DB
                            if rescan == "1":
                                logger.info("Updating Database...")
                                update_db_entry(
                                    app_dic,
                                    man_data_dic,
                                    man_an_dic,
                                    code_an_dic,
                                    cert_dic,
                                    bin_an_buff,
                                    {},
                                )
                            elif rescan == "0":
                                logger.info("Saving to Database")
                                create_db_entry(
                                    app_dic,
                                    man_data_dic,
                                    man_an_dic,
                                    code_an_dic,
                                    cert_dic,
                                    bin_an_buff,
                                    {},
                                )
                        except:
                            PrintException("[ERROR] Saving to Database Failed")
                        context = get_context_from_analysis(
                            app_dic,
                            man_data_dic,
                            man_an_dic,
                            code_an_dic,
                            cert_dic,
                            bin_an_buff,
                            {},
                        )
                    else:
                        msg = "This ZIP Format is not supported"
                        if api:
                            return print_n_send_error_response(request, msg, True)
                        else:
                            print_n_send_error_response(request, msg, False)
                            return HttpResponseRedirect("/zip_format/")
                context["average_cvss"], context["security_score"] = score(
                    context["findings"]
                )
                template = "static_analysis/static_analysis_android_zip.html"
                if api:
                    return context
                else:
                    return render(request, template, context)
            else:
                logger.error(
                    "Only APK,IPA and Zipped Android/iOS Source code supported now!"
                )
        else:
            msg = "Hash match failed or Invalid file extension or file type"
            if api:
                return print_n_send_error_response(request, msg, True)
            else:
                return print_n_send_error_response(request, msg, False)

    except Exception as excep:
        msg = str(excep)
        exp = excep.__doc__
        if api:
            return print_n_send_error_response(request, msg, True, exp)
        else:
            return print_n_send_error_response(request, msg, False, exp)


# Traceback (KeyError)
[INFO] 08/Feb/2019 16:17:54 - VM Starting
[INFO] 08/Feb/2019 16:17:55 - "POST /DynamicAnalyzer/ HTTP/1.1" 200 32400
[INFO] 08/Feb/2019 16:17:55 - "GET /static/css/devices.min.css HTTP/1.1" 200 44241
[INFO] 08/Feb/2019 16:17:55 - "GET /download/screen/screen.png HTTP/1.1" 302 0
[DEBUG] 08/Feb/2019 16:17:55 - Exception while resolving variable 'exp' in template 'general/error.html'.
Traceback (most recent call last):
File "/home/userhome/Mobile-Security-Framework-MobSF/venv/lib/python3.6/site-packages/django/template/base.py", line 829, in _resolve_lookup
current = current[bit]
File "/home/userhome/Mobile-Security-Framework-MobSF/venv/lib/python3.6/site-packages/django/template/context.py", line 83, in __getitem__
raise KeyError(key)
KeyError: 'exp'

During handling of the above exception, another exception occurred:

# Fixed code
def static_analyzer(request, api=False):
    """Do static analysis on an request and save to db."""
    try:
        if api:
            typ = request.POST["scan_type"]
            checksum = request.POST["hash"]
            filename = request.POST["file_name"]
            rescan = str(request.POST.get("re_scan", 0))
        else:
            typ = request.GET["type"]
            checksum = request.GET["checksum"]
            filename = request.GET["name"]
            rescan = str(request.GET.get("rescan", 0))
        # Input validation
        app_dic = {}
        match = re.match("^[0-9a-f]{32}$", checksum)
        if (
            (match)
            and (filename.lower().endswith(".apk") or filename.lower().endswith(".zip"))
            and (typ in ["zip", "apk"])
        ):
            app_dic["dir"] = settings.BASE_DIR  # BASE DIR
            app_dic["app_name"] = filename  # APP ORGINAL NAME
            app_dic["md5"] = checksum  # MD5
            app_dic["app_dir"] = os.path.join(
                settings.UPLD_DIR, app_dic["md5"] + "/"
            )  # APP DIRECTORY
            app_dic["tools_dir"] = os.path.join(
                app_dic["dir"], "StaticAnalyzer/tools/"
            )  # TOOLS DIR
            # DWD_DIR = settings.DWD_DIR # not needed? Var is never used.
            logger.info("Starting Analysis on : " + app_dic["app_name"])

            if typ == "apk":
                # Check if in DB
                # pylint: disable=E1101
                db_entry = StaticAnalyzerAndroid.objects.filter(MD5=app_dic["md5"])
                if db_entry.exists() and rescan == "0":
                    context = get_context_from_db_entry(db_entry)
                else:
                    app_dic["app_file"] = app_dic["md5"] + ".apk"  # NEW FILENAME
                    app_dic["app_path"] = (
                        app_dic["app_dir"] + app_dic["app_file"]
                    )  # APP PATH

                    # ANALYSIS BEGINS
                    app_dic["size"] = (
                        str(file_size(app_dic["app_path"])) + "MB"
                    )  # FILE SIZE
                    app_dic["sha1"], app_dic["sha256"] = hash_gen(app_dic["app_path"])

                    app_dic["files"] = unzip(app_dic["app_path"], app_dic["app_dir"])
                    app_dic["certz"] = get_hardcoded_cert_keystore(app_dic["files"])

                    logger.info("APK Extracted")

                    # Manifest XML
                    app_dic["parsed_xml"] = get_manifest(
                        app_dic["app_path"],
                        app_dic["app_dir"],
                        app_dic["tools_dir"],
                        "",
                        True,
                    )

                    # Get icon
                    res_path = os.path.join(app_dic["app_dir"], "res")
                    app_dic["icon_hidden"] = True
                    # Even if the icon is hidden, try to guess it by the
                    # default paths
                    app_dic["icon_found"] = False
                    app_dic["icon_path"] = ""
                    # TODO: Check for possible different names for resource
                    # folder?
                    if os.path.exists(res_path):
                        icon_dic = get_icon(app_dic["app_path"], res_path)
                        if icon_dic:
                            app_dic["icon_hidden"] = icon_dic["hidden"]
                            app_dic["icon_found"] = bool(icon_dic["path"])
                            app_dic["icon_path"] = icon_dic["path"]

                    # Set Manifest link
                    app_dic["mani"] = (
                        "../ManifestView/?md5=" + app_dic["md5"] + "&type=apk&bin=1"
                    )
                    man_data_dic = manifest_data(app_dic["parsed_xml"])

                    man_an_dic = manifest_analysis(app_dic["parsed_xml"], man_data_dic)
                    bin_an_buff = []
                    bin_an_buff += elf_analysis(app_dic["app_dir"])
                    bin_an_buff += res_analysis(app_dic["app_dir"])
                    cert_dic = cert_info(app_dic["app_dir"], app_dic["tools_dir"])
                    apkid_results = apkid_analysis(
                        app_dic["app_dir"], app_dic["app_path"]
                    )
                    dex_2_jar(
                        app_dic["app_path"], app_dic["app_dir"], app_dic["tools_dir"]
                    )
                    dex_2_smali(app_dic["app_dir"], app_dic["tools_dir"])
                    jar_2_java(app_dic["app_dir"], app_dic["tools_dir"])
                    code_an_dic = code_analysis(
                        app_dic["app_dir"], man_an_dic["permissons"], "apk"
                    )
                    logger.info("Generating Java and Smali Downloads")
                    gen_downloads(
                        app_dic["app_dir"], app_dic["md5"], app_dic["icon_path"]
                    )

                    # Get the strings
                    app_dic["strings"] = strings_jar(
                        app_dic["app_file"], app_dic["app_dir"]
                    )
                    app_dic["zipped"] = "&type=apk"

                    logger.info("Connecting to Database")
                    try:
                        # SAVE TO DB
                        if rescan == "1":
                            logger.info("Updating Database...")
                            update_db_entry(
                                app_dic,
                                man_data_dic,
                                man_an_dic,
                                code_an_dic,
                                cert_dic,
                                bin_an_buff,
                                apkid_results,
                            )
                        elif rescan == "0":
                            logger.info("Saving to Database")
                            create_db_entry(
                                app_dic,
                                man_data_dic,
                                man_an_dic,
                                code_an_dic,
                                cert_dic,
                                bin_an_buff,
                                apkid_results,
                            )
                    except:
                        PrintException("Saving to Database Failed")
                    context = get_context_from_analysis(
                        app_dic,
                        man_data_dic,
                        man_an_dic,
                        code_an_dic,
                        cert_dic,
                        bin_an_buff,
                        apkid_results,
                    )
                context["average_cvss"], context["security_score"] = score(
                    context["findings"]
                )
                context["dynamic_analysis_done"] = os.path.exists(
                    os.path.join(app_dic["app_dir"], "logcat.txt")
                )

                context["VT_RESULT"] = None
                if settings.VT_ENABLED:
                    vt = VirusTotal.VirusTotal()
                    context["VT_RESULT"] = vt.get_result(
                        os.path.join(app_dic["app_dir"], app_dic["md5"]) + ".apk",
                        app_dic["md5"],
                    )
                template = "static_analysis/static_analysis.html"
                if api:
                    return context
                else:
                    return render(request, template, context)
            elif typ == "zip":
                # Check if in DB
                # pylint: disable=E1101
                cert_dic = {}
                cert_dic["cert_info"] = ""
                cert_dic["issued"] = ""
                cert_dic["sha256Digest"] = False
                bin_an_buff = []
                app_dic["strings"] = ""
                app_dic["zipped"] = ""
                # Above fields are only available for APK and not ZIP
                db_entry = StaticAnalyzerAndroid.objects.filter(MD5=app_dic["md5"])
                if db_entry.exists() and rescan == "0":
                    context = get_context_from_db_entry(db_entry)
                else:
                    app_dic["app_file"] = app_dic["md5"] + ".zip"  # NEW FILENAME
                    app_dic["app_path"] = (
                        app_dic["app_dir"] + app_dic["app_file"]
                    )  # APP PATH
                    logger.info("Extracting ZIP")
                    app_dic["files"] = unzip(app_dic["app_path"], app_dic["app_dir"])
                    # Check if Valid Directory Structure and get ZIP Type
                    pro_type, valid = valid_android_zip(app_dic["app_dir"])
                    if valid and pro_type == "ios":
                        logger.info("Redirecting to iOS Source Code Analyzer")
                        if api:
                            return {"type": "ios"}
                        else:
                            return HttpResponseRedirect(
                                "/StaticAnalyzer_iOS/?name="
                                + app_dic["app_name"]
                                + "&type=ios&checksum="
                                + app_dic["md5"]
                            )
                    app_dic["certz"] = get_hardcoded_cert_keystore(app_dic["files"])
                    app_dic["zipped"] = pro_type
                    logger.info("ZIP Type - " + pro_type)
                    if valid and (pro_type in ["eclipse", "studio"]):
                        # ANALYSIS BEGINS
                        app_dic["size"] = (
                            str(file_size(app_dic["app_path"])) + "MB"
                        )  # FILE SIZE
                        app_dic["sha1"], app_dic["sha256"] = hash_gen(
                            app_dic["app_path"]
                        )

                        # Manifest XML
                        app_dic["persed_xml"] = get_manifest(
                            "",
                            app_dic["app_dir"],
                            app_dic["tools_dir"],
                            pro_type,
                            False,
                        )

                        # Set manifest view link
                        app_dic["mani"] = (
                            "../ManifestView/?md5="
                            + app_dic["md5"]
                            + "&type="
                            + pro_type
                            + "&bin=0"
                        )

                        man_data_dic = manifest_data(app_dic["persed_xml"])

                        man_an_dic = manifest_analysis(
                            app_dic["persed_xml"], man_data_dic
                        )

                        # Get icon
                        eclipse_res_path = os.path.join(app_dic["app_dir"], "res")
                        studio_res_path = os.path.join(
                            app_dic["app_dir"], "app", "src", "main", "res"
                        )
                        if os.path.exists(eclipse_res_path):
                            res_path = eclipse_res_path
                        elif os.path.exists(studio_res_path):
                            res_path = studio_res_path
                        else:
                            res_path = ""

                        app_dic["icon_hidden"] = man_an_dic["icon_hidden"]
                        app_dic["icon_found"] = False
                        app_dic["icon_path"] = ""
                        if res_path:
                            app_dic["icon_path"] = find_icon_path_zip(
                                res_path, man_data_dic["icons"]
                            )
                            if app_dic["icon_path"]:
                                app_dic["icon_found"] = True

                        if app_dic["icon_path"]:
                            if os.path.exists(app_dic["icon_path"]):
                                shutil.copy2(
                                    app_dic["icon_path"],
                                    os.path.join(
                                        settings.DWD_DIR, app_dic["md5"] + "-icon.png"
                                    ),
                                )

                        code_an_dic = code_analysis(
                            app_dic["app_dir"], man_an_dic["permissons"], pro_type
                        )
                        logger.info("Connecting to Database")
                        try:
                            # SAVE TO DB
                            if rescan == "1":
                                logger.info("Updating Database...")
                                update_db_entry(
                                    app_dic,
                                    man_data_dic,
                                    man_an_dic,
                                    code_an_dic,
                                    cert_dic,
                                    bin_an_buff,
                                    {},
                                )
                            elif rescan == "0":
                                logger.info("Saving to Database")
                                create_db_entry(
                                    app_dic,
                                    man_data_dic,
                                    man_an_dic,
                                    code_an_dic,
                                    cert_dic,
                                    bin_an_buff,
                                    {},
                                )
                        except:
                            PrintException("Saving to Database Failed")
                        context = get_context_from_analysis(
                            app_dic,
                            man_data_dic,
                            man_an_dic,
                            code_an_dic,
                            cert_dic,
                            bin_an_buff,
                            {},
                        )
                    else:
                        msg = "This ZIP Format is not supported"
                        if api:
                            return print_n_send_error_response(request, msg, True)
                        else:
                            print_n_send_error_response(request, msg, False)
                            return HttpResponseRedirect("/zip_format/")
                context["average_cvss"], context["security_score"] = score(
                    context["findings"]
                )
                template = "static_analysis/static_analysis_android_zip.html"
                if api:
                    return context
                else:
                    return render(request, template, context)
            else:
                logger.error(
                    "Only APK,IPA and Zipped Android/iOS Source code supported now!"
                )
        else:
            msg = "Hash match failed or Invalid file extension or file type"
            if api:
                return print_n_send_error_response(request, msg, True)
            else:
                return print_n_send_error_response(request, msg, False)

    except Exception as excep:
        msg = str(excep)
        exp = excep.__doc__
        if api:
            return print_n_send_error_response(request, msg, True, exp)
        else:
            return print_n_send_error_response(request, msg, False, exp)