예제 #1
0
    def obfuscate(self, obfuscation_info: Obfuscation):
        self.logger.info('Running "{0}" obfuscator'.format(
            self.__class__.__name__))

        try:
            android_class_names: Set[str] = set(util.get_android_class_names())
            parent_class_names: Set[str] = self.get_parent_class_names(
                obfuscation_info.get_smali_files())

            # Methods in parent classes belonging to the Android framework should be ignored when renaming.
            classes_to_ignore: Set[str] = parent_class_names.intersection(
                android_class_names)
            methods_to_ignore: Set[str] = self.get_methods_to_ignore(
                obfuscation_info.get_smali_files(), classes_to_ignore)

            renamed_methods: Set[str] = self.rename_method_declarations(
                obfuscation_info.get_smali_files(), methods_to_ignore,
                obfuscation_info.interactive)

            self.rename_method_invocations(obfuscation_info.get_smali_files(),
                                           renamed_methods,
                                           android_class_names,
                                           obfuscation_info.interactive)

        except Exception as e:
            self.logger.error(
                'Error during execution of "{0}" obfuscator: {1}'.format(
                    self.__class__.__name__, e))
            raise

        finally:
            obfuscation_info.used_obfuscators.append(self.__class__.__name__)
예제 #2
0
    def obfuscate(self, obfuscation_info: Obfuscation):
        self.logger.info('Running "{0}" obfuscator'.format(self.__class__.__name__))

        try:
            # NOTE: only direct methods (methods that are by nature non-overridable,
            # namely private instance methods, constructors and static methods) will be
            # renamed.

            android_class_names: Set[str] = set(util.get_android_class_names())

            renamed_methods: Set[str] = self.rename_method_declarations(
                obfuscation_info.get_smali_files(),
                android_class_names,
                obfuscation_info.interactive,
            )

            self.rename_method_invocations(
                obfuscation_info.get_smali_files(),
                renamed_methods,
                obfuscation_info.interactive,
            )

        except Exception as e:
            self.logger.error(
                'Error during execution of "{0}" obfuscator: {1}'.format(
                    self.__class__.__name__, e
                )
            )
            raise

        finally:
            obfuscation_info.used_obfuscators.append(self.__class__.__name__)
예제 #3
0
    def obfuscate(self, obfuscation_info: Obfuscation):
        self.logger.info('Running "{0}" obfuscator'.format(
            self.__class__.__name__))

        try:
            android_class_names: Set[str] = set(util.get_android_class_names())
            parent_class_names: Set[str] = self.get_parent_class_names(
                obfuscation_info.get_smali_files())

            # Methods in parent classes belonging to the Android framework should
            # be ignored.
            classes_to_ignore: Set[str] = parent_class_names.intersection(
                android_class_names)
            methods_to_ignore: Set[str] = self.get_methods_to_ignore(
                obfuscation_info.get_smali_files(), classes_to_ignore)

            # There is a method limit for dex files.
            max_methods_to_add = obfuscation_info.get_remaining_methods_per_obfuscator(
            )

            if obfuscation_info.is_multidex():
                for index, dex_smali_files in enumerate(
                        util.show_list_progress(
                            obfuscation_info.get_multidex_smali_files(),
                            interactive=obfuscation_info.interactive,
                            unit="dex",
                            description="Processing multidex",
                        )):
                    max_methods_to_add = obfuscation_info.get_remaining_methods_per_obfuscator(
                    )[index]
                    self.add_method_overloads(
                        dex_smali_files,
                        methods_to_ignore,
                        max_methods_to_add,
                        obfuscation_info.interactive,
                    )
            else:
                self.add_method_overloads(
                    obfuscation_info.get_smali_files(),
                    methods_to_ignore,
                    max_methods_to_add,
                    obfuscation_info.interactive,
                )

        except Exception as e:
            self.logger.error(
                'Error during execution of "{0}" obfuscator: {1}'.format(
                    self.__class__.__name__, e))
            raise

        finally:
            obfuscation_info.used_obfuscators.append(self.__class__.__name__)
예제 #4
0
    def obfuscate(self, obfuscation_info: Obfuscation):
        self.logger.info('Running "{0}" obfuscator'.format(
            self.__class__.__name__))

        try:
            # NOTE: only direct methods (methods that are by nature non-overridable,
            # namely private instance methods, constructors and static methods) will be
            # overloaded.

            android_class_names: Set[str] = set(util.get_android_class_names())

            # There is a method limit for dex files.
            max_methods_to_add = obfuscation_info.get_remaining_methods_per_obfuscator(
            )

            if obfuscation_info.is_multidex():
                for index, dex_smali_files in enumerate(
                        util.show_list_progress(
                            obfuscation_info.get_multidex_smali_files(),
                            interactive=obfuscation_info.interactive,
                            unit="dex",
                            description="Processing multidex",
                        )):
                    max_methods_to_add = (
                        obfuscation_info.get_remaining_methods_per_obfuscator(
                        )[index])
                    self.add_method_overloads(
                        dex_smali_files,
                        android_class_names,
                        max_methods_to_add,
                        obfuscation_info.interactive,
                    )
            else:
                self.add_method_overloads(
                    obfuscation_info.get_smali_files(),
                    android_class_names,
                    max_methods_to_add,
                    obfuscation_info.interactive,
                )

        except Exception as e:
            self.logger.error(
                'Error during execution of "{0}" obfuscator: {1}'.format(
                    self.__class__.__name__, e))
            raise

        finally:
            obfuscation_info.used_obfuscators.append(self.__class__.__name__)
예제 #5
0
    def __init__(self):
        self.logger = logging.getLogger('{0}.{1}'.format(
            __name__, self.__class__.__name__))
        super().__init__()

        self.android_class_names: Set[str] = set(
            util.get_android_class_names())

        self.methods_with_reflection: int = 0

        # Will be populated before running the reflection obfuscator.
        self.class_name_to_smali_file: dict = {}

        # Keep track of the length of the added instructions for reflection obfuscator, since there is a limit
        # for the number of maximum instructions in a try catch block. Not all the instructions have the same length.
        self.obfuscator_instructions_length: int = 0
        self.obfuscator_instructions_limit: int = 60000

        self.primitive_types: Set[str] = {
            'I', 'Z', 'B', 'S', 'J', 'F', 'D', 'C'
        }

        self.type_dict = {
            'I': 'Ljava/lang/Integer;',
            'Z': 'Ljava/lang/Boolean;',
            'B': 'Ljava/lang/Byte;',
            'S': 'Ljava/lang/Short;',
            'J': 'Ljava/lang/Long;',
            'F': 'Ljava/lang/Float;',
            'D': 'Ljava/lang/Double;',
            'C': 'Ljava/lang/Character;'
        }

        self.sget_dict = {
            'I': 'Ljava/lang/Integer;->TYPE:Ljava/lang/Class;',
            'Z': 'Ljava/lang/Boolean;->TYPE:Ljava/lang/Class;',
            'B': 'Ljava/lang/Byte;->TYPE:Ljava/lang/Class;',
            'S': 'Ljava/lang/Short;->TYPE:Ljava/lang/Class;',
            'J': 'Ljava/lang/Long;->TYPE:Ljava/lang/Class;',
            'F': 'Ljava/lang/Float;->TYPE:Ljava/lang/Class;',
            'D': 'Ljava/lang/Double;->TYPE:Ljava/lang/Class;',
            'C': 'Ljava/lang/Character;->TYPE:Ljava/lang/Class;'
        }

        self.cast_dict = {
            'I': 'Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;',
            'Z': 'Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;',
            'B': 'Ljava/lang/Byte;->valueOf(B)Ljava/lang/Byte;',
            'S': 'Ljava/lang/Short;->valueOf(S)Ljava/lang/Short;',
            'J': 'Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;',
            'F': 'Ljava/lang/Float;->valueOf(F)Ljava/lang/Float;',
            'D': 'Ljava/lang/Double;->valueOf(D)Ljava/lang/Double;',
            'C': 'Ljava/lang/Character;->valueOf(C)Ljava/lang/Character;'
        }

        self.reverse_cast_dict = {
            'I': 'Ljava/lang/Integer;->intValue()I',
            'Z': 'Ljava/lang/Boolean;->booleanValue()Z',
            'B': 'Ljava/lang/Byte;->byteValue()B',
            'S': 'Ljava/lang/Short;->shortValue()S',
            'J': 'Ljava/lang/Long;->longValue()J',
            'F': 'Ljava/lang/Float;->floatValue()F',
            'D': 'Ljava/lang/Double;->doubleValue()D',
            'C': 'Ljava/lang/Character;->charValue()C'
        }
예제 #6
0
    def __init__(self):
        self.logger = logging.getLogger("{0}.{1}".format(
            __name__, self.__class__.__name__))
        super().__init__()

        self.android_class_names: Set[str] = set(
            util.get_android_class_names())

        self.methods_with_reflection: int = 0

        # Will be populated before running the reflection obfuscator.
        self.class_name_to_smali_file: dict = {}

        # Keep track of the length of the added instructions for reflection obfuscator,
        # since there is a limit for the number of maximum instructions in a try catch
        # block. Not all the instructions have the same length.
        self.obfuscator_instructions_length: int = 0
        self.obfuscator_instructions_limit: int = 60000

        self.primitive_types: Set[str] = {
            "I", "Z", "B", "S", "J", "F", "D", "C"
        }

        self.type_dict = {
            "I": "Ljava/lang/Integer;",
            "Z": "Ljava/lang/Boolean;",
            "B": "Ljava/lang/Byte;",
            "S": "Ljava/lang/Short;",
            "J": "Ljava/lang/Long;",
            "F": "Ljava/lang/Float;",
            "D": "Ljava/lang/Double;",
            "C": "Ljava/lang/Character;",
        }

        self.sget_dict = {
            "I": "Ljava/lang/Integer;->TYPE:Ljava/lang/Class;",
            "Z": "Ljava/lang/Boolean;->TYPE:Ljava/lang/Class;",
            "B": "Ljava/lang/Byte;->TYPE:Ljava/lang/Class;",
            "S": "Ljava/lang/Short;->TYPE:Ljava/lang/Class;",
            "J": "Ljava/lang/Long;->TYPE:Ljava/lang/Class;",
            "F": "Ljava/lang/Float;->TYPE:Ljava/lang/Class;",
            "D": "Ljava/lang/Double;->TYPE:Ljava/lang/Class;",
            "C": "Ljava/lang/Character;->TYPE:Ljava/lang/Class;",
        }

        self.cast_dict = {
            "I": "Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;",
            "Z": "Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;",
            "B": "Ljava/lang/Byte;->valueOf(B)Ljava/lang/Byte;",
            "S": "Ljava/lang/Short;->valueOf(S)Ljava/lang/Short;",
            "J": "Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;",
            "F": "Ljava/lang/Float;->valueOf(F)Ljava/lang/Float;",
            "D": "Ljava/lang/Double;->valueOf(D)Ljava/lang/Double;",
            "C": "Ljava/lang/Character;->valueOf(C)Ljava/lang/Character;",
        }

        self.reverse_cast_dict = {
            "I": "Ljava/lang/Integer;->intValue()I",
            "Z": "Ljava/lang/Boolean;->booleanValue()Z",
            "B": "Ljava/lang/Byte;->byteValue()B",
            "S": "Ljava/lang/Short;->shortValue()S",
            "J": "Ljava/lang/Long;->longValue()J",
            "F": "Ljava/lang/Float;->floatValue()F",
            "D": "Ljava/lang/Double;->doubleValue()D",
            "C": "Ljava/lang/Character;->charValue()C",
        }