feat: change app icons

This commit is contained in:
zx
2024-09-08 19:29:59 -04:00
parent 30fa189197
commit 1e9607d9e1
6 changed files with 59 additions and 1 deletions

View File

@@ -42,6 +42,10 @@ def main() -> None:
"-m", metavar="minimum",
help="modify the app's minimum OS version"
)
parser.add_argument(
"-k", metavar="icon",
help="modify the app's icon"
)
parser.add_argument(
"-u", "--remove-supported-devices", action="store_true",

View File

@@ -55,6 +55,8 @@ def main(parser: ArgumentParser) -> None:
app.plist.change_bundle_id(args.b)
if args.m is not None:
app.plist.change_minimum_version(args.m)
if args.k is not None:
app.change_icon(args.k, tmpdir)
if args.remove_supported_devices:
app.plist.remove_uisd()

View File

@@ -1,6 +1,7 @@
import os
import shutil
from glob import glob
from uuid import uuid4
from typing import Optional, Literal
from .executable import Executable
@@ -101,3 +102,45 @@ class AppBundle:
else:
print("[*] removed encrypted plugins:", ", ".join(removed))
def change_icon(self, path: str, tmpdir: str) -> None:
try:
from PIL import Image
except Exception:
return print("[?] pillow is not installed, -k is not available")
tmpath = f"{tmpdir}/icon.png"
if not path.endswith(".png"):
with Image.open(path) as img:
img.save(tmpath, "PNG")
else:
shutil.copyfile(path, tmpath)
uid = f"cyan_{uuid4().hex[:7]}a" # can't have it end with a num
i60 = f"{uid}60x60"
i76 = f"{uid}76x76"
with Image.open(tmpath) as img:
img.resize((120, 120)).save(f"{self.path}/{i60}@2x.png", "PNG")
img.resize((152, 152)).save(f"{self.path}/{i76}@2x~ipad.png", "PNG")
if "CFBundleIcons" not in self.plist:
self.plist["CFBundleIcons"] = {}
if "CFBundleIcons~ipad" not in self.plist:
self.plist["CFBundleIcons~ipad"] = {}
self.plist["CFBundleIcons"] = self.plist["CFBundleIcons"] | {
"CFBundlePrimaryIcon": {
"CFBundleIconFiles": [i60],
"CFBundleIconName": uid
}
}
self.plist["CFBundleIcons~ipad"] = self.plist["CFBundleIcons~ipad"] | {
"CFBundlePrimaryIcon": {
"CFBundleIconFiles": [i60, i76],
"CFBundleIconName": uid
}
}
self.plist.save()
print("[*] updated app icon")

View File

@@ -25,6 +25,9 @@ class Plist:
def __setitem__(self, key: str, val: Any) -> None:
self.data[key] = val
def __contains__(self, key: str) -> bool:
return key in self.data
def save(self) -> None:
with open(self.path, "wb") as f:
plistlib.dump(self.data, f)

View File

@@ -54,6 +54,9 @@ def validate_inputs(args: Namespace) -> Optional[str]:
):
sys.exit(f"[!] invalid OS version: {args.m}")
if args.k is not None and not os.path.isfile(args.k):
sys.exit(f"[!] {args.k} does not exist")
def get_app(path: str, tmpdir: str, is_ipa: bool) -> str:
payload = f"{tmpdir}/Payload"