Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3bc2b310a3 |
@@ -18,7 +18,7 @@ from stuff.nodataperm import Nodataperm
|
||||
from stuff.smartdock import Smartdock
|
||||
from stuff.widevine import Widevine
|
||||
from stuff.fdroidpriv import FDroidPriv
|
||||
from stuff.tflitefix import TfliteFix
|
||||
from stuff.device_spoof import DeviceSpoof, PROFILES
|
||||
import tools.helper as helper
|
||||
from tools import container
|
||||
from tools import images
|
||||
@@ -90,6 +90,8 @@ def install_app(args):
|
||||
install_list.append(Mitm(args.ca_cert_file))
|
||||
if "fdroidpriv" in app:
|
||||
install_list.append(FDroidPriv(args.android_version))
|
||||
if "device_spoof" in app:
|
||||
DeviceSpoof(getattr(args, "spoof_profile", "pixel6")).install()
|
||||
|
||||
if not container.use_overlayfs():
|
||||
copy_dir = "/tmp/waydroid"
|
||||
@@ -141,12 +143,12 @@ def remove_app(args):
|
||||
remove_list.append(Mitm())
|
||||
if "fdroidpriv" in app:
|
||||
remove_list.append(FDroidPriv(args.android_version))
|
||||
if "device_spoof" in app:
|
||||
DeviceSpoof().uninstall()
|
||||
if "nodataperm" in app:
|
||||
remove_list.append(Nodataperm(args.android_version))
|
||||
if "hidestatusbar" in app:
|
||||
remove_list.append(HideStatusBar())
|
||||
if "tflitefix" in app:
|
||||
remove_list.append(TfliteFix())
|
||||
|
||||
if not container.use_overlayfs():
|
||||
copy_dir = "/tmp/waydroid"
|
||||
@@ -172,8 +174,6 @@ def hack_option(args):
|
||||
hack_list.append(Nodataperm())
|
||||
if "hidestatusbar" in options:
|
||||
hack_list.append(HideStatusBar())
|
||||
if "tflitefix" in options:
|
||||
hack_list.append(TfliteFix())
|
||||
|
||||
if not container.use_overlayfs():
|
||||
copy_dir = "/tmp/waydroid"
|
||||
@@ -209,7 +209,7 @@ def interact():
|
||||
args = argparse.Namespace()
|
||||
android_version = inquirer.select(
|
||||
message="Select Android version",
|
||||
instruction="(↑↓ Select Item)",
|
||||
instruction="(\u2191\u2193 Select Item)",
|
||||
choices=[
|
||||
Choice(name="Android 11", value="11"),
|
||||
Choice(name="Android 13", value="13"),
|
||||
@@ -234,8 +234,8 @@ def interact():
|
||||
if not action:
|
||||
exit()
|
||||
|
||||
install_choices = ["gapps", "microg", "libndk", "libhoudini", "magisk", "smartdock", "fdroidpriv", "widevine",]
|
||||
hack_choices = ["tflitefix"]
|
||||
install_choices = ["gapps", "microg", "libndk", "libhoudini", "magisk", "smartdock", "fdroidpriv", "widevine", "device_spoof"]
|
||||
hack_choices = []
|
||||
if android_version=="11":
|
||||
hack_choices.extend(["nodataperm", "hidestatusbar"])
|
||||
|
||||
@@ -256,6 +256,13 @@ def interact():
|
||||
default="Standard",
|
||||
).execute()
|
||||
args.microg_variant = microg_variant
|
||||
if "device_spoof" in apps:
|
||||
spoof_profile = inquirer.select(
|
||||
message="Select device profile to spoof",
|
||||
choices=list(PROFILES.keys()),
|
||||
default="pixel6",
|
||||
).execute()
|
||||
args.spoof_profile = spoof_profile
|
||||
args.app = apps
|
||||
install_app(args)
|
||||
elif action == "Remove":
|
||||
@@ -301,8 +308,8 @@ def main():
|
||||
certified.set_defaults(func=get_certified)
|
||||
|
||||
install_choices = ["gapps", "microg", "libndk", "libhoudini",
|
||||
"magisk", "mitm", "smartdock", "widevine"]
|
||||
hack_choices = ["nodataperm", "hidestatusbar", "tflitefix"]
|
||||
"magisk", "mitm", "smartdock", "widevine", "device_spoof"]
|
||||
hack_choices = ["nodataperm", "hidestatusbar"]
|
||||
micrg_variants = ["Standard", "NoGoolag", "UNLP", "Minimal", "MinimalIAP"]
|
||||
remove_choices = install_choices
|
||||
|
||||
@@ -332,6 +339,11 @@ widevine: Add support for widevine DRM L3
|
||||
dest='ca_cert_file',
|
||||
help='[for mitm only] The CA certificate file (*.pem) to install',
|
||||
default=None)
|
||||
install_parser.add_argument('-p', '--spoof-profile',
|
||||
dest='spoof_profile',
|
||||
help='[for device_spoof only] Device profile to spoof',
|
||||
choices=list(PROFILES.keys()),
|
||||
default="pixel6")
|
||||
install_parser.set_defaults(func=install_app)
|
||||
|
||||
# remove and its aliases
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import configparser
|
||||
from tools.logger import Logger
|
||||
|
||||
|
||||
PROFILES = {
|
||||
"pixel6": {
|
||||
"ro.product.brand": "google",
|
||||
"ro.product.manufacturer": "Google",
|
||||
"ro.product.model": "Pixel 6",
|
||||
"ro.product.name": "oriole",
|
||||
"ro.product.device": "oriole",
|
||||
"ro.product.board": "oriole",
|
||||
"ro.build.product": "oriole",
|
||||
"ro.build.fingerprint": "google/oriole/oriole:13/TQ3A.230901.001/10750268:user/release-keys",
|
||||
"ro.build.description": "oriole-user 13 TQ3A.230901.001 10750268 release-keys",
|
||||
"ro.build.version.release": "13",
|
||||
"ro.build.version.sdk": "33",
|
||||
"ro.build.type": "user",
|
||||
"ro.build.tags": "release-keys",
|
||||
},
|
||||
"samsung_s21": {
|
||||
"ro.product.brand": "samsung",
|
||||
"ro.product.manufacturer": "samsung",
|
||||
"ro.product.model": "SM-G991B",
|
||||
"ro.product.name": "o1sxeea",
|
||||
"ro.product.device": "o1s",
|
||||
"ro.product.board": "lahaina",
|
||||
"ro.build.product": "o1s",
|
||||
"ro.build.fingerprint": "samsung/o1sxeea/o1s:13/TP1A.220624.014/G991BXXU5EWCA:user/release-keys",
|
||||
"ro.build.description": "o1sxeea-user 13 TP1A.220624.014 G991BXXU5EWCA release-keys",
|
||||
"ro.build.version.release": "13",
|
||||
"ro.build.version.sdk": "33",
|
||||
"ro.build.type": "user",
|
||||
"ro.build.tags": "release-keys",
|
||||
},
|
||||
}
|
||||
|
||||
PROP_KEYS = list(next(iter(PROFILES.values())).keys())
|
||||
|
||||
|
||||
class DeviceSpoof:
|
||||
id = "device_spoof"
|
||||
|
||||
def __init__(self, profile_name="pixel6") -> None:
|
||||
if profile_name not in PROFILES:
|
||||
raise ValueError(f"Unknown profile '{profile_name}'. Choose from: {list(PROFILES.keys())}")
|
||||
self.profile_name = profile_name
|
||||
self.apply_props = PROFILES[profile_name]
|
||||
|
||||
def _read_cfg(self):
|
||||
cfg = configparser.ConfigParser()
|
||||
cfg.read("/var/lib/waydroid/waydroid.cfg")
|
||||
if not cfg.has_section("properties"):
|
||||
cfg.add_section("properties")
|
||||
return cfg
|
||||
|
||||
def install(self):
|
||||
cfg = self._read_cfg()
|
||||
for key, value in self.apply_props.items():
|
||||
cfg.set("properties", key, value)
|
||||
with open("/var/lib/waydroid/waydroid.cfg", "w") as f:
|
||||
cfg.write(f)
|
||||
Logger.info(f"Device spoofed as '{self.profile_name}'. Restart Waydroid to apply.")
|
||||
|
||||
def uninstall(self):
|
||||
cfg = self._read_cfg()
|
||||
for key in PROP_KEYS:
|
||||
cfg.remove_option("properties", key)
|
||||
with open("/var/lib/waydroid/waydroid.cfg", "w") as f:
|
||||
cfg.write(f)
|
||||
Logger.info("Device spoof properties removed. Restart Waydroid to apply.")
|
||||
@@ -1,78 +0,0 @@
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
from stuff.general import General
|
||||
from tools.logger import Logger
|
||||
|
||||
|
||||
class TfliteFix(General):
|
||||
id = "tflitefix"
|
||||
partition = "system"
|
||||
TARGET_OFFSET = 0x2E9204
|
||||
PATCH_BYTES = b"\xc0\x03\x5f\xd6" # ret in AArch64 little-endian
|
||||
|
||||
def __init__(self, android_version="13") -> None:
|
||||
super().__init__()
|
||||
|
||||
def download(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
def skip_extract(self):
|
||||
return True
|
||||
|
||||
def copy(self):
|
||||
pass
|
||||
|
||||
def extra1(self):
|
||||
"""Applies binary patch to libtensorflowlite.so in installed apps"""
|
||||
search_paths = [
|
||||
os.path.expanduser("~/.local/share/waydroid/data/app/~~*==/*/lib/arm64/libtensorflowlite.so"),
|
||||
"/var/lib/waydroid/data/app/~~*==/*/lib/arm64/libtensorflowlite.so",
|
||||
]
|
||||
found = []
|
||||
for p in search_paths:
|
||||
found.extend(glob.glob(p))
|
||||
|
||||
if not found:
|
||||
Logger.warning("No installed apps with libtensorflowlite.so found in Waydroid data.")
|
||||
return
|
||||
|
||||
for lib_path in found:
|
||||
try:
|
||||
with open(lib_path, "rb") as f:
|
||||
data = bytearray(f.read())
|
||||
|
||||
if len(data) > self.TARGET_OFFSET + 4:
|
||||
if bytes(data[self.TARGET_OFFSET:self.TARGET_OFFSET+4]) == self.PATCH_BYTES:
|
||||
Logger.info(f"Patch already applied to {lib_path}")
|
||||
continue
|
||||
|
||||
backup = lib_path + ".orig"
|
||||
if not os.path.exists(backup):
|
||||
shutil.copy2(lib_path, backup)
|
||||
|
||||
data[self.TARGET_OFFSET:self.TARGET_OFFSET+4] = self.PATCH_BYTES
|
||||
with open(lib_path, "wb") as f:
|
||||
f.write(data)
|
||||
os.chmod(lib_path, 0o755)
|
||||
Logger.info(f"Successfully patched {lib_path}")
|
||||
except Exception as e:
|
||||
Logger.error(f"Failed to patch {lib_path}: {e}")
|
||||
|
||||
def extra2(self):
|
||||
"""Restores original libtensorflowlite.so from backup"""
|
||||
search_paths = [
|
||||
os.path.expanduser("~/.local/share/waydroid/data/app/~~*==/*/lib/arm64/libtensorflowlite.so.orig"),
|
||||
"/var/lib/waydroid/data/app/~~*==/*/lib/arm64/libtensorflowlite.so.orig",
|
||||
]
|
||||
for p in search_paths:
|
||||
for orig in glob.glob(p):
|
||||
target = orig[:-5]
|
||||
try:
|
||||
shutil.copy2(orig, target)
|
||||
os.remove(orig)
|
||||
os.chmod(target, 0o755)
|
||||
Logger.info(f"Restored {target}")
|
||||
except Exception as e:
|
||||
Logger.error(f"Failed to restore {target}: {e}")
|
||||
Reference in New Issue
Block a user