Пример #1
0
    def obfuscate(self, obfuscation_info: Obfuscation):
        self.logger.info('Running "{0}" obfuscator'.format(self.__class__.__name__))

        try:
            for smali_file in util.show_list_progress(obfuscation_info.get_smali_files(),
                                                      interactive=obfuscation_info.interactive,
                                                      description='Inserting arithmetic computations in smali files'):
                self.logger.debug('Inserting arithmetic computations in file "{0}"'.format(smali_file))
                with util.inplace_edit_file(smali_file) as current_file:
                    editing_method = False
                    start_label = None
                    end_label = None
                    for line in current_file:
                        if line.startswith('.method ') and ' abstract ' not in line and \
                                ' native ' not in line and not editing_method:
                            # Entering method.
                            print(line, end='')
                            editing_method = True

                        elif line.startswith('.end method') and editing_method:
                            # Exiting method.
                            if start_label and end_label:
                                print('\t:{0}'.format(end_label))
                                print('\tgoto/32 :{0}'.format(start_label))
                                start_label = None
                                end_label = None
                            print(line, end='')
                            editing_method = False

                        elif editing_method:
                            # Inside method.
                            print(line, end='')
                            match = util.locals_pattern.match(line)
                            if match and int(match.group('local_count')) >= 2:
                                # If there are at least 2 registers available, add a fake branch at the beginning of
                                # the method: one branch will continue from here, the other branch will go to the end
                                # of the method and then will return here through a "goto" instruction.
                                v0, v1 = util.get_random_int(1, 32), util.get_random_int(1, 32)
                                start_label = util.get_random_string(16)
                                end_label = util.get_random_string(16)
                                tmp_label = util.get_random_string(16)
                                print('\n\tconst v0, {0}'.format(v0))
                                print('\tconst v1, {0}'.format(v1))
                                print('\tadd-int v0, v0, v1')
                                print('\trem-int v0, v0, v1')
                                print('\tif-gtz v0, :{0}'.format(tmp_label))
                                print('\tgoto/32 :{0}'.format(end_label))
                                print('\t:{0}'.format(tmp_label))
                                print('\t:{0}'.format(start_label))

                        else:
                            print(line, end='')

        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:
            op_codes = util.get_nop_valid_op_codes()
            pattern = re.compile(r'\s+(?P<op_code>\S+)')

            for smali_file in util.show_list_progress(obfuscation_info.get_smali_files(),
                                                      interactive=obfuscation_info.interactive,
                                                      description='Inserting "nop" instructions in smali files'):
                self.logger.debug('Inserting "nop" instructions in file "{0}"'.format(smali_file))
                with util.inplace_edit_file(smali_file) as current_file:
                    for line in current_file:

                        # Print original instruction.
                        print(line, end='')

                        # Check if this line contains an op code at the beginning of the string.
                        match = pattern.match(line)
                        if match:
                            op_code = match.group('op_code')
                            # If this is a valid op code, insert some nop instructions after it.
                            if op_code in op_codes:
                                nop_count = util.get_random_int(1, 5)
                                print('\tnop\n' * nop_count, end='')

        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 add_random_fields(self, original_field_declaration: str):
     if self.added_fields < self.max_fields_to_add:
         for _ in range(util.get_random_int(1, 4)):
             print('\n', end='')
             print(original_field_declaration.replace(
                 ':', '{0}:'.format(util.get_random_string(8))),
                   end='')
             self.added_fields += 1
Пример #4
0
    def rename_field_declarations(self,
                                  smali_files: List[str],
                                  interactive: bool = False) -> Set[str]:
        renamed_fields: Set[str] = set()

        # Search for field definitions that can be renamed.
        for smali_file in util.show_list_progress(
                smali_files,
                interactive=interactive,
                description="Renaming field declarations",
        ):
            with util.inplace_edit_file(smali_file) as (in_file, out_file):
                for line in in_file:
                    # Field declared in class.
                    field_match = util.field_pattern.match(line)

                    if field_match:
                        field_name = field_match.group("field_name")
                        # Avoid sub-fields.
                        if "$" not in field_name:
                            # Rename field declaration (usages of this field will be
                            # renamed later) and add some random fields.
                            line = line.replace(
                                "{0}:".format(field_name),
                                "{0}:".format(self.rename_field(field_name)),
                            )
                            out_file.write(line)

                            # Add random fields.
                            if self.added_fields < self.max_fields_to_add:
                                for _ in range(util.get_random_int(1, 4)):
                                    out_file.write("\n")
                                    out_file.write(
                                        line.replace(
                                            ":",
                                            "{0}:".format(
                                                util.get_random_string(8)),
                                        ))
                                    self.added_fields += 1

                            field = "{field_name}:{field_type}".format(
                                field_name=field_match.group("field_name"),
                                field_type=field_match.group("field_type"),
                            )
                            renamed_fields.add(field)
                        else:
                            out_file.write(line)
                    else:
                        out_file.write(line)

        return renamed_fields