From ce42bdff76616e7e9b1af9471d882f8407964d66 Mon Sep 17 00:00:00 2001 From: zx Date: Tue, 3 Sep 2024 20:36:45 -0400 Subject: [PATCH] feat: iOS support --- README.md | 7 +------ cyan/tbhtypes/app_bundle.py | 2 +- cyan/tbhtypes/dylib.py | 0 cyan/tbhtypes/executable.py | 20 +++++++++++++++++--- cyan/tbhutils.py | 2 +- cyan/tools/Darwin/arm64/insert_dylib | Bin 0 -> 69088 bytes cyan/tools/Darwin/arm64/install_name_tool | Bin cyan/tools/Darwin/arm64/ldid | Bin cyan/tools/Darwin/arm64/otool | Bin cyan/tools/Darwin/iOS | 1 + cyan/tools/Darwin/x86_64/install_name_tool | Bin cyan/tools/Darwin/x86_64/ldid | Bin cyan/tools/Darwin/x86_64/otool | Bin setup.py | 4 ++-- 14 files changed, 23 insertions(+), 13 deletions(-) delete mode 100644 cyan/tbhtypes/dylib.py create mode 100755 cyan/tools/Darwin/arm64/insert_dylib mode change 100644 => 100755 cyan/tools/Darwin/arm64/install_name_tool mode change 100644 => 100755 cyan/tools/Darwin/arm64/ldid mode change 100644 => 100755 cyan/tools/Darwin/arm64/otool create mode 120000 cyan/tools/Darwin/iOS mode change 100644 => 100755 cyan/tools/Darwin/x86_64/install_name_tool mode change 100644 => 100755 cyan/tools/Darwin/x86_64/ldid mode change 100644 => 100755 cyan/tools/Darwin/x86_64/otool diff --git a/README.md b/README.md index 4e3d55d..5420fe0 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,6 @@ rewriting [pyzule](https://github.com/asdfzxcvbn/pyzule), but actually good this this is pretty much just a hobby project that i'll work on when i'm bored. pyzule in its current state is kinda ugly, but it works and i haven't really had the motivation to work on it. there really isn't any need for improvements, anyway.. -`cyan` will target python v3.12 (finally!), be pep8-compliant (hopefully..), and be type-hinted! +`cyan` will ~~target python v3.12 (finally!)~~, be pep8-compliant (hopefully..), and be type-hinted! -## plan - -- have a __main__ file ofc, this is what `cyan` command runs -- also have a cyan file, it should have the main logic of the program -- have other files for a class of the ipa/app, main executable, etc diff --git a/cyan/tbhtypes/app_bundle.py b/cyan/tbhtypes/app_bundle.py index 38f661d..738f662 100644 --- a/cyan/tbhtypes/app_bundle.py +++ b/cyan/tbhtypes/app_bundle.py @@ -8,7 +8,7 @@ class AppBundle: self.plist = get_plist(plist_path) self.executable = Executable( - f"{path}/{self.plist["CFBundleExecutable"]}", + f"{path}/{self.plist['CFBundleExecutable']}", path ) diff --git a/cyan/tbhtypes/dylib.py b/cyan/tbhtypes/dylib.py deleted file mode 100644 index e69de29..0000000 diff --git a/cyan/tbhtypes/executable.py b/cyan/tbhtypes/executable.py index 1a20f95..f906783 100644 --- a/cyan/tbhtypes/executable.py +++ b/cyan/tbhtypes/executable.py @@ -27,13 +27,17 @@ class Executable: self.bn = os.path.basename(path) self.inj: Optional[lief.MachO.Binary] = None + if self.specific.endswith("iOS"): + self.inj_func = self.ios_inject + else: + self.inj_func = self.insert_cmd + def is_encrypted(self) -> bool: proc = subprocess.run( [self.otool, "-l", self.path], capture_output=True ) - # print(proc.stdout) return b"cryptid 1" in proc.stdout def inject(self, tweaks: dict[str, str], tmpdir: str) -> None: @@ -155,12 +159,12 @@ class Executable: elif bn.endswith(".dylib"): fpath = f"{FRAMEWORKS_DIR}/{bn}" existed = tbhutils.delete_if_exists(fpath, bn) - self.insert_cmd(f"@rpath/{bn}") + self.inj_func(f"@rpath/{bn}") shutil.copy2(path, FRAMEWORKS_DIR) elif bn.endswith(".framework"): fpath = f"{FRAMEWORKS_DIR}/{bn}" existed = tbhutils.delete_if_exists(fpath, bn) - self.insert_cmd(f"@rpath/{bn}/{bn[:-10]}") + self.inj_func(f"@rpath/{bn}/{bn[:-10]}") shutil.copytree(path, fpath) else: fpath = f"{self.bundle_path}/{bn}" @@ -193,10 +197,20 @@ class Executable: def insert_cmd(self, cmd: str) -> None: if self.inj is None: + lief.logging.disable() self.inj = lief.parse(self.path) # type: ignore self.inj.add(lief.MachO.DylibCommand.weak_lib(cmd)) # type: ignore + def ios_inject(self, cmd: str) -> None: + subprocess.run( + [ + f"{self.specific}/insert_dylib", + "--weak", "--inplace", "--no-strip-codesig", "--all-yes", + cmd, self.path + ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL + ) + def get_dependencies(self) -> list[str]: proc = subprocess.run( [self.otool, "-L", self.path], diff --git a/cyan/tbhutils.py b/cyan/tbhutils.py index dacb3d1..432178c 100644 --- a/cyan/tbhutils.py +++ b/cyan/tbhutils.py @@ -88,7 +88,7 @@ def get_tools_dir() -> tuple[str, str]: system = platform.system() if "iPhone" in mach or "iPad" in mach: - mach = "arm64" + mach = "iOS" with resources.files() as files: # type: ignore return ( diff --git a/cyan/tools/Darwin/arm64/insert_dylib b/cyan/tools/Darwin/arm64/insert_dylib new file mode 100755 index 0000000000000000000000000000000000000000..f37175f0968a987c45b12c6fe61799121a98c6a2 GIT binary patch literal 69088 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