diff --git a/.gitignore b/.gitignore index 9079f6c..761bec3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ original tools decompiled dist -__pycache__ \ No newline at end of file +__pycache__ +keystore.jks \ No newline at end of file diff --git a/main.py b/main.py index 668d022..f3482fb 100644 --- a/main.py +++ b/main.py @@ -1,9 +1,11 @@ from scripts.download_tools import check_and_download_all_tools from scripts.select_apk import get_apks, select_apk from scripts.select_patches import apply_patches, get_patches, select_patches -from scripts.utils import check_java_version, decompile_apk +from scripts.utils import check_java_version, compile_apk, decompile_apk, sign_apk from config import log, console +from time import time +import math if __name__ == "__main__": check_and_download_all_tools() @@ -15,15 +17,30 @@ if __name__ == "__main__": exit(1) apk = select_apk(apks) + + start_time = time() decompile_apk(apk) - + patches = get_patches() patches = select_patches(patches) - statuses = apply_patches(patches) + statuses_ok = [] + statuses_err = [] for status in statuses: if status["status"]: console.print(f"{status['name']}: ✔", style="bold green") + statuses_ok.append(status["name"]) else: console.print(f"{status['name']}: ✘", style="bold red") + statuses_err.append(status["name"]) + + compile_apk(f"{apk.removesuffix(".apk")}-patched.apk") + sign_apk(f"{apk.removesuffix(".apk")}-patched.apk") + end_time = time() + + log.info("Finished") + log.info(f"install this apk file: {apk.removesuffix(".apk")}-patched-aligned-signed.apk") + log.info(f"used and successful patches: {", ".join(statuses_ok)}") + log.info(f"used and unsuccessful patches: {", ".join(statuses_err)}") + log.info(f"time taken: {math.floor(end_time - start_time)}s") diff --git a/scripts/utils.py b/scripts/utils.py index c8c3520..12c6df9 100644 --- a/scripts/utils.py +++ b/scripts/utils.py @@ -41,3 +41,51 @@ def decompile_apk(apk: str): except subprocess.CalledProcessError as e: log.fatal(f"error of running a command: %s", e.stderr, exc_info=True) exit(1) + + +def compile_apk(apk: str): + if not os.path.exists(config["folders"]["dist"]): + log.info(f"creating `dist` folder: {config['folders']['dist']}") + os.mkdir(config["folders"]["dist"]) + else: + log.info(f"resetting `dist` folder: {config['folders']['dist']}") + shutil.rmtree(config["folders"]["dist"]) + os.mkdir(config["folders"]["dist"]) + + log.info(f"compile apk: `{apk}`") + try: + result = subprocess.run( + f"java -jar {config['folders']['tools']}/apktool.jar b -f -o {config['folders']['dist']}/{apk} {config['folders']['decompiled']}", + shell=True, + check=True, + text=True, + # stdout=subprocess.DEVNULL, + stderr=subprocess.PIPE, + ) + except subprocess.CalledProcessError as e: + log.fatal(f"error of running a command: %s", e.stderr, exc_info=True) + exit(1) + + +def sign_apk(apk: str): + log.info(f"sign and align apk: `{apk}`") + try: + result = subprocess.run( + f"zipalign -p 4 {config['folders']['dist']}/{apk} {config['folders']['dist']}/{apk.removesuffix(".apk")}-aligned.apk", + shell=True, + check=True, + text=True, + # stdout=subprocess.DEVNULL, + stderr=subprocess.PIPE, + ) + result = subprocess.run( + f"apksigner sign --ks ./keystore.jks --out {config['folders']['dist']}/{apk.removesuffix(".apk")}-aligned-signed.apk {config['folders']['dist']}/{apk.removesuffix(".apk")}-aligned.apk", + shell=True, + check=True, + text=True, + # stdout=subprocess.DEVNULL, + stderr=subprocess.PIPE, + ) + except subprocess.CalledProcessError as e: + log.fatal(f"error of running a command: %s", e.stderr, exc_info=True) + exit(1)