Example #1
0
    def add_method_overloads_to_file(self, smali_file: str,
                                     overloaded_method_body: str,
                                     methods_to_ignore: Set[str]) -> int:
        new_methods_num: int = 0
        with util.inplace_edit_file(smali_file) as current_file:

            skip_remaining_lines = False
            class_name = None
            for line in current_file:

                if skip_remaining_lines:
                    print(line, end='')
                    continue

                if not class_name:
                    class_match = util.class_pattern.match(line)
                    # If this is an enum class, skip it.
                    if ' enum ' in line:
                        skip_remaining_lines = True
                        print(line, end='')
                        continue
                    elif class_match:
                        class_name = class_match.group('class_name')
                        print(line, end='')
                        continue

                # Skip virtual methods, consider only the direct methods defined earlier in the file.
                if line.startswith('# virtual methods'):
                    skip_remaining_lines = True
                    print(line, end='')
                    continue

                # Method declared in class.
                method_match = util.method_pattern.match(line)

                # Avoid constructors, native and abstract methods.
                if method_match and '<init>' not in line and '<clinit>' not in line and \
                        ' native ' not in line and ' abstract ' not in line:
                    method = '{method_name}({method_param}){method_return}'.format(
                        method_name=method_match.group('method_name'),
                        method_param=method_match.group('method_param'),
                        method_return=method_match.group('method_return'))
                    # Add method overload.
                    if method not in methods_to_ignore:
                        # Create random parameter lists to be added to the method signature.
                        # Add 3 overloads for each method and for each overload use 4 random params.
                        for params in util.get_random_list_permutations(
                                random.sample(self.param_types, 4))[:3]:
                            new_param = ''.join(params)
                            # Update parameter list and add void return type.
                            overloaded_signature = line.replace(
                                '({0}){1}'.format(
                                    method_match.group('method_param'),
                                    method_match.group('method_return')),
                                '({0}{1})V'.format(
                                    method_match.group('method_param'),
                                    new_param))
                            print(overloaded_signature, end='')
                            print(overloaded_method_body)
                            new_methods_num += 1

                        # Print original method.
                        print(line, end='')
                    else:
                        print(line, end='')
                else:
                    print(line, end='')

        return new_methods_num
Example #2
0
    def add_method_overloads_to_file(self, smali_file: str,
                                     overloaded_method_body: str,
                                     methods_to_ignore: Set[str]) -> int:
        new_methods_num: int = 0
        with util.inplace_edit_file(smali_file) as (in_file, out_file):

            skip_remaining_lines = False
            class_name = None
            for line in in_file:

                if skip_remaining_lines:
                    out_file.write(line)
                    continue

                if not class_name:
                    class_match = util.class_pattern.match(line)
                    # If this is an enum class, skip it.
                    if " enum " in line:
                        skip_remaining_lines = True
                        out_file.write(line)
                        continue
                    elif class_match:
                        class_name = class_match.group("class_name")
                        out_file.write(line)
                        continue

                # Skip virtual methods, consider only the direct methods defined
                # earlier in the file.
                if line.startswith("# virtual methods"):
                    skip_remaining_lines = True
                    out_file.write(line)
                    continue

                # Method declared in class.
                method_match = util.method_pattern.match(line)

                # Avoid constructors, native and abstract methods.
                if (method_match and "<init>" not in line
                        and "<clinit>" not in line and " native " not in line
                        and " abstract " not in line):
                    method = "{method_name}({method_param}){method_return}".format(
                        method_name=method_match.group("method_name"),
                        method_param=method_match.group("method_param"),
                        method_return=method_match.group("method_return"),
                    )
                    # Add method overload.
                    if method not in methods_to_ignore:
                        # Create random parameter lists to be added to the method
                        # signature. Add 3 overloads for each method and for each
                        # overload use 4 random params.
                        for params in util.get_random_list_permutations(
                                random.sample(self.param_types, 4))[:3]:
                            new_param = "".join(params)
                            # Update parameter list and add void return type.
                            overloaded_signature = line.replace(
                                "({0}){1}".format(
                                    method_match.group("method_param"),
                                    method_match.group("method_return"),
                                ),
                                "({0}{1})V".format(
                                    method_match.group("method_param"),
                                    new_param),
                            )
                            out_file.write(overloaded_signature)
                            out_file.write(overloaded_method_body)
                            new_methods_num += 1

                        # Print original method.
                        out_file.write(line)
                    else:
                        out_file.write(line)
                else:
                    out_file.write(line)

        return new_methods_num