예제 #1
0
 def __init__(self,
              input_filepath: str,
              output_directory: str,
              logger: Logger = None):
     self.input_filepath = input_filepath
     self.output_directory = output_directory
     self.logger = logger
     self.executor = JobExecutor()
예제 #2
0
 def __init__(self,
              apk: APK,
              output_directory: str,
              logger: Logger = logger):
     self.apk = apk
     self.output_directory = output_directory
     self.logger = logger
     self.executor = JobExecutor()
예제 #3
0
 def __init__(self,
              apk: APK,
              input_filename: str,
              output_directory: str,
              logger: Logger = logger):
     self.apk = apk
     report_filename = GetApkInfoInJson.__REPORT_FILENAME_PREFIX + input_filename + ".json"
     self.filepath = os.path.join(output_directory, report_filename)
     self.logger = logger
     self.executor = JobExecutor()
예제 #4
0
class ExtractDexFile(UseCase):
    """
    Extract classes.dex file to a given output directory.
    """
    def __init__(self, apk: APK, output_directory: str, logger: Logger = None):
        self.apk = apk
        self.output_directory = output_directory
        self.logger = logger
        self.executor = JobExecutor()

    def execute(self) -> Future:
        if self.logger:
            self.logger.info("Creating " + self.output_directory +
                             "/classes.dex...")
        return self.executor.submit(self.job(self.output_directory))

    def job(self, output_directory: str):
        """
        Extract the classes.dex file of the APK package.

        :param output_directory: The directory where to save the classes.dex file.
        """
        with ZipFile(self.apk.get_file_name()) as package:
            dex = self.apk.get_dex().get_file_name()
            dex_abspath = os.path.join(output_directory, dex)
            with package.open(dex) as dex, open(dex_abspath, 'wb') as fp:
                shutil.copyfileobj(dex, fp)
class ExtractCertificateFile(UseCase):
    """
    Extract CERT.RSA/DSA file to a given output directory.
    """

    def __init__(self, apk: APK, output_directory: str, logger: Logger = None):
        self.apk = apk
        self.output_directory = output_directory
        self.logger = logger
        self.executor = JobExecutor()

    def execute(self) -> Future:
        if self.logger:
            self.logger.info("Creating " + self.output_directory + "/CERT.RSA...")
        return self.executor.submit(self.job(self.output_directory))

    def job(self, output_directory: str):
        """
        Extract the certificate file of the APK package (whether its name is CERT.RSA or CERT.DSA or PACKAGE.RSA).

        :param output_directory: The directory where to save the CERT.RSA/DSA file.
        """
        with ZipFile(self.apk.get_file_name()) as package:
            cert = self.apk.get_cert().get_file_name()
            cert_abspath = os.path.join(output_directory, os.path.basename(cert))
            with package.open(cert) as cert, open(cert_abspath, 'wb') as fp:
                shutil.copyfileobj(cert, fp)
예제 #6
0
class LaunchApkTool(UseCase):
    """
    Apktool will extract the (decrypted) AndroidManifest.xml, the resources and generate the disassembled smali files.
    """

    APKTOOL_PATH = os.path.join(os.path.dirname(__file__), "..", "apktool", "apktool.jar")

    def __init__(self, input_filepath: str, output_directory: str, logger: Logger = logger):
        self.input_filepath = input_filepath
        self.output_directory = output_directory
        self.logger = logger
        self.executor = JobExecutor()
        self.logger.debug("apktool path: %s", self.APKTOOL_PATH)

    def execute(self) -> Future:
        self.logger.info("Executing apktool...")
        self.logger.info("Creating " + self.output_directory + "/smali/...")
        self.logger.info("Creating " + self.output_directory + "/AndroidManifest.xml...")
        self.logger.info("Creating " + self.output_directory + "/res/...")
        self.logger.info("Creating " + self.output_directory + "/assets/...")

        command = "java -jar {} -q decode -f {} -o {}".format(
            LaunchApkTool.APKTOOL_PATH,
            self.input_filepath,
            self.output_directory
        )
        self.logger.debug("apktool command: `%s`", command)

        return self.executor.submit(os.system(command))
예제 #7
0
class GetApkInfoInJson(UseCase):
    """
    Generate the JSON report file of a given APK file and save it to a given output directory.
    """

    __REPORT_FILENAME_PREFIX = "report-"

    def __init__(self,
                 apk: APK,
                 input_filename: str,
                 output_directory: str,
                 logger: Logger = logger):
        self.apk = apk
        report_filename = GetApkInfoInJson.__REPORT_FILENAME_PREFIX + input_filename + ".json"
        self.filepath = os.path.join(output_directory, report_filename)
        self.logger = logger
        self.executor = JobExecutor()

    def execute(self) -> Future:
        self.logger.info("Creating " + self.filepath + "...")
        return self.executor.submit(self.job())

    def job(self):
        fp = open(os.path.join(self.filepath), "w")
        apk_info = json.dumps(self.apk.dump(),
                              sort_keys=True,
                              ensure_ascii=False,
                              indent=4)
        fp.write(apk_info)
        fp.close()
class GetApkInfoInHtml(UseCase):
    """
    Generate the HTML report file of a given APK file and save it to a given output directory.
    """

    __REPORT_FILENAME_PREFIX = "report-"

    def __init__(self,
                 apk: APK,
                 input_filename: str,
                 output_directory: str,
                 logger: Logger = logger):
        self.apk = apk
        report_filename = GetApkInfoInHtml.__REPORT_FILENAME_PREFIX + input_filename + ".html"
        self.filepath = os.path.join(output_directory, report_filename)
        self.logger = logger
        self.executor = JobExecutor()

    def execute(self) -> Future:
        self.logger.info("Creating " + self.filepath + "...")
        return self.executor.submit(self.job())

    def job(self):
        fp = open(os.path.join(self.filepath), "w")
        apk_info = HtmlReport.generate_html_report(self.apk)
        fp.write(apk_info)
        fp.close()
예제 #9
0
class LaunchDex2Jar(UseCase):
    """
    Dex2jar will generate a jar file from the classes.dex.
    """

    DEX2JAR = os.path.join(os.path.dirname(__file__), "..", "dex2jar",
                           "d2j-dex2jar.sh")

    def __init__(self,
                 input_filepath: str,
                 input_filename: str,
                 output_directory: str,
                 logger: Logger = logger):
        self.input_filepath = input_filepath
        self.input_filename = input_filename
        self.output_directory = output_directory
        self.logger = logger
        self.executor = JobExecutor()

    def execute(self) -> Future:
        jarfile = self.input_filename + ".jar"
        self.logger.info("Running dex2jar on %s, creating %s/%s...",
                         self.input_filepath, self.output_directory, jarfile)

        command = LaunchDex2Jar.DEX2JAR + " -f " + self.input_filepath + \
                  " -o " + self.output_directory + "/" + jarfile

        return self.executor.submit(os.system(command))
예제 #10
0
class LaunchDex2Jar(UseCase):
    """
    Dex2jar will generate a jar file from the classes.dex.
    """

    DEX2JAR = "ninjadroid/dex2jar/d2j-dex2jar.sh"

    def __init__(self,
                 input_filepath: str,
                 input_filename: str,
                 output_directory: str,
                 logger: Logger = None):
        self.input_filepath = input_filepath
        self.input_filename = input_filename
        self.output_directory = output_directory
        self.logger = logger
        self.executor = JobExecutor()

    def execute(self) -> Future:
        jarfile = self.input_filename + ".jar"
        if self.logger:
            self.logger.info("Creating " + self.output_directory + "/" +
                             jarfile + "...")

        command = LaunchDex2Jar.DEX2JAR + " -f " + self.input_filepath + \
                  " -o " + self.output_directory + "/" + jarfile

        return self.executor.submit(os.system(command))
예제 #11
0
class ExtractCertificateFile(UseCase):
    """
    Extract CERT.RSA/DSA file to a given output directory.
    """
    def __init__(self,
                 apk: APK,
                 output_directory: str,
                 logger: Logger = logger):
        self.apk = apk
        self.output_directory = output_directory
        self.logger = logger
        self.executor = JobExecutor()

    def execute(self) -> Future:
        self.logger.info("Extracting certificate to %s...",
                         self.output_directory)
        return self.executor.submit(self.job(self.output_directory))

    def job(self, output_directory: str):
        """
        Extract the certificate file of the APK package (whether its name is CERT.RSA or CERT.DSA or PACKAGE.RSA).

        :param output_directory: The directory where to save the CERT.RSA/DSA file.
        """
        with ZipFile(self.apk.get_file_name()) as package:
            cert = self.apk.get_cert().get_file_name()
            self.logger.info("Extracting %s", cert)

            cert_abspath = os.path.join(output_directory,
                                        os.path.basename(cert))
            with package.open(cert) as cert, open(cert_abspath, 'wb') as fp:
                shutil.copyfileobj(cert, fp)
예제 #12
0
class ExtractDexFile(UseCase):
    """
    Extract classes.dex file to a given output directory.
    """

    def __init__(self, apk: APK, output_directory: str, logger: Logger = None):
        self.apk = apk
        self.output_directory = output_directory
        self.logger = logger
        self.executor = JobExecutor()

    def execute(self) -> Future:
        if self.logger:
            self.logger.info("Creating " + self.output_directory + "/classes.dex...")
        return self.executor.submit(self.job(self.output_directory))

    def job(self, output_directory: str):
        """
        Extract the classes.dex file of the APK package.

        :param output_directory: The directory where to save the classes.dex file.
        """
        with ZipFile(self.apk.get_file_name()) as package:
            dex = self.apk.get_dex().get_file_name()
            dex_abspath = os.path.join(output_directory, dex)
            with package.open(dex) as dex, open(dex_abspath, 'wb') as fp:
                shutil.copyfileobj(dex, fp)
예제 #13
0
class LaunchApkTool(UseCase):
    """
    Apktool will extract the (decrypted) AndroidManifest.xml, the resources and generate the disassembled smali files.
    """

    APKTOOL_PATH = "ninjadroid/apktool/apktool.jar"

    def __init__(self,
                 input_filepath: str,
                 output_directory: str,
                 logger: Logger = None):
        self.input_filepath = input_filepath
        self.output_directory = output_directory
        self.logger = logger
        self.executor = JobExecutor()

    def execute(self) -> Future:
        if self.logger:
            self.logger.info("Creating " + self.output_directory +
                             "/smali/...")
            self.logger.info("Creating " + self.output_directory +
                             "/AndroidManifest.xml...")
            self.logger.info("Creating " + self.output_directory + "/res/...")
            self.logger.info("Creating " + self.output_directory +
                             "/assets/...")

        command = "java -jar " + LaunchApkTool.APKTOOL_PATH + \
                  " -q d -f " + self.input_filepath + " " + self.output_directory

        return self.executor.submit(os.system(command))
예제 #14
0
class LaunchDex2Jar(UseCase):
    """
    Dex2jar will generate a jar file from the classes.dex.
    """

    DEX2JAR = "ninjadroid/dex2jar/d2j-dex2jar.sh"

    def __init__(self, input_filepath: str, input_filename: str, output_directory: str, logger: Logger = None):
        self.input_filepath = input_filepath
        self.input_filename = input_filename
        self.output_directory = output_directory
        self.logger = logger
        self.executor = JobExecutor()

    def execute(self) -> Future:
        jarfile = self.input_filename + ".jar"
        if self.logger:
            self.logger.info("Creating " + self.output_directory + "/" + jarfile + "...")

        command = LaunchDex2Jar.DEX2JAR + " -f " + self.input_filepath + \
                  " -o " + self.output_directory + "/" + jarfile

        return self.executor.submit(os.system(command))
예제 #15
0
class ExtractDexFile(UseCase):
    """
    Extract classes.dex file to a given output directory.
    """
    def __init__(self,
                 apk: APK,
                 output_directory: str,
                 logger: Logger = logger):
        self.apk = apk
        self.output_directory = output_directory
        self.logger = logger
        self.executor = JobExecutor()

    def execute(self) -> Future:
        self.logger.info("Extracting DEX files to %s", self.output_directory)
        return self.executor.submit(self.job(self.output_directory))

    def job(self, output_directory: str):
        """
        Extract the DEX files from the APK package.

        :param output_directory: The directory where to save the DEX files.
        """
        apk_filename = self.apk.get_file_name()
        with ZipFile(apk_filename) as package:
            for dex_file in self.apk.get_dex_files():
                dex_filename = dex_file.get_file_name()
                self.logger.debug("Extracting %s from %s", dex_filename,
                                  apk_filename)
                dex_abspath = os.path.join(output_directory, dex_filename)
                output_directory = os.path.split(dex_abspath)[0]
                os.makedirs(output_directory, exist_ok=True)

                with package.open(dex_filename) as dex:
                    with open(dex_abspath, 'wb') as fp:
                        self.logger.info("Extracting DEX %s", dex_filename)
                        shutil.copyfileobj(dex, fp)
예제 #16
0
class LaunchApkTool(UseCase):
    """
    Apktool will extract the (decrypted) AndroidManifest.xml, the resources and generate the disassembled smali files.
    """

    APKTOOL_PATH = "ninjadroid/apktool/apktool.jar"

    def __init__(self, input_filepath: str, output_directory: str, logger: Logger = None):
        self.input_filepath = input_filepath
        self.output_directory = output_directory
        self.logger = logger
        self.executor = JobExecutor()

    def execute(self) -> Future:
        if self.logger:
            self.logger.info("Creating " + self.output_directory + "/smali/...")
            self.logger.info("Creating " + self.output_directory + "/AndroidManifest.xml...")
            self.logger.info("Creating " + self.output_directory + "/res/...")
            self.logger.info("Creating " + self.output_directory + "/assets/...")

        command = "java -jar " + LaunchApkTool.APKTOOL_PATH + \
                  " -q d -f " + self.input_filepath + " " + self.output_directory

        return self.executor.submit(os.system(command))
class GetApkInfoInJson(UseCase):
    """
    Generate the JSON report file of a given APK file and save it to a given output directory.
    """

    __REPORT_FILENAME_PREFIX = "report-"

    def __init__(self, apk: APK, input_filename: str,  output_directory: str, logger: Logger = None):
        self.apk = apk
        report_filename = GetApkInfoInJson.__REPORT_FILENAME_PREFIX + input_filename + ".json"
        self.filepath = os.path.join(output_directory, report_filename)
        self.logger = logger
        self.executor = JobExecutor()

    def execute(self) -> Future:
        if self.logger:
            self.logger.info("Creating " + self.filepath + "...")
        return self.executor.submit(self.job())

    def job(self):
        fp = open(os.path.join(self.filepath), "w")
        apk_info = json.dumps(self.apk.dump(), sort_keys=True, ensure_ascii=False, indent=4)
        fp.write(apk_info)
        fp.close()
예제 #18
0
 def __init__(self, input_filepath: str, input_filename: str, output_directory: str, logger: Logger = None):
     self.input_filepath = input_filepath
     self.input_filename = input_filename
     self.output_directory = output_directory
     self.logger = logger
     self.executor = JobExecutor()
 def __init__(self, apk: APK, input_filename: str,  output_directory: str, logger: Logger = None):
     self.apk = apk
     report_filename = GetApkInfoInJson.__REPORT_FILENAME_PREFIX + input_filename + ".json"
     self.filepath = os.path.join(output_directory, report_filename)
     self.logger = logger
     self.executor = JobExecutor()
예제 #20
0
 def __init__(self, apk: APK, output_directory: str, logger: Logger = None):
     self.apk = apk
     self.output_directory = output_directory
     self.logger = logger
     self.executor = JobExecutor()
예제 #21
0
 def __init__(self, input_filepath: str, output_directory: str, logger: Logger = logger):
     self.input_filepath = input_filepath
     self.output_directory = output_directory
     self.logger = logger
     self.executor = JobExecutor()
     self.logger.debug("apktool path: %s", self.APKTOOL_PATH)