mirror of
https://github.com/NohamR/pyzule-rw.git
synced 2026-10-10 18:39:41 +00:00
feat: thinning
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
import shutil
|
||||
from glob import glob
|
||||
from typing import Optional
|
||||
|
||||
from .executable import Executable
|
||||
from .plist import Plist
|
||||
@@ -15,6 +16,8 @@ class AppBundle:
|
||||
path
|
||||
)
|
||||
|
||||
self.cached_executables: Optional[list[str]] = None
|
||||
|
||||
def remove(self, name: str) -> bool:
|
||||
path = f"{self.path}/{name}"
|
||||
if not os.path.exists(path):
|
||||
@@ -38,20 +41,38 @@ class AppBundle:
|
||||
else:
|
||||
print("[?] watch app not present")
|
||||
|
||||
def fakesign_all(self) -> None:
|
||||
self.executable.fakesign()
|
||||
count = 1
|
||||
|
||||
for ts in sum((
|
||||
def get_executables(self) -> list[str]:
|
||||
return sum((
|
||||
glob(f"{self.path}/**/*.dylib", recursive=True),
|
||||
glob(f"{self.path}/**/*.appex", recursive=True),
|
||||
glob(f"{self.path}/**/*.framework", recursive=True)
|
||||
), []): # type: ignore
|
||||
pl = Plist(f"{ts}/Info.plist")
|
||||
Executable(f"{ts}/{pl['CFBundleExecutable']}").fakesign()
|
||||
count += 1
|
||||
), []) # type: ignore
|
||||
|
||||
for ts in glob(f"{self.path}/**/*.dylib", recursive=True):
|
||||
Executable(ts).fakesign()
|
||||
count += 1
|
||||
def mass_operate(self, op: str, func: str) -> None:
|
||||
# this works since we call this after injecting
|
||||
if self.cached_executables is None:
|
||||
self.cached_executables = self.get_executables()
|
||||
|
||||
if getattr(self.executable, func)():
|
||||
count = 1
|
||||
else:
|
||||
count = 0
|
||||
|
||||
for ts in self.cached_executables:
|
||||
if ts.endswith(".dylib"):
|
||||
call = getattr(Executable(ts), func)()
|
||||
else:
|
||||
pl = Plist(f"{ts}/Info.plist")
|
||||
call = getattr(Executable(f"{ts}/{pl['CFBundleExecutable']}"), func)()
|
||||
|
||||
if call:
|
||||
count += 1
|
||||
|
||||
print(f"[*] {op} \033[96m{count}\033[0m item(s)")
|
||||
|
||||
def fakesign_all(self) -> None:
|
||||
self.mass_operate("fakesigned", "fakesign")
|
||||
|
||||
def thin_all(self) -> None:
|
||||
self.mass_operate("thinned", "thin")
|
||||
|
||||
print(f"[*] fakesigned \033[96m{count}\033[0m items")
|
||||
|
||||
@@ -16,6 +16,7 @@ class Executable:
|
||||
install_dir, specific = tbhutils.get_tools_dir()
|
||||
nt = f"{specific}/install_name_tool"
|
||||
ldid = f"{specific}/ldid"
|
||||
lipo = f"{specific}/lipo"
|
||||
otool = f"{specific}/otool"
|
||||
|
||||
starters = ("\t/Library/", "\t@rpath", "\t@executable_path")
|
||||
@@ -183,12 +184,22 @@ class Executable:
|
||||
subprocess.run(["ldid", f"-S{ENT_PATH}", self.path])
|
||||
print("[*] restored entitlements")
|
||||
|
||||
def fakesign(self, keep_entitlements: bool = True) -> None:
|
||||
def fakesign(self, keep_entitlements: bool = True) -> bool:
|
||||
cmd = [self.ldid, "-S"]
|
||||
if keep_entitlements:
|
||||
cmd.append("-M")
|
||||
|
||||
subprocess.run(cmd + [self.path])
|
||||
return True
|
||||
|
||||
def thin(self) -> bool:
|
||||
if subprocess.run(
|
||||
[self.lipo, "-thin", "arm64", self.path, "-output", self.path],
|
||||
stderr=subprocess.DEVNULL
|
||||
).returncode == 0:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def change_dependency(self, old: str, new: str) -> None:
|
||||
subprocess.run([self.nt, "-change", old, new, self.path])
|
||||
|
||||
@@ -54,3 +54,4 @@ class Plist:
|
||||
print("[*] enabled documents support")
|
||||
else:
|
||||
print("[?] documents support was already enabled")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user