mirror of
https://github.com/Lakr233/vphone-cli.git
synced 2026-04-05 04:59:05 +08:00
Nix PATH preservation, amfidont boot, and preflight stability (#196)
* fix: preserve caller PATH through Nix zshenv reset in cfw scripts Nix darwin's /etc/zshenv resets PATH on every zsh subprocess, discarding the Makefile's carefully constructed PATH (which includes .venv/bin and /opt/homebrew/bin). This caused 'Missing Python deps' and ldid PKCS12_parse errors during cfw_install. Pass the Makefile PATH through _VPHONE_PATH env var (which zshenv won't touch), and restore it at the top of each cfw_install script. * fix(cfw_install_dev): add python resolver, use glob for vphoned sources - Add _resolve_python3() matching cfw_install.sh so the venv python is used instead of Nix system python (which lacks capstone/keystone). - Replace hardcoded VPHONED_SRCS list with glob pattern to auto-pick up new .m files (was missing 5 files: accessibility, apps, clipboard, settings, url — causing linker errors). * fix: amfidont uses bundle binary CDHash and .build path make boot launches the bundle binary (.build/vphone-cli.app/Contents/ MacOS/vphone-cli), not the release binary. amfidont's --path must cover the .app bundle location. - amfidont_allow_vphone depends on bundle (not build) - start_amfidont_for_vphone.sh extracts CDHash from bundle binary - --path points to .build/ so amfidont covers .app bundle contents * fix(preflight): prevent run_capture errexit on non-zero return zsh set -e is global scope — set -e inside run_capture then return 137 triggers errexit and kills the script before reaching the assert-bootable check. Use '|| rc=$?' instead to capture the exit code without modifying errexit state.
This commit is contained in:
8
Makefile
8
Makefile
@@ -189,7 +189,7 @@ vm_new:
|
||||
CPU="$(CPU)" MEMORY="$(MEMORY)" \
|
||||
zsh $(SCRIPTS)/vm_create.sh --dir $(VM_DIR) --disk-size $(DISK_SIZE)
|
||||
|
||||
amfidont_allow_vphone: build
|
||||
amfidont_allow_vphone: bundle
|
||||
zsh $(SCRIPTS)/start_amfidont_for_vphone.sh
|
||||
|
||||
boot_host_preflight: build
|
||||
@@ -280,10 +280,10 @@ ramdisk_send:
|
||||
.PHONY: cfw_install cfw_install_dev cfw_install_jb
|
||||
|
||||
cfw_install:
|
||||
cd $(VM_DIR) && $(if $(SSH_PORT),SSH_PORT="$(SSH_PORT)") zsh "$(CURDIR)/$(SCRIPTS)/cfw_install.sh" .
|
||||
cd $(VM_DIR) && $(if $(SSH_PORT),SSH_PORT="$(SSH_PORT)") _VPHONE_PATH="$$PATH" zsh "$(CURDIR)/$(SCRIPTS)/cfw_install.sh" .
|
||||
|
||||
cfw_install_dev:
|
||||
cd $(VM_DIR) && $(if $(SSH_PORT),SSH_PORT="$(SSH_PORT)") zsh "$(CURDIR)/$(SCRIPTS)/cfw_install_dev.sh" .
|
||||
cd $(VM_DIR) && $(if $(SSH_PORT),SSH_PORT="$(SSH_PORT)") _VPHONE_PATH="$$PATH" zsh "$(CURDIR)/$(SCRIPTS)/cfw_install_dev.sh" .
|
||||
|
||||
cfw_install_jb:
|
||||
cd $(VM_DIR) && $(if $(SSH_PORT),SSH_PORT="$(SSH_PORT)") zsh "$(CURDIR)/$(SCRIPTS)/cfw_install_jb.sh" .
|
||||
cd $(VM_DIR) && $(if $(SSH_PORT),SSH_PORT="$(SSH_PORT)") _VPHONE_PATH="$$PATH" zsh "$(CURDIR)/$(SCRIPTS)/cfw_install_jb.sh" .
|
||||
|
||||
@@ -51,10 +51,8 @@ run_capture() {
|
||||
shift
|
||||
|
||||
local log_file="${TMP_DIR}/${label}.log"
|
||||
set +e
|
||||
"$@" >"$log_file" 2>&1
|
||||
local rc=$?
|
||||
set -e
|
||||
local rc=0
|
||||
"$@" >"$log_file" 2>&1 || rc=$?
|
||||
|
||||
(( QUIET == 0 )) && echo "[${label}] exit=${rc}"
|
||||
if (( QUIET == 0 )) && [[ -s "$log_file" ]]; then
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
# Usage: make cfw_install
|
||||
set -euo pipefail
|
||||
|
||||
# ── Restore caller's PATH — Nix /etc/zshenv resets PATH on zsh startup ─
|
||||
[[ -n "${_VPHONE_PATH:-}" ]] && export PATH="$_VPHONE_PATH"
|
||||
|
||||
VM_DIR="${1:-.}"
|
||||
SCRIPT_DIR="${0:a:h}"
|
||||
CFW_SKIP_HALT="${CFW_SKIP_HALT:-0}"
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
# Usage: make cfw_install_dev
|
||||
set -euo pipefail
|
||||
|
||||
# ── Restore caller's PATH — Nix /etc/zshenv resets PATH on zsh startup ─
|
||||
[[ -n "${_VPHONE_PATH:-}" ]] && export PATH="$_VPHONE_PATH"
|
||||
|
||||
VM_DIR="${1:-.}"
|
||||
SCRIPT_DIR="${0:a:h}"
|
||||
CFW_SKIP_HALT="${CFW_SKIP_HALT:-0}"
|
||||
@@ -24,6 +27,17 @@ CFW_SKIP_HALT="${CFW_SKIP_HALT:-0}"
|
||||
# Resolve absolute paths
|
||||
VM_DIR="$(cd "$VM_DIR" && pwd)"
|
||||
|
||||
# ── Python resolver — prefer project venv over whatever is in PATH ─
|
||||
_resolve_python3() {
|
||||
local venv_py="${SCRIPT_DIR:h}/.venv/bin/python3"
|
||||
if [[ -x "$venv_py" ]]; then
|
||||
echo "$venv_py"
|
||||
else
|
||||
command -v python3 || true
|
||||
fi
|
||||
}
|
||||
PYTHON3="$(_resolve_python3)"
|
||||
|
||||
# ── Configuration ───────────────────────────────────────────────
|
||||
CFW_INPUT="cfw_input"
|
||||
CFW_ARCHIVE="cfw_input.tar.zst"
|
||||
@@ -177,9 +191,12 @@ apply_dev_overlay() {
|
||||
check_prereqs() {
|
||||
command -v ipsw >/dev/null 2>&1 || die "'ipsw' not found. Install: brew install blacktop/tap/ipsw"
|
||||
command -v aea >/dev/null 2>&1 || die "'aea' not found (requires macOS 12+)"
|
||||
command -v python3 >/dev/null 2>&1 || die "python3 not found"
|
||||
python3 -c "import capstone, keystone" 2>/dev/null ||
|
||||
die "Missing Python deps. Install: pip install capstone keystone-engine"
|
||||
[[ -x "$PYTHON3" ]] || die "python3 not found (tried: $PYTHON3). Run: make setup_venv"
|
||||
echo "[*] Python: $PYTHON3 ($("$PYTHON3" --version 2>&1))"
|
||||
local py_err
|
||||
py_err="$("$PYTHON3" -c "import capstone, keystone" 2>&1)" || {
|
||||
die "Missing Python deps (using $PYTHON3).\n Error: ${py_err}\n Fix: source ${SCRIPT_DIR:h}/.venv/bin/activate && pip install capstone keystone-engine\n Or: make setup_venv"
|
||||
}
|
||||
}
|
||||
|
||||
# ── Cleanup trap (unmount DMGs on error) ───────────────────────
|
||||
@@ -210,7 +227,7 @@ mkdir -p "$TEMP_DIR"
|
||||
# ── Parse Cryptex paths from BuildManifest ─────────────────────
|
||||
echo ""
|
||||
echo "[*] Parsing iPhone BuildManifest for Cryptex paths..."
|
||||
CRYPTEX_PATHS=$(python3 "$SCRIPT_DIR/patchers/cfw.py" cryptex-paths "$RESTORE_DIR/BuildManifest-iPhone.plist")
|
||||
CRYPTEX_PATHS=$("$PYTHON3" "$SCRIPT_DIR/patchers/cfw.py" cryptex-paths "$RESTORE_DIR/BuildManifest-iPhone.plist")
|
||||
CRYPTEX_SYSOS=$(echo "$CRYPTEX_PATHS" | head -1)
|
||||
CRYPTEX_APPOS=$(echo "$CRYPTEX_PATHS" | tail -1)
|
||||
echo " SystemOS: $CRYPTEX_SYSOS"
|
||||
@@ -270,7 +287,7 @@ fi
|
||||
|
||||
scp_from "/mnt1/sbin/launchd.bak" "$TEMP_DIR/launchd"
|
||||
|
||||
python3 "$SCRIPT_DIR/patchers/cfw.py" patch-launchd-jetsam "$TEMP_DIR/launchd"
|
||||
"$PYTHON3" "$SCRIPT_DIR/patchers/cfw.py" patch-launchd-jetsam "$TEMP_DIR/launchd"
|
||||
ldid_sign "$TEMP_DIR/launchd"
|
||||
scp_to "$TEMP_DIR/launchd" "/mnt1/sbin/launchd"
|
||||
ssh_cmd "/bin/chmod 0755 /mnt1/sbin/launchd"
|
||||
@@ -348,7 +365,7 @@ if ! remote_file_exists "/mnt1/usr/libexec/seputil.bak"; then
|
||||
fi
|
||||
|
||||
scp_from "/mnt1/usr/libexec/seputil.bak" "$TEMP_DIR/seputil"
|
||||
python3 "$SCRIPT_DIR/patchers/cfw.py" patch-seputil "$TEMP_DIR/seputil"
|
||||
"$PYTHON3" "$SCRIPT_DIR/patchers/cfw.py" patch-seputil "$TEMP_DIR/seputil"
|
||||
ldid_sign "$TEMP_DIR/seputil" "com.apple.seputil"
|
||||
scp_to "$TEMP_DIR/seputil" "/mnt1/usr/libexec/seputil"
|
||||
ssh_cmd "/bin/chmod 0755 /mnt1/usr/libexec/seputil"
|
||||
@@ -404,7 +421,7 @@ if ! remote_file_exists "/mnt1/usr/libexec/launchd_cache_loader.bak"; then
|
||||
fi
|
||||
|
||||
scp_from "/mnt1/usr/libexec/launchd_cache_loader.bak" "$TEMP_DIR/launchd_cache_loader"
|
||||
python3 "$SCRIPT_DIR/patchers/cfw.py" patch-launchd-cache-loader "$TEMP_DIR/launchd_cache_loader"
|
||||
"$PYTHON3" "$SCRIPT_DIR/patchers/cfw.py" patch-launchd-cache-loader "$TEMP_DIR/launchd_cache_loader"
|
||||
ldid_sign "$TEMP_DIR/launchd_cache_loader" "com.apple.launchd_cache_loader"
|
||||
scp_to "$TEMP_DIR/launchd_cache_loader" "/mnt1/usr/libexec/launchd_cache_loader"
|
||||
ssh_cmd "/bin/chmod 0755 /mnt1/usr/libexec/launchd_cache_loader"
|
||||
@@ -422,7 +439,7 @@ if ! remote_file_exists "/mnt1/usr/libexec/mobileactivationd.bak"; then
|
||||
fi
|
||||
|
||||
scp_from "/mnt1/usr/libexec/mobileactivationd.bak" "$TEMP_DIR/mobileactivationd"
|
||||
python3 "$SCRIPT_DIR/patchers/cfw.py" patch-mobileactivationd "$TEMP_DIR/mobileactivationd"
|
||||
"$PYTHON3" "$SCRIPT_DIR/patchers/cfw.py" patch-mobileactivationd "$TEMP_DIR/mobileactivationd"
|
||||
ldid_sign "$TEMP_DIR/mobileactivationd"
|
||||
scp_to "$TEMP_DIR/mobileactivationd" "/mnt1/usr/libexec/mobileactivationd"
|
||||
ssh_cmd "/bin/chmod 0755 /mnt1/usr/libexec/mobileactivationd"
|
||||
@@ -436,17 +453,7 @@ echo "[7/7] Installing LaunchDaemons..."
|
||||
# Install vphoned (vsock HID injector daemon)
|
||||
VPHONED_SRC="$SCRIPT_DIR/vphoned"
|
||||
VPHONED_BIN="$VPHONED_SRC/vphoned"
|
||||
VPHONED_SRCS=(
|
||||
"$VPHONED_SRC/unarchive.m"
|
||||
"$VPHONED_SRC/vphoned.m"
|
||||
"$VPHONED_SRC/vphoned_install.m"
|
||||
"$VPHONED_SRC/vphoned_protocol.m"
|
||||
"$VPHONED_SRC/vphoned_hid.m"
|
||||
"$VPHONED_SRC/vphoned_devmode.m"
|
||||
"$VPHONED_SRC/vphoned_location.m"
|
||||
"$VPHONED_SRC/vphoned_files.m"
|
||||
"$VPHONED_SRC/vphoned_keychain.m"
|
||||
)
|
||||
VPHONED_SRCS=("$VPHONED_SRC"/*.m)
|
||||
needs_vphoned_build=0
|
||||
if [[ ! -f "$VPHONED_BIN" ]]; then
|
||||
needs_vphoned_build=1
|
||||
@@ -495,7 +502,7 @@ fi
|
||||
|
||||
scp_from "/mnt1/System/Library/xpc/launchd.plist.bak" "$TEMP_DIR/launchd.plist"
|
||||
cp "$VPHONED_SRC/vphoned.plist" "$INPUT_DIR/jb/LaunchDaemons/"
|
||||
python3 "$SCRIPT_DIR/patchers/cfw.py" inject-daemons "$TEMP_DIR/launchd.plist" "$INPUT_DIR/jb/LaunchDaemons"
|
||||
"$PYTHON3" "$SCRIPT_DIR/patchers/cfw.py" inject-daemons "$TEMP_DIR/launchd.plist" "$INPUT_DIR/jb/LaunchDaemons"
|
||||
scp_to "$TEMP_DIR/launchd.plist" "/mnt1/System/Library/xpc/launchd.plist"
|
||||
ssh_cmd "/bin/chmod 0644 /mnt1/System/Library/xpc/launchd.plist"
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
# Usage: make cfw_install_jb
|
||||
set -euo pipefail
|
||||
|
||||
# ── Restore caller's PATH — Nix /etc/zshenv resets PATH on zsh startup ─
|
||||
[[ -n "${_VPHONE_PATH:-}" ]] && export PATH="$_VPHONE_PATH"
|
||||
VM_DIR="${1:-.}"
|
||||
SCRIPT_DIR="${0:a:h}"
|
||||
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
# start_amfidont_for_vphone.sh — Start amfidont for the current vphone build.
|
||||
#
|
||||
# This is the README "Option 2" host workaround packaged for this repo:
|
||||
# - computes the signed release binary CDHash
|
||||
# - uses the URL-encoded project path form observed by AMFIPathValidator
|
||||
# - computes the signed bundle binary CDHash (what `make boot` actually launches)
|
||||
# - uses the .build path so amfidont covers binaries inside the .app bundle
|
||||
# - starts amfidont in daemon mode so signed vphone-cli launches are allowlisted
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="${0:A:h}"
|
||||
PROJECT_ROOT="${SCRIPT_DIR:h}"
|
||||
RELEASE_BIN="${PROJECT_ROOT}/.build/release/vphone-cli"
|
||||
BUNDLE_BIN="${PROJECT_ROOT}/.build/vphone-cli.app/Contents/MacOS/vphone-cli"
|
||||
AMFIDONT_BIN="${HOME}/Library/Python/3.9/bin/amfidont"
|
||||
|
||||
[[ -x "$AMFIDONT_BIN" ]] || {
|
||||
@@ -19,29 +19,33 @@ AMFIDONT_BIN="${HOME}/Library/Python/3.9/bin/amfidont"
|
||||
exit 1
|
||||
}
|
||||
|
||||
[[ -x "$RELEASE_BIN" ]] || {
|
||||
echo "Missing release binary: $RELEASE_BIN" >&2
|
||||
echo "Run 'make build' first." >&2
|
||||
[[ -x "$BUNDLE_BIN" ]] || {
|
||||
echo "Missing bundle binary: $BUNDLE_BIN" >&2
|
||||
echo "Run 'make bundle' first." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
CDHASH="$(
|
||||
codesign -dv --verbose=4 "$RELEASE_BIN" 2>&1 \
|
||||
codesign -dv --verbose=4 "$BUNDLE_BIN" 2>&1 \
|
||||
| sed -n 's/^CDHash=//p' \
|
||||
| head -n1
|
||||
)"
|
||||
[[ -n "$CDHASH" ]] || {
|
||||
echo "Failed to extract CDHash for $RELEASE_BIN" >&2
|
||||
echo "Failed to extract CDHash for $BUNDLE_BIN" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
ENCODED_PROJECT_ROOT="${PROJECT_ROOT// /%20}"
|
||||
# amfidont --path must cover the actual binary location inside the .app
|
||||
AMFI_PATH="${PROJECT_ROOT}/.build"
|
||||
ENCODED_AMFI_PATH="${AMFI_PATH// /%20}"
|
||||
|
||||
echo "[*] Project root: $PROJECT_ROOT"
|
||||
echo "[*] Encoded AMFI path: $ENCODED_PROJECT_ROOT"
|
||||
echo "[*] Release CDHash: $CDHASH"
|
||||
echo "[*] AMFI path: $AMFI_PATH"
|
||||
echo "[*] Bundle CDHash: $CDHASH"
|
||||
|
||||
exec sudo "$AMFIDONT_BIN" daemon \
|
||||
--path "$ENCODED_PROJECT_ROOT" \
|
||||
--cdhash "$CDHASH" \
|
||||
--verbose
|
||||
sudo env PYTHONPATH="/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python" \
|
||||
/usr/bin/python3 "$AMFIDONT_BIN" daemon \
|
||||
--path "$ENCODED_AMFI_PATH" \
|
||||
--cdhash "$CDHASH" \
|
||||
--verbose \
|
||||
>/dev/null 2>&1
|
||||
|
||||
Reference in New Issue
Block a user