From 0d7681bccbf9a54bba66723e7307dabeee9c93bb Mon Sep 17 00:00:00 2001 From: Rikka <1103670381@qq.com> Date: Thu, 26 Jan 2023 23:23:50 +0800 Subject: [PATCH] add uninstall function --- README.md | 20 ++++++++------ main.py | 20 +++++--------- stuffs/gapps.py | 30 ++++++++++++++++++++ stuffs/general.py | 66 +++++++++++++++++++++++++++++++++++++------- stuffs/houdini.py | 12 ++++++++ stuffs/magisk.py | 64 +++++++++++++++++++++++++++++++++--------- stuffs/microg.py | 18 ++++++++++-- stuffs/ndk.py | 39 +++++++++++++++----------- stuffs/nodataperm.py | 21 ++++++++++++++ stuffs/smartdock.py | 4 +++ stuffs/widevine.py | 9 ++++++ tools/helper.py | 4 +++ 12 files changed, 244 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index b12999b..a266bfd 100644 --- a/README.md +++ b/README.md @@ -140,17 +140,19 @@ Star this repository if you find this useful, if you encounter problem create a ## Error handling -In case of error, if you retry immediately and it fails with this error -``` -==> Failed to resize image '/var/lib/waydroid/images/system.img' .. ! e2fsck 1.45.5 (07-Jan-2020) -/var/lib/waydroid/images/system.img is mounted. -e2fsck: Cannot continue, aborting. -``` -You need to get the mounting point using `df | grep waydroid`. It will be something like `/dev/loopXXX`. Then, unmount it +- WayDroid no longer boots + ``` -sudo umount /dev/loopXXX +sudo waydroid upgrade -o +sudo systemctl restart waydroid-container.service ``` -And re-run the script. +This will make `/var/lib/waydroid/waydroid_base.prop` return to original state, so libndk/libhoudini will be invalid. You need to modify `waydroid_base.prop` again. + +Or use `sudo python3 main.py uninstall xxxxx` to remove what is causing the issue. + +- Magisk installed: N/A + +Check [waydroid-magisk](https://github.com/nitanmarcel/waydroid-magisk) ## Credits - [WayDroid](https://github.com/waydroid/waydroid) diff --git a/main.py b/main.py index b054b40..45c525a 100755 --- a/main.py +++ b/main.py @@ -41,18 +41,10 @@ def install(*args): def uninstall(*args): if "gapps" in args: Gapps().uninstall() - if "libndk" in args and "houdini" not in args: - arch = helper.host()[0] - if arch == "x86_64": - Ndk().uninstall() - else: - Logger.warn("libndk is not supported on your CPU") - if "libhoudini" in args and "ndk" not in args: - arch = helper.host()[0] - if arch == "x86_64": - Houdini().uninstall() - else: - Logger.warn("libhoudini is not supported on your CPU") + if "libndk" in args: + Ndk().uninstall() + if "libhoudini" in args: + Houdini().uninstall() if "magisk" in args: Magisk().uninstall() if "widevine" in args: @@ -61,6 +53,8 @@ def uninstall(*args): Smartdock().uninstall() if "nodataperm" in args: Nodataperm().uninstall() + if "microg" in args: + MicroG().uninstall() def main(): about = """ @@ -85,7 +79,7 @@ def main(): "type": str, "nargs": '+', "metavar":"", - "choices": ["gapps", "microg", "libndk","libhoudini","magisk", "smartdock","widevine", "nodataperm"], + "choices": ["gapps", "microg", "libndk", "libhoudini", "magisk", "smartdock", "widevine", "nodataperm"], } install_help = """ diff --git a/stuffs/gapps.py b/stuffs/gapps.py index 0407b8e..3400554 100644 --- a/stuffs/gapps.py +++ b/stuffs/gapps.py @@ -27,6 +27,36 @@ class Gapps(General): "setupwizarddefault-x86_64.tar.lz", "setupwizardtablet-x86_64.tar.lz" ] + files = [ + "etc/default-permissions/default-permissions.xml", + "etc/default-permissions/opengapps-permissions-q.xml", + "etc/permissions/com.google.android.maps.xml", + "etc/permissions/com.google.android.media.effects.xml", + "etc/permissions/privapp-permissions-google.xml", + "etc/permissions/split-permissions-google.xml", + "etc/preferred-apps/google.xml", + "etc/sysconfig/google.xml", + "etc/sysconfig/google_build.xml", + "etc/sysconfig/google_exclusives_enable.xml", + "etc/sysconfig/google-hiddenapi-package-whitelist.xml", + "framework/com.google.android.maps.jar", + "framework/com.google.android.media.effects.jar", + "priv-app/AndroidMigratePrebuilt", + "priv-app/GoogleExtServices", + "priv-app/GoogleRestore", + "priv-app/CarrierSetup", + "priv-app/GoogleExtShared", + "priv-app/GoogleServicesFramework", + "priv-app/ConfigUpdater", + "priv-app/GoogleFeedback", + "priv-app/Phonesky", + "priv-app/GoogleBackupTransport", + "priv-app/GoogleOneTimeInitializer", + "priv-app/PrebuiltGmsCore", + "priv-app/GoogleContactsSyncAdapter", + "priv-app/GooglePartnerSetup", + "product/overlay/PlayStoreOverlay.apk" + ] def copy(self): if not os.path.exists(self.extract_to): diff --git a/stuffs/general.py b/stuffs/general.py index e1f425c..d6df1a7 100644 --- a/stuffs/general.py +++ b/stuffs/general.py @@ -1,6 +1,7 @@ -import configparser +import glob import os import re +import shutil import zipfile import hashlib from tools import images @@ -37,6 +38,21 @@ class General: Logger.warning( "md5 mismatches, redownloading now ....") loc_md5 = download_file(self.dl_link, self.download_loc) + + def remove(self): + for f in self.files: + file = os.path.join(self.copy_dir, self.partition, f) + if "*" in file: + for wildcard_file in glob.glob(file): + if os.path.isdir(wildcard_file): + shutil.rmtree(wildcard_file) + elif os.path.isfile(wildcard_file): + os.remove(wildcard_file) + else: + if os.path.isdir(file): + shutil.rmtree(file) + elif os.path.isfile(file): + os.remove(file) def extract(self): Logger.info("Extracting archive...") @@ -44,14 +60,26 @@ class General: z.extractall(self.extract_to) def add_props(self): - cfg = configparser.ConfigParser() - cfg.read("/var/lib/waydroid/waydroid.cfg") - - for key in self.apply_props.keys(): - cfg.set('properties', key, self.apply_props[key]) - - with open("/var/lib/waydroid/waydroid.cfg", "w") as f: - cfg.write(f) + with open(os.path.join("/var/lib/waydroid/waydroid_base.prop"), "r") as propfile: + prop_content = propfile.read() + for key in self.apply_props: + if key not in prop_content: + prop_content = prop_content+"\n{key}={value}".format(key=key, value=self.apply_props[key]) + else: + p = re.compile(r"^{key}=.*$".format(key=key), re.M) + prop_content = re.sub(p, "{key}={value}".format(key=key, value=self.apply_props[key]), prop_content) + with open(os.path.join("/var/lib/waydroid/waydroid_base.prop"), "w") as propfile: + propfile.write(prop_content) + + def remove_props(self): + with open(os.path.join("/var/lib/waydroid/waydroid_base.prop"), "r") as propfile: + prop_content = propfile.read() + for key in self.apply_props: + if key in prop_content: + p = re.compile(r"^{key}=.*(\n)*".format(key=key), re.M) + prop_content = re.sub(p, "", prop_content) + with open(os.path.join("/var/lib/waydroid/waydroid_base.prop"), "w") as propfile: + propfile.write(prop_content) def mount(self): img = os.path.join(images.get_image_dir(), self.partition+".img") @@ -103,6 +131,9 @@ class General: def extra2(self): pass + def extra3(self): + pass + def install(self): if container.use_overlayfs(): self.download() @@ -131,4 +162,19 @@ class General: Logger.info("Installation finished") def uninstall(self): - pass + if container.use_overlayfs(): + self.remove() + if hasattr(self, "apply_props"): + self.remove_props() + self.extra3() + self.restart() + else: + self.stop() + self.mount() + self.remove() + if hasattr(self, "apply_props"): + self.remove_props() + self.extra3() + self.umount() + self.start() + Logger.info("Uninstallation finished") diff --git a/stuffs/houdini.py b/stuffs/houdini.py index b784bc0..81dca90 100644 --- a/stuffs/houdini.py +++ b/stuffs/houdini.py @@ -31,6 +31,18 @@ on property:ro.enable.native.bridge.exec=1 "ro.dalvik.vm.isa.arm": "x86", "ro.dalvik.vm.isa.arm64": "x86_64" } + files = [ + "bin/arm", + "bin/arm64", + "bin/houdini", + "bin/houdini64", + "etc/binfmt_misc", + "etc/init/houdini.rc", + "lib/arm", + "lib/libhoudini.so", + "lib64/arm64", + "lib64/libhoudini.so" + ] def copy(self): run(["chmod", "+x", self.extract_to, "-R"]) diff --git a/stuffs/magisk.py b/stuffs/magisk.py index e4145ab..cee09c5 100644 --- a/stuffs/magisk.py +++ b/stuffs/magisk.py @@ -3,7 +3,7 @@ import os import shutil import re from stuffs.general import General -from tools.helper import download_file, host, run +from tools.helper import download_file, get_data_dir, host, run from tools.logger import Logger from tools import container @@ -14,6 +14,7 @@ class Magisk(General): extract_to = "/tmp/magisk_unpack" magisk_dir = os.path.join(partition, "etc", "init", "magisk") machine = host() + files = ["etc/init/magisk"] oringinal_bootanim = """ service bootanim /system/bin/bootanimation class core animation @@ -60,6 +61,13 @@ on property:init.svc.zygote=stopped Logger.info("Downloading latest Magisk-Delta to {} now ...".format(self.download_loc)) download_file(self.dl_link, self.download_loc) + # require additional setup + def setup(self): + Logger.info("Additional setup") + magisk_absolute_dir = os.path.join(self.copy_dir, self.magisk_dir) + data_dir = get_data_dir() + shutil.copytree(magisk_absolute_dir, os.path.join(data_dir, "adb", "magisk"), dirs_exist_ok=True) + def copy(self): magisk_absolute_dir = os.path.join(self.copy_dir, self.magisk_dir) if not os.path.exists(magisk_absolute_dir): @@ -79,6 +87,16 @@ on property:init.svc.zygote=stopped shutil.copyfile(o_path, n_path) run(["chmod", "+x", n_path]) shutil.copyfile(self.download_loc, os.path.join(magisk_absolute_dir,"magisk.apk") ) + shutil.copytree(os.path.join(self.extract_to, "assets", "chromeos"), os.path.join(magisk_absolute_dir, "chromeos"), dirs_exist_ok=True) + assets_files = [ + "addon.d.sh", + "boot_patch.sh", + "stub.apk", + "util_functions.sh" + ] + for f in assets_files: + shutil.copyfile(os.path.join(self.extract_to, "assets", f), os.path.join(magisk_absolute_dir, f)) + self.setup() # Updating Magisk from Magisk manager will modify bootanim.rc, # So it is necessary to backup the original bootanim.rc. @@ -94,16 +112,36 @@ on property:init.svc.zygote=stopped def extra1(self): if container.use_overlayfs(): sys_overlay_rw = "/var/lib/waydroid/overlay_rw" - old_bootanim_rc = os.path.join(sys_overlay_rw, "system","system", "etc", "init", "bootanim.rc") - old_bootanim_rc_gz = os.path.join(sys_overlay_rw, "system","system", "etc", "init", "bootanim.rc.gz") - old_magisk = os.path.join(sys_overlay_rw, "system","system", "etc", "init", "magisk") + files = [ + "system/system/etc/init/bootanim.rc", + "system/system/etc/init/bootanim.rc.gz", + "system/system/etc/init/magisk", + "system/system/addon.d/99-magisk.sh", + "vendor/etc/selinux/precompiled_sepolicy" + ] - if os.path.exists(old_bootanim_rc): - os.remove(old_bootanim_rc) - if os.path.exists(old_bootanim_rc_gz): - os.remove(old_bootanim_rc_gz) - if os.path.exists(old_magisk): - if os.path.isdir(old_magisk): - shutil.rmtree(old_magisk) - else: - os.remove(old_magisk) + for f in files: + file = os.path.join(sys_overlay_rw, f) + if os.path.isdir(file): + shutil.rmtree(file) + elif os.path.isfile(file) or os.path.exists(file): + os.remove(file) + + def extra3(self): + self.extra1() + data_dir = get_data_dir() + files = [ + os.path.join(data_dir, "adb/magisk.db"), + os.path.join(data_dir, "adb/magisk") + ] + for file in files: + if os.path.isdir(file): + shutil.rmtree(file) + elif os.path.isfile(file): + os.remove(file) + bootanim_path = os.path.join(self.copy_dir, self.partition, "etc", "init", "bootanim.rc") + if container.use_overlayfs(): + os.remove(bootanim_path) + else: + with open(bootanim_path, "w") as initfile: + initfile.write(self.oringinal_bootanim) diff --git a/stuffs/microg.py b/stuffs/microg.py index bfc847a..da1e56e 100644 --- a/stuffs/microg.py +++ b/stuffs/microg.py @@ -28,6 +28,7 @@ class MicroG(General): "com.android.vending-22.apk": "6815d191433ffcd8fa65923d5b0b0573", "org.microg.gms.droidguard-14.apk": "4734b41c1a6bc34a541053ddde7a0f8e" } + priv_apps = ["com.google.android.gms", "com.android.vending"] def skip_extract(self): return True @@ -59,12 +60,11 @@ class MicroG(General): def copy(self): Logger.info("Copying MicroG and other files") - priv_apps = ["com.google.android.gms", "com.android.vending"] for apk in {**self.fdroid_repo_apks, **self.microg_apks}.keys(): splitor = "_" if apk in self.fdroid_repo_apks.keys() else "-" package = apk.split(splitor)[0] download_dir = get_download_dir() - apk_dir = "app" if package not in priv_apps else "priv-app" + apk_dir = "app" if package not in self.priv_apps else "priv-app" if not os.path.exists(os.path.join(self.copy_dir, self.partition, apk_dir, package)): os.makedirs(os.path.join(self.copy_dir, self.partition, apk_dir, package)) shutil.copyfile(os.path.join(download_dir, apk), @@ -89,3 +89,17 @@ class MicroG(General): Logger.info("Signature spoofing") run("waydroid shell pm grant com.google.android.gms android.permission.FAKE_PACKAGE_SIGNATURE".split()) run("waydroid shell pm grant com.android.vending android.permission.FAKE_PACKAGE_SIGNATURE".split()) + + def remove(self): + system_dir = os.path.join(self.copy_dir, self.partition) + files = [key.split("_")[0] for key in self.fdroid_repo_apks.keys()] + files += [key.split("-")[0] for key in self.microg_apks.keys()] + for f in files: + if f in self.priv_apps: + file = os.path.join(system_dir, "priv-app", f) + else: + file = os.path.join(system_dir, "app", f) + if os.path.isdir(file): + shutil.rmtree(file) + elif os.path.isfile(file): + os.remove(file) diff --git a/stuffs/ndk.py b/stuffs/ndk.py index 3c0ced7..1e08a77 100644 --- a/stuffs/ndk.py +++ b/stuffs/ndk.py @@ -1,4 +1,5 @@ -from os import path, makedirs +import glob +import os import shutil from stuffs.general import General from tools.helper import run @@ -6,10 +7,10 @@ from tools.logger import Logger class Ndk(General): partition = "system" - dl_link = "https://github.com/supremegamers/vendor_google_proprietary_ndk_translation-prebuilt/archive/181d9290a69309511185c4417ba3d890b3caaaa8.zip" + dl_link = "https://www.dropbox.com/s/eaf4dj3novwiccp/libndk_translation_Module-c6077f3398172c64f55aad7aab0e55fad9110cf3.zip?dl=1" dl_file_name = "libndktranslation.zip" extract_to = "/tmp/libndkunpack" - act_md5 = "0beff55f312492f24d539569d84f5bfb" + act_md5 = "4456fc1002dc78e544e8d9721bb24398" apply_props = { "ro.product.cpu.abilist": "x86_64,x86,armeabi-v7a,armeabi,arm64-v8a", "ro.product.cpu.abilist32": "x86,armeabi-v7a,armeabi", @@ -31,23 +32,29 @@ on property:ro.enable.native.bridge.exec=1 copy /system/etc/binfmt_misc/arm64_exe /proc/sys/fs/binfmt_misc/register copy /system/etc/binfmt_misc/arm64_dyn /proc/sys/fs/binfmt_misc/register """ + files = [ + "bin/arm", + "bin/arm64", + "bin/ndk_translation_program_runner_binfmt_misc", + "bin/ndk_translation_program_runner_binfmt_misc_arm64", + "etc/binfmt_misc", + "etc/ld.config.arm.txt", + "etc/ld.config.arm64.txt", + "etc/init/libndk.rc", + "lib/arm", + "lib64/arm64", + "lib/libndk*", + "lib64/libndk*" + ] def copy(self): run(["chmod", "+x", self.extract_to, "-R"]) Logger.info("Copying libndk library files ...") - archive_url, commit_sha = path.split(path.splitext(self.dl_link)[0]) - zipped_basepath, _ = path.split(archive_url) - prebuilts_sourcedir = path.join( - self.extract_to, - f"{path.basename(zipped_basepath)}-{commit_sha}", - "prebuilts") - shutil.copytree( - prebuilts_sourcedir, - path.join(self.copy_dir, self.partition), - dirs_exist_ok=True) + shutil.copytree(os.path.join(self.extract_to, "libndk_translation_Module-c6077f3398172c64f55aad7aab0e55fad9110cf3", "system"), os.path.join(self.copy_dir, self.partition), dirs_exist_ok=True) - init_path = path.join(self.copy_dir, self.partition, "etc", "init", "libndk.rc") - if not path.isfile(init_path): - makedirs(path.dirname(init_path), exist_ok=True) + init_path = os.path.join(self.copy_dir, self.partition, "etc", "init", "libndk.rc") + if not os.path.isfile(init_path): + os.makedirs(os.path.dirname(init_path), exist_ok=True) with open(init_path, "w") as initfile: initfile.write(self.init_rc_component) + \ No newline at end of file diff --git a/stuffs/nodataperm.py b/stuffs/nodataperm.py index 87ed01b..30601c9 100644 --- a/stuffs/nodataperm.py +++ b/stuffs/nodataperm.py @@ -1,8 +1,10 @@ +import gzip import os import shutil from stuffs.general import General from tools.helper import run from tools.logger import Logger +from tools import container class Nodataperm(General): dl_link = "https://github.com/ayasa520/hack_full_data_permission/archive/refs/heads/main.zip" @@ -10,11 +12,30 @@ class Nodataperm(General): extract_to = "/tmp/nodataperm" act_md5 = "eafd7b0986f3edaebaf1dd89f19d49bf" partition = "system" + files = [ + "etc/nodataperm.sh", + "etc/init/nodataperm.rc", + "framework/services.jar" + ] def copy(self): extract_path = os.path.join(self.extract_to, "hack_full_data_permission-main") + if not container.use_overlayfs(): + services_jar = os.path.join(self.copy_dir, self.partition, "framework", "services.jar") + gz_filename = services_jar+".gz" + with gzip.open(gz_filename,'wb') as f_gz: + with open(services_jar, "rb") as f: + f_gz.write(f.read()) os.chmod(os.path.join(extract_path, "framework", "services.jar"), 0o644) os.chmod(os.path.join(extract_path, "etc", "nodataperm.sh"), 0o755) os.chmod(os.path.join(extract_path, "etc", "init", "nodataperm.rc"), 0o755) Logger.info("Copying widevine library files ...") shutil.copytree(extract_path, os.path.join(self.copy_dir, self.partition), dirs_exist_ok=True) + + def extra3(self): + if not container.use_overlayfs(): + services_jar = os.path.join(self.copy_dir, self.partition, "framework", "services.jar") + gz_filename = services_jar+".gz" + with gzip.GzipFile(gz_filename) as f_gz: + with open(services_jar, "wb") as f: + f.writelines(f_gz) diff --git a/stuffs/smartdock.py b/stuffs/smartdock.py index b8a8e99..ca0572b 100644 --- a/stuffs/smartdock.py +++ b/stuffs/smartdock.py @@ -12,6 +12,10 @@ class Smartdock(General): dl_file_name = "smartdock.zip" act_md5 = "ad0cc5e023ac6ee97e7b013b9b0defee" apply_props = { "qemu.hw.mainkeys" : "1" } + files = [ + "etc/permissions/permissions_cu.axel.smartdock.xml", + "priv-app/SmartDock" + ] def copy(self): if not os.path.exists(os.path.join(self.copy_dir, self.partition, "priv-app", "SmartDock")): diff --git a/stuffs/widevine.py b/stuffs/widevine.py index 7da3dda..ce8665d 100644 --- a/stuffs/widevine.py +++ b/stuffs/widevine.py @@ -11,6 +11,15 @@ class Widevine(General): dl_file_name = "widevine.zip" extract_to = "/tmp/widevineunpack" act_md5 = "a31f325453c5d239c21ecab8cfdbd878" + files = [ + "bin/hw/android.hardware.drm@1.3-service-lazy.widevine", + "bin/move_widevine_data.sh", + "etc/init/android.hardware.drm@1.3-service-lazy.widevine.rc", + "etc/vintf/manifest/manifest_android.hardware.drm@1.3-service.widevine.xml", + "lib/libwvhidl.so", + "lib/mediadrm", + "lib64/mediadrm" + ] def copy(self): run(["chmod", "+x", self.extract_to, "-R"]) diff --git a/tools/helper.py b/tools/helper.py index bc92890..18ff50f 100644 --- a/tools/helper.py +++ b/tools/helper.py @@ -19,6 +19,10 @@ def get_download_dir(): os.makedirs(download_loc) return download_loc +# not good +def get_data_dir(): + return os.path.join('/', "home", os.environ.get("SUDO_USER", os.environ["USER"]), ".local", "share", "waydroid", "data") + def run(args, ignore=""): result = subprocess.run(args=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # print(result.stdout.decode())