Esempio n. 1
0
    def test_obfuscation_decode_apk_success(
            self, tmp_demo_apk_v10_original_path: str):
        obfuscation = Obfuscation(tmp_demo_apk_v10_original_path,
                                  ignore_libs=True,
                                  interactive=True)

        assert not obfuscation._decoded_apk_path

        obfuscation.decode_apk()

        assert os.path.isdir(obfuscation._decoded_apk_path)
Esempio n. 2
0
    def test_obfuscation_decode_apk_error(self,
                                          tmp_demo_apk_v10_original_path: str,
                                          monkeypatch):
        def mock(*args, **kwargs):
            raise Exception

        monkeypatch.setattr(Apktool, "decode", mock)

        obfuscation = Obfuscation(tmp_demo_apk_v10_original_path,
                                  ignore_libs=True,
                                  interactive=True)

        with pytest.raises(Exception):
            obfuscation.decode_apk()
Esempio n. 3
0
    def test_obfuscation_align_obfuscated_apk_success(
        self,
        tmp_working_directory_path: str,
        tmp_demo_apk_v10_original_path: str,
        tmp_demo_apk_v10_rebuild_path: str,
    ):
        obfuscated_apk_path = os.path.join(tmp_working_directory_path,
                                           "obfuscated.apk")
        obfuscation = Obfuscation(
            tmp_demo_apk_v10_original_path,
            tmp_working_directory_path,
            obfuscated_apk_path,
        )
        obfuscation.obfuscated_apk_path = tmp_demo_apk_v10_rebuild_path

        # In case of errors an exception would be thrown.
        obfuscation.align_obfuscated_apk()
Esempio n. 4
0
    def test_obfuscation_build_obfuscated_apk_success(
        self,
        tmp_working_directory_path: str,
        tmp_demo_apk_v10_original_path: str,
    ):
        obfuscated_apk_path = os.path.join(tmp_working_directory_path,
                                           "obfuscated.apk")
        obfuscation = Obfuscation(
            tmp_demo_apk_v10_original_path,
            tmp_working_directory_path,
            obfuscated_apk_path,
        )

        assert not os.path.isfile(obfuscated_apk_path)

        obfuscation.build_obfuscated_apk()

        assert os.path.isfile(obfuscated_apk_path)
Esempio n. 5
0
    def test_obfuscation_sign_obfuscated_apk_error_missing_keystore_file(
        self,
        tmp_working_directory_path: str,
        tmp_demo_apk_v10_original_path: str,
        tmp_demo_apk_v10_rebuild_path: str,
    ):
        obfuscated_apk_path = os.path.join(tmp_working_directory_path,
                                           "obfuscated.apk")
        obfuscation = Obfuscation(
            tmp_demo_apk_v10_original_path,
            tmp_working_directory_path,
            obfuscated_apk_path,
            keystore_file="invalid.keystore.path",
        )
        obfuscation.obfuscated_apk_path = tmp_demo_apk_v10_rebuild_path

        with pytest.raises(FileNotFoundError):
            obfuscation.sign_obfuscated_apk()
Esempio n. 6
0
def perform_obfuscation(
    input_apk_path: str,
    obfuscator_list: List[str],
    working_dir_path: str = None,
    obfuscated_apk_path: str = None,
    interactive: bool = False,
    ignore_libs: bool = False,
    virus_total_api_key: List[str] = None,
):
    """
    Apply the obfuscation techniques to an input application and generate an obfuscated
    apk file.

    :param input_apk_path: The path to the input application file to obfuscate.
    :param obfuscator_list: A list containing the names of the obfuscation techniques
                            to apply.
    :param working_dir_path: The working directory where to store the intermediate
                             files. By default a directory will be created in the same
                             directory as the input application. If the specified
                             directory doesn't exist, it will be created.
    :param obfuscated_apk_path: The path where to save the obfuscated apk file. By
                                default the file will be saved in the working directory.
    :param interactive: If True, show a progress bar with the obfuscation progress.
    :param ignore_libs: If True, exclude known third party libraries from the
                        obfuscation operations.
    :param virus_total_api_key: A list containing Virus Total API keys, needed only
                                when using Virus Total obfuscator.
    """

    check_external_tool_dependencies()

    if not os.path.isfile(input_apk_path):
        logger.critical(
            'Unable to find application file "{0}"'.format(input_apk_path))
        raise FileNotFoundError(
            'Unable to find application file "{0}"'.format(input_apk_path))

    obfuscation = Obfuscation(
        input_apk_path,
        working_dir_path,
        obfuscated_apk_path,
        interactive=interactive,
        ignore_libs=ignore_libs,
        virus_total_api_key=virus_total_api_key,
    )

    manager = ObfuscatorManager()
    obfuscator_name_to_obfuscator_object = {
        ob.name: ob.plugin_object
        for ob in manager.get_all_obfuscators()
    }
    obfuscator_name_to_function = {
        ob.name: ob.plugin_object.obfuscate
        for ob in manager.get_all_obfuscators()
    }
    valid_obfuscators = manager.get_obfuscators_names()

    # Check how many obfuscators in list will add new fields/methods.
    for obfuscator_name in obfuscator_list:
        # Make sure all the provided obfuscator names are valid.
        if obfuscator_name not in valid_obfuscators:
            raise ValueError(
                'There is no obfuscator named "{0}"'.format(obfuscator_name))
        if obfuscator_name_to_obfuscator_object[
                obfuscator_name].is_adding_fields:
            obfuscation.obfuscators_adding_fields += 1
        if obfuscator_name_to_obfuscator_object[
                obfuscator_name].is_adding_methods:
            obfuscation.obfuscators_adding_methods += 1

    obfuscator_progress = util.show_list_progress(
        obfuscator_list,
        interactive=interactive,
        unit="obfuscator",
        description="Running obfuscators",
    )

    for obfuscator_name in obfuscator_progress:
        try:
            if interactive:
                obfuscator_progress.set_description(
                    "Running obfuscators ({0})".format(obfuscator_name))
            (obfuscator_name_to_function[obfuscator_name])(obfuscation)
        except Exception as e:
            logger.critical("Error during obfuscation: {0}".format(e),
                            exc_info=True)
            raise
Esempio n. 7
0
 def test_obfuscation_error_invalid_apk_path(self):
     with pytest.raises(FileNotFoundError):
         Obfuscation("invalid.apk.path")
Esempio n. 8
0
 def test_get_resource_directory(self, tmp_demo_apk_v10_original_path: str):
     obfuscation = Obfuscation(tmp_demo_apk_v10_original_path)
     resource_dir = obfuscation.get_resource_directory()
     assert os.path.isdir(resource_dir)
     assert "drawable" in os.listdir(resource_dir)
Esempio n. 9
0
 def test_get_assets_directory(self, tmp_demo_apk_v10_original_path: str):
     obfuscation = Obfuscation(tmp_demo_apk_v10_original_path)
     assets_dir = obfuscation.get_assets_directory()
     assert os.path.isdir(assets_dir)
     assert "message.txt" in os.listdir(assets_dir)
Esempio n. 10
0
 def test_get_native_lib_files(self, tmp_demo_apk_v10_original_path: str):
     obfuscation = Obfuscation(tmp_demo_apk_v10_original_path)
     native_libs = obfuscation.get_native_lib_files()
     assert len(native_libs) > 0
     assert all(os.path.isfile(native_lib) for native_lib in native_libs)
Esempio n. 11
0
 def test_get_multidex_smali_files(self,
                                   tmp_demo_apk_v10_original_path: str):
     obfuscation = Obfuscation(tmp_demo_apk_v10_original_path)
     smali_files = obfuscation.get_multidex_smali_files()
     # This test application is not multidex.
     assert len(smali_files) == 0
Esempio n. 12
0
 def test_get_smali_files(self, tmp_demo_apk_v10_original_path: str):
     obfuscation = Obfuscation(tmp_demo_apk_v10_original_path)
     smali_files = obfuscation.get_smali_files()
     assert len(smali_files) > 5
     assert all(os.path.isfile(smali_file) for smali_file in smali_files)
Esempio n. 13
0
 def test_get_manifest_file(self, tmp_demo_apk_v10_original_path: str):
     obfuscation = Obfuscation(tmp_demo_apk_v10_original_path)
     manifest = obfuscation.get_manifest_file()
     assert os.path.isfile(manifest)
Esempio n. 14
0
 def test_is_multidex(self, tmp_demo_apk_v10_original_path: str):
     obfuscation = Obfuscation(tmp_demo_apk_v10_original_path)
     is_multidex = obfuscation.is_multidex()
     assert is_multidex is False
Esempio n. 15
0
 def test_obfuscation_get_remaining_methods(
         self, tmp_demo_apk_v10_original_path: str):
     obfuscation = Obfuscation(tmp_demo_apk_v10_original_path)
     remaining_methods = obfuscation._get_remaining_methods()
     assert isinstance(remaining_methods, int)
     assert remaining_methods > 63500
Esempio n. 16
0
 def test_obfuscation_get_total_methods(
         self, tmp_demo_apk_v10_original_path: str):
     obfuscation = Obfuscation(tmp_demo_apk_v10_original_path)
     total_methods = obfuscation._get_total_methods()
     assert isinstance(total_methods, int)
     assert total_methods > 10