mirror of
https://github.com/NohamR/pyzule-rw.git
synced 2026-10-10 18:39:41 +00:00
feat: .cyan files
This commit is contained in:
20
README.md
20
README.md
@@ -1,15 +1,14 @@
|
|||||||
# pyzule-rw / cyan
|
# pyzule-rw / cyan
|
||||||
|
|
||||||
rewriting [pyzule](https://github.com/asdfzxcvbn/pyzule), but actually good this time! btw.. cyan/pyzule looks best with a monospace font !! :D
|
a rewrite of [pyzule](https://github.com/asdfzxcvbn/pyzule) that doesn't (completely) suck !!
|
||||||
|
|
||||||
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 supports **linux, macOS, WSL, and jailbroken iOS!** all either x86_64 or arm64/aarch64 !!
|
||||||
|
|
||||||
`cyan` will ~~target python v3.12 (finally!)~~, be pep8-compliant (hopefully..), and be type-hinted!
|
|
||||||
|
|
||||||
## features
|
## features
|
||||||
|
|
||||||
more coming soon! i'm trying to copy pyzule in order to deprecate it in favor of cyan, which is 1000x better
|
more coming soon! i'm trying to copy pyzule in order to deprecate it in favor of cyan, which is 1000x better
|
||||||
|
|
||||||
|
- generate and use [shareable .cyan files](https://github.com/asdfzxcvbn/cyan-gen) to configure IPAs!
|
||||||
- inject deb, dylib, framework, bundle, and appex files/folders
|
- inject deb, dylib, framework, bundle, and appex files/folders
|
||||||
- automatically fix dependencies on CydiaSubstrate **(cyan uses [ElleKit](https://github.com/evelyneee/ellekit/)!)**, Cephei*, and Orion
|
- automatically fix dependencies on CydiaSubstrate **(cyan uses [ElleKit](https://github.com/evelyneee/ellekit/)!)**, Cephei*, and Orion
|
||||||
- copy any unknown file/folder types to app root
|
- copy any unknown file/folder types to app root
|
||||||
@@ -23,8 +22,6 @@ more coming soon! i'm trying to copy pyzule in order to deprecate it in favor of
|
|||||||
|
|
||||||
## install instructions
|
## install instructions
|
||||||
|
|
||||||
cyan works on linux, macOS, WSL, and jailbroken iOS!
|
|
||||||
|
|
||||||
first, make sure you have [ar](https://command-not-found.com/ar) and [tar](https://command-not-found.com/tar) installed
|
first, make sure you have [ar](https://command-not-found.com/ar) and [tar](https://command-not-found.com/tar) installed
|
||||||
|
|
||||||
also obviously install python, version 3.9 or greater is required (the version available on the procursus repo for iOS)
|
also obviously install python, version 3.9 or greater is required (the version available on the procursus repo for iOS)
|
||||||
@@ -35,7 +32,12 @@ also obviously install python, version 3.9 or greater is required (the version a
|
|||||||
|
|
||||||
then finally, to install or update cyan, just `pip install --force-reinstall git+https://github.com/asdfzxcvbn/pyzule-rw.git#egg=cyan`
|
then finally, to install or update cyan, just `pip install --force-reinstall git+https://github.com/asdfzxcvbn/pyzule-rw.git#egg=cyan`
|
||||||
|
|
||||||
## todo
|
## acknowledgements
|
||||||
|
|
||||||
|
- [Al4ise](https://github.com/Al4ise) for the original [Azule](https://github.com/Al4ise/Azule)
|
||||||
|
- [lief-project](https://github.com/lief-project) for [LIEF](https://github.com/lief-project/LIEF)
|
||||||
|
|
||||||
|
### todo
|
||||||
|
|
||||||
[x] refactor: dont prepare, just copy and fix as you go
|
[x] refactor: dont prepare, just copy and fix as you go
|
||||||
|
|
||||||
@@ -51,5 +53,7 @@ then finally, to install or update cyan, just `pip install --force-reinstall git
|
|||||||
|
|
||||||
[x] feat: change app icon
|
[x] feat: change app icon
|
||||||
|
|
||||||
[] feat: .cyan files (lol rip .pyzule files)
|
[x] feat: .cyan files (lol rip .pyzule files)
|
||||||
|
|
||||||
|
:D
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ def main() -> None:
|
|||||||
"-o", "--output", metavar="output",
|
"-o", "--output", metavar="output",
|
||||||
help="if unspecified, overwrites input"
|
help="if unspecified, overwrites input"
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-z", "--cyan", metavar="cyan",
|
||||||
|
help="the .cyan file to use"
|
||||||
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-f", metavar="file", nargs="+",
|
"-f", metavar="file", nargs="+",
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ def main(parser: ArgumentParser) -> None:
|
|||||||
else:
|
else:
|
||||||
sys.exit("[!] main binary is encrypted; exiting")
|
sys.exit("[!] main binary is encrypted; exiting")
|
||||||
|
|
||||||
|
if args.cyan is not None:
|
||||||
|
changing = vars(args)
|
||||||
|
tbhutils.parse_cyan(changing, tmpdir)
|
||||||
|
|
||||||
# this goes before injection,
|
# this goes before injection,
|
||||||
# since user might inject their own extensions
|
# since user might inject their own extensions
|
||||||
if args.remove_extensions:
|
if args.remove_extensions:
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import json
|
||||||
import shutil
|
import shutil
|
||||||
import zipfile
|
import zipfile
|
||||||
import platform
|
import platform
|
||||||
import subprocess
|
import subprocess
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from typing import Optional
|
|
||||||
from glob import glob, iglob
|
from glob import glob, iglob
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
|
from typing import Optional, Any
|
||||||
|
|
||||||
|
|
||||||
def validate_inputs(args: Namespace) -> Optional[str]:
|
def validate_inputs(args: Namespace) -> Optional[str]:
|
||||||
@@ -57,6 +58,9 @@ def validate_inputs(args: Namespace) -> Optional[str]:
|
|||||||
if args.k is not None and not os.path.isfile(args.k):
|
if args.k is not None and not os.path.isfile(args.k):
|
||||||
sys.exit(f"[!] {args.k} does not exist")
|
sys.exit(f"[!] {args.k} does not exist")
|
||||||
|
|
||||||
|
if args.cyan is not None and not os.path.isfile(args.cyan):
|
||||||
|
sys.exit(f"[!] {args.cyan} does not exist")
|
||||||
|
|
||||||
|
|
||||||
def get_app(path: str, tmpdir: str, is_ipa: bool) -> str:
|
def get_app(path: str, tmpdir: str, is_ipa: bool) -> str:
|
||||||
payload = f"{tmpdir}/Payload"
|
payload = f"{tmpdir}/Payload"
|
||||||
@@ -179,3 +183,29 @@ def make_ipa(tmpdir: str, output: str, level: int) -> None:
|
|||||||
if weird != 0:
|
if weird != 0:
|
||||||
print(f"[?] was unable to zip {weird} file(s) due to timestamps")
|
print(f"[?] was unable to zip {weird} file(s) due to timestamps")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_cyan(args: dict[str, Any], tmpdir: str) -> None:
|
||||||
|
print("[*] parsing .cyan file..")
|
||||||
|
with zipfile.ZipFile(args["cyan"]) as zf:
|
||||||
|
DOT_PATH = f"{tmpdir}/cyan"
|
||||||
|
os.mkdir(DOT_PATH)
|
||||||
|
|
||||||
|
with zf.open("config.json") as f:
|
||||||
|
config = json.load(f)
|
||||||
|
|
||||||
|
if "f" in config:
|
||||||
|
NAMES = [n for n in zf.namelist() if n.startswith("inject/")]
|
||||||
|
zf.extractall(DOT_PATH, NAMES)
|
||||||
|
|
||||||
|
# ensure not None
|
||||||
|
args["f"] = args["f"] if args["f"] is not None else {}
|
||||||
|
for e in os.scandir(f"{DOT_PATH}/inject"):
|
||||||
|
args["f"][e.name] = e.path
|
||||||
|
del config["f"]
|
||||||
|
if "k" in config:
|
||||||
|
args["k"] = zf.extract("icon.idk", DOT_PATH)
|
||||||
|
del config["k"]
|
||||||
|
|
||||||
|
for k, v in config.items():
|
||||||
|
args[k] = v
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user