import os import sys import json import requests import colorama import importlib import subprocess from tqdm import tqdm def init(apktool_jar_url: str, apktool_wrapper_url: str) -> dict: for directory in ["original", "modified", "patches", "tools", "decompiled"]: if not os.path.exists(directory): os.makedirs(directory) if not os.path.exists("./tools/apktool.jar"): try: print("Скачивание Apktool...") jar_response = requests.get(apktool_jar_url, stream=True) jar_path = "tools/apktool.jar" with open(jar_path, "wb") as f: for chunk in jar_response.iter_content(chunk_size=8192): f.write(chunk) wrapper_response = requests.get(apktool_wrapper_url) wrapper_path = "tools/apktool" with open(wrapper_path, "w") as f: f.write(wrapper_response.text) os.chmod(wrapper_path, 0o755) except Exception as e: print(f"Ошибка при скачивании Apktool: {e}") exit(1) try: result = subprocess.run( ["java", "-version"], capture_output=True, text=True, check=True ) version_line = result.stderr.splitlines()[0] if "1.8" in version_line or any(f"{i}." in version_line for i in range(9, 100)): print("Java 8 или более поздняя версия установлена.") else: print("Java 8 или более поздняя версия не установлена.") sys.exit(1) except subprocess.CalledProcessError: print("Java не установлена. Установите Java 8 или более позднюю версию.") exit(1) with open("./patches/config.json", "r") as config_file: return json.load(config_file) def select_apk() -> str: apks = [] for file in os.listdir("original"): if file.endswith(".apk") and os.path.isfile(os.path.join("original", file)): apks.append(file) if not apks: print("Нет файлов .apk в текущей директории") sys.exit(1) while True: print("Выберете файл для модификации") for index, apk in enumerate(apks): print(f"{index + 1}. {apk}") print("0. Exit") try: selected_index = int(input("\nВведите номер файла: ")) if selected_index == 0: sys.exit(0) elif selected_index > len(apks): print("Неверный номер файла") else: apk = apks[selected_index - 1] print(f"Выбран файл {apk}") return apk except ValueError: print("Неверный формат ввода") except KeyboardInterrupt: print("Прервано пользователем") sys.exit(0) def decompile_apk(apk: str): print("Декомпилируем apk...") try: result = subprocess.run( "tools/apktool d -f -o decompiled " + os.path.join("original", apk), shell=True, check=True, text=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, ) except subprocess.CalledProcessError as e: print("Ошибка при выполнении команды:") print(e.stderr) sys.exit(1) class Patch: def __init__(self, name, pkg): self.name = name self.package = pkg self.applied = False def apply(self, conf: dict) -> bool: try: self.applied = self.package.apply(conf) return True except Exception as e: print(f"Ошибка при применении патча {self.name}: {e}") return False conf = init( apktool_jar_url="https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.12.0.jar", apktool_wrapper_url="https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool", ) apk = select_apk() patch = decompile_apk(apk) patches = [] for filename in os.listdir("patches/"): if filename.endswith(".py") and filename != "__init__.py": module_name = filename[:-3] module = importlib.import_module(f"patches.{module_name}") patches.append(Patch(module_name, module)) for patch in tqdm(patches, colour="green", desc="Применение патчей"): tqdm.write(f"Применение патча: {patch.name}") patch.apply(conf) statuses = {} for patch in patches: statuses[patch.name] = patch.applied marker = colorama.Fore.GREEN + "✔" if patch.applied else colorama.Fore.RED + "✘" print(f"{marker}{colorama.Style.RESET_ALL} {patch.name}") if all(statuses.values()): print("Все патчи успешно применены") elif any(statuses.values()): print("Некоторые патчи не были успешно применены") else: print("Ни один патч не был успешно применен")