diff --git a/README.md b/README.md index f0ad232f..8d2a9f03 100644 --- a/README.md +++ b/README.md @@ -251,7 +251,7 @@ Let's start by looking at the help message: $ obfuscapk --help obfuscapk [-h] -o OBFUSCATOR [-w DIR] [-d OUT_APK] [-i] [-p] [-k VT_API_KEY] [--keystore-file KEYSTORE_FILE] [--keystore-password KEYSTORE_PASSWORD] - [--key-alias KEY_ALIAS] [--key-password KEY_PASSWORD] + [--key-alias KEY_ALIAS] [--key-password KEY_PASSWORD] [--use-aapt2] ``` @@ -303,6 +303,7 @@ shown in the example below: com.mycompany.ignore ... ``` +* `--use-aapt2` is a flag for use aapt2 option to rebuild app when using apktool. Let's consider now a simple working example to see how Obfuscapk works: diff --git a/src/obfuscapk/cli.py b/src/obfuscapk/cli.py index d02e71dc..372663cc 100644 --- a/src/obfuscapk/cli.py +++ b/src/obfuscapk/cli.py @@ -71,6 +71,11 @@ def get_cmd_args(args: list = None): dest="interactive", help="Show obfuscation progress (as a progress bar)", ) + parser.add_argument( + "--use-aapt2", + action="store_true", + help="Use aapt2 for rebuild app" + ) parser.add_argument( "-k", "--virus-total-key", @@ -120,7 +125,7 @@ def main(): """ A full command to obfuscate an application: - python3 -m obfuscapk.cli -p -i -w /working/dir/path -d /path/to/obfuscated.apk \ + python3 -m obfuscapk.cli -p -i -w /working/dir/path --use-aapt2 -d /path/to/obfuscated.apk \ -o DebugRemoval -o LibEncryption -o CallIndirection -o MethodRename \ -o AssetEncryption -o MethodOverload -o ConstStringEncryption \ -o ResStringEncryption -o ArithmeticBranch -o FieldRename -o Nop -o Goto \ @@ -177,6 +182,7 @@ def main(): arguments.key_alias, arguments.key_password, arguments.ignore_packages_file, + arguments.use_aapt2, ) diff --git a/src/obfuscapk/main.py b/src/obfuscapk/main.py index d5083fb8..161f0b7b 100644 --- a/src/obfuscapk/main.py +++ b/src/obfuscapk/main.py @@ -55,6 +55,7 @@ def perform_obfuscation( key_alias: str = None, key_password: str = None, ignore_packages_file: str = None, + use_aapt2: bool = False ): """ Apply the obfuscation techniques to an input application and generate an obfuscated @@ -87,6 +88,7 @@ def perform_obfuscation( file). :param ignore_packages_file: The file containing the package names to be ignored during the obfuscation (one package name per line). + :param use_aapt2 If True, use aapt2 for rebuild app """ check_external_tool_dependencies() @@ -109,6 +111,7 @@ def perform_obfuscation( key_alias, key_password, ignore_packages_file, + use_aapt2 ) manager = ObfuscatorManager() diff --git a/src/obfuscapk/obfuscation.py b/src/obfuscapk/obfuscation.py index 6c235ac7..47f7edce 100644 --- a/src/obfuscapk/obfuscation.py +++ b/src/obfuscapk/obfuscation.py @@ -30,6 +30,7 @@ def __init__( key_alias: str = None, key_password: str = None, ignore_packages_file: str = None, + use_aapt2: bool = False, ): self.logger = logging.getLogger(__name__) @@ -44,6 +45,7 @@ def __init__( self.key_alias: str = key_alias self.key_password: str = key_password self.ignore_packages_file: str = ignore_packages_file + self.use_aapt2 = use_aapt2 # Random string (32 chars long) generation with ASCII letters and digits self.encryption_secret = "".join( @@ -501,7 +503,7 @@ def build_obfuscated_apk(self) -> None: apktool: Apktool = Apktool() try: - apktool.build(self._decoded_apk_path, self.obfuscated_apk_path) + apktool.build(self._decoded_apk_path, self.obfuscated_apk_path, self.use_aapt2) except Exception as e: self.logger.error("Error during apk building: {0}".format(e)) raise diff --git a/src/obfuscapk/tool.py b/src/obfuscapk/tool.py index 6ff49304..ea174634 100644 --- a/src/obfuscapk/tool.py +++ b/src/obfuscapk/tool.py @@ -119,7 +119,7 @@ def decode( self.logger.error("Error during decoding: {0}".format(e)) raise - def build(self, source_dir_path: str, output_apk_path: str = None) -> str: + def build(self, source_dir_path: str, output_apk_path: str = None, use_aapt2: bool = False) -> str: # Check if the input directory exists. if not os.path.isdir(source_dir_path): @@ -143,6 +143,7 @@ def build(self, source_dir_path: str, output_apk_path: str = None) -> str: 'default path: "{0}"'.format(output_apk_path) ) + build_cmd: List[str] = [ self.apktool_path, "--frame-path", @@ -154,6 +155,9 @@ def build(self, source_dir_path: str, output_apk_path: str = None) -> str: output_apk_path, ] + if use_aapt2: + build_cmd.insert(-2, "--use-aapt2") + try: self.logger.info('Running build command "{0}"'.format(" ".join(build_cmd))) # A new line character is sent as input since newer versions of Apktool