Example #1
0
    def __init__(self):
        self.internal_data_path = "/data/data/{}"
        self.external_data_path = "/sdcard/Android/data/{}"
        self.internal_data_dump_name = "{}_internal.tar.gz"
        self.external_data_dump_name = "{}_external.tar.gz"

        #Dump internal data https://android.stackexchange.com/questions/85564/need-one-line-adb-shell-su-push-pull-to-access-data-from-windows-batch-file
        self.check_root_command = """{} -s {} shell "su -c 'echo HASROOT'"""
        self.magic_root_command = """{} -s {} shell "su -c 'cd {} && tar czf - ./ --exclude='./files'| base64' 2>/dev/null" | {} -d"""
        self.magic_noroot_command = """{} -s {} shell "cd {} && tar czf - ./ --exclude='./files'| base64 2>/dev/null" | {} -d"""

        if not (
                Utils.get_platform().startswith("windows")
                or Utils.get_platform().startswith("darwin")
        ):  #some linux versions doesn't output if contains errors, so we ignore it. but base64 for windows doesn't have this attribute
            self.magic_root_command += "i"  #add -i flag to base64 decode to avoid some encoding issues
            self.magic_noroot_command += "i"  #add -i flag to base64 decode to avoid some encoding issues

        self.adb_location = Utils.get_adb_location()
        self.base64_location = Utils.get_base64_location()

        self.dumps_path = os.path.join(Utils.get_base_path_folder(), "dumps")
        Utils.check_and_generate_folder(self.dumps_path)

        self.path_dump_folder = os.path.join(self.dumps_path,
                                             Utils.get_current_time())
Example #2
0
    def generate_html_report(reports, report_path):
        logging.info("Generating HTML report")

        Utils.copy_tree(os.path.join(Utils.get_base_path_folder(), "template"),
                        report_path)

        report_file_path = os.path.join(report_path, "report.html")

        try:
            os.remove(os.path.join(
                report_path, "index.html"))  #remove report.html from index
        except:
            pass

        if not reports.get("header"):
            reports["header"] = {}

        reports["header"]["case_name"] = os.environ.get("case_name".upper())
        reports["header"]["case_number"] = os.environ.get(
            "case_number".upper())
        reports["header"]["examiner"] = os.environ.get("examiner".upper())

        js_code = "var reportData = " + json.dumps(reports, indent=2)

        assets_folder = os.path.join(report_path, "assets")
        Utils.check_and_generate_folder(assets_folder)

        handler = open(os.path.join(assets_folder, "Report.js"), "w")
        handler.write(js_code)
        handler.close()

        return report_file_path
Example #3
0
def start(args):
    Utils.setup_custom_logger()
    Utils.set_env()

    logging.info("Starting")

    extract = Extract()

    #If we don't found an output folder, we use the "report" folder
    if not args.output:
        args.output = os.path.join(Utils.get_base_path_folder(), "report")

    #Remove previous index.html from output folder
    try:
        os.remove(os.path.join(args.output, "index.html"))
    except:
        pass

    #Remove previous assets from output folder
    try:
        Utils.remove_folder(os.path.join(args.output, "assets"))
    except:
        pass

    #List of reports for html output
    reports = []

    for app in args.app:
        folders = []

        #This logic support both <appname> and <com.app.id>
        #app > appname
        #app_id > com.app.id
        if '.' in app:
            app = Utils.find_app_name(app)
            app_id = app
        else:
            app_id = Utils.find_package(app)

        #app_id output folder
        app_report_base = os.path.join(args.output, app_id)

        #We are starting, let's clean report app output folder first!
        Utils.remove_folder(app_report_base)

        if args.dump:
            #For each dump in arguments
            for dump in args.dump:
                dump_path = os.path.join(Utils.get_base_path_folder(), "dumps",
                                         dump)

                #If dump path exists
                if os.path.exists(dump_path):

                    #We list everything in folder
                    for folder in os.listdir(dump_path):

                        #We add every subdirectory to analyze (folder by device)
                        if os.path.isdir(os.path.join(dump_path, folder)):
                            folders.append(os.path.join(dump_path, folder))
                        #We found .tar.gz in the base folder, let's add them too, but add it only if don't add it before
                        elif '.tar.gz' in folder and dump_path not in folders:
                            folders.append(dump_path)

                #The dump file not found
                else:
                    logging.warning(
                        "Invalid dump name: {}. Ignoring".format(dump))

        #We can use an mount path as input
        if args.path:
            folders.append(args.path)

        #We can use adb to extract contents
        if args.adb:
            for serial, folder in extract.dump_from_adb(app_id).items():
                folders.append(folder)

        #For each folder previously added
        index = 0

        for folder in folders:
            index += 1

            #Every app can have multiple dumps, so we add a folder for each dump
            report_path = os.path.join(app_report_base, str(index))

            #Analyze every folder
            analyzer = Analyzer(app_id, folder, report_path)
            report = analyzer.generate_report()

            #If we set html report output, generate it
            if args.html and report:
                #Generate individual html report
                analyzer.generate_html_report(report, report_path)

                #Add to list to create index
                reports.append(
                    analyzer.generate_report_summary(report, str(index)))

    #Generate html index
    if args.html and reports:
        item = {}
        item["reports"] = reports
        analyzer.generate_html_index(item, args.output)

    logging.info("Done")