mirror of
https://github.com/Lakr233/vphone-cli.git
synced 2026-09-05 17:14:28 +00:00
Rework JB finalization: drop dropbear, auto-bootstrap on first boot (#141)
* fix: build
* fix: remove [trusted=yes] from Havoc apt source
The inline [trusted=yes] option can cause issues with Sileo's
source parser. The apt-get calls already use AllowUnauthenticated
flags, making it redundant.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: main actor crash in VPhoneControl + IPA extraction failures
VPhoneControl: pending request handlers are @MainActor-isolated closures
but were called from DispatchQueue.global() in the read loop and timeout
handler, causing dispatch_assert_queue_fail crashes. Wrap all
pending.handler() calls in DispatchQueue.main.async.
unarchive: the recent ARCHIVE_EXTRACT_SECURE_* hardening (ef02d50) broke
IPA extraction on iOS because:
- SECURE_NOABSOLUTEPATHS: we set absolute output paths on entries
- SECURE_SYMLINKS: iOS system paths (/var, /tmp) are symlinks
- archive_write_header failures were silently swallowed due to if/else if
structure, making extraction report success with no files extracted
Fix by keeping only SECURE_NODOTDOT, resolving symlinks in extraction
path, fixing header error handling, removing unnecessary ACL/FFLAGS
flags, and surfacing libarchive errors in the install response.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* remove dropbear SSH daemon from guest
Drop all dropbear setup: LaunchDaemon plist injection, host key
generation, daemon deployment, and SSH availability messages.
Guest communication is handled by vphoned over vsock.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* feat: liblaunch compat stub + automatic JB first-boot setup
liblaunch_compat.dylib: stub exporting _launch_active_user_switch
(missing from PCC VM's libSystem.B.dylib) so procursus binaries
like launchctl can load. Deployed to /cores/, loaded via
DYLD_INSERT_LIBRARIES in LaunchDaemon environment and JB profile.
vphone_jb_setup.sh: first-boot script replacing the SSH-based
cfw_install_jb_post.sh. Runs as a LaunchDaemon on first normal
boot and performs all JB finalization: /var/jb symlink,
prep_bootstrap, markers, Sileo, apt setup, TrollStore Lite.
Idempotent with done marker. Logs to /var/log/vphone_jb_setup.log.
Removes the cfw_install_jb_finalize make target and the entire
SSH/iproxy/sshpass-based post-boot flow from setup_machine.sh.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* chore: update AGENTS.md firmware table, gitignore build artifacts
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: launchctl wrapper uses absolute path + timeout to prevent hangs
- Use absolute path to launchctl.real instead of relative dirname,
fixing "not found" when called via /var/jb/bin/launchctl symlink
- Add 5s timeout so launchctl doesn't hang when launchd is
unresponsive on PCC VMs — always exits 0 for dpkg postinst compat
- Symlink /var/jb/bin/launchctl -> /var/jb/usr/bin/launchctl so both
paths work (openssh postinst uses the /bin/ path)
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: replace liblaunch_compat dylib stub with iosbinpack64 launchctl symlink
Procursus launchctl crashes on PCC VMs due to missing
_launch_active_user_switch symbol. Rather than a custom dylib stub,
simply symlink iosbinpack64's launchctl into /var/jb — it talks to
launchd fine and always exits 0, which is all dpkg scripts need.
- Remove liblaunch_compat.c, its build target, signing, and deployment
- Remove DYLD_INSERT_LIBRARIES from setup script and plist
- Replace launchctl wrapper with symlinks to /iosbinpack64/bin/launchctl
- Both /var/jb/usr/bin/launchctl and /var/jb/bin/launchctl are covered
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
5921cba2ba
commit
32b73cd50b
Executable
+198
@@ -0,0 +1,198 @@
|
||||
#!/bin/bash
|
||||
# vphone_jb_setup.sh — First-boot JB finalization script.
|
||||
#
|
||||
# Deployed to /cores/ during cfw_install_jb.sh (ramdisk phase).
|
||||
# Runs automatically via LaunchDaemon on first normal boot.
|
||||
# Idempotent — safe to re-run on subsequent boots.
|
||||
#
|
||||
# Logs to /var/log/vphone_jb_setup.log for host-side monitoring
|
||||
# via vphoned file browser.
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
LOG="/var/log/vphone_jb_setup.log"
|
||||
DONE_MARKER="/var/mobile/.vphone_jb_setup_done"
|
||||
|
||||
log() { echo "[$(date '+%H:%M:%S')] $*" | tee -a "$LOG"; }
|
||||
die() { log "FATAL: $*"; exit 1; }
|
||||
|
||||
# Redirect all output to log
|
||||
exec > >(tee -a "$LOG") 2>&1
|
||||
|
||||
log "=== vphone_jb_setup.sh starting ==="
|
||||
|
||||
# ── Check done marker ────────────────────────────────────────
|
||||
if [ -f "$DONE_MARKER" ]; then
|
||||
log "Already completed (marker exists), exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ── Environment ──────────────────────────────────────────────
|
||||
export TERM=xterm-256color
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Discover PATH dynamically
|
||||
P=""
|
||||
for d in \
|
||||
/var/jb/usr/bin /var/jb/bin /var/jb/sbin /var/jb/usr/sbin \
|
||||
/iosbinpack64/bin /iosbinpack64/usr/bin /iosbinpack64/sbin /iosbinpack64/usr/sbin \
|
||||
/usr/bin /usr/sbin /bin /sbin; do
|
||||
[ -d "$d" ] && P="$P:$d"
|
||||
done
|
||||
export PATH="${P#:}"
|
||||
log "PATH=$PATH"
|
||||
|
||||
# ── Find boot manifest hash ─────────────────────────────────
|
||||
BOOT_HASH=""
|
||||
for d in /private/preboot/*/; do
|
||||
b="${d%/}"; b="${b##*/}"
|
||||
if [ "${#b}" = 96 ]; then
|
||||
BOOT_HASH="$b"
|
||||
break
|
||||
fi
|
||||
done
|
||||
[ -n "$BOOT_HASH" ] || die "Could not find 96-char boot manifest hash"
|
||||
log "Boot hash: $BOOT_HASH"
|
||||
|
||||
JB_TARGET="/private/preboot/$BOOT_HASH/jb-vphone/procursus"
|
||||
[ -d "$JB_TARGET" ] || die "Procursus not found at $JB_TARGET"
|
||||
|
||||
# ═══════════ 0/7 REPLACE LAUNCHCTL ═════════════════════════════
|
||||
# Procursus launchctl crashes (missing _launch_active_user_switch symbol).
|
||||
# iosbinpack64's launchctl talks to launchd fine and always exits 0,
|
||||
# which is enough for dpkg postinst/prerm script compatibility.
|
||||
log "[0/7] Linking iosbinpack64 launchctl into procursus..."
|
||||
IOSBINPACK_LAUNCHCTL=""
|
||||
for p in /iosbinpack64/bin/launchctl /iosbinpack64/usr/bin/launchctl; do
|
||||
[ -f "$p" ] && IOSBINPACK_LAUNCHCTL="$p" && break
|
||||
done
|
||||
|
||||
if [ -n "$IOSBINPACK_LAUNCHCTL" ]; then
|
||||
if [ -f "$JB_TARGET/usr/bin/launchctl" ] && [ ! -L "$JB_TARGET/usr/bin/launchctl" ] && [ ! -f "$JB_TARGET/usr/bin/launchctl.procursus" ]; then
|
||||
mv "$JB_TARGET/usr/bin/launchctl" "$JB_TARGET/usr/bin/launchctl.procursus"
|
||||
log " procursus original saved as launchctl.procursus"
|
||||
fi
|
||||
ln -sf "$IOSBINPACK_LAUNCHCTL" "$JB_TARGET/usr/bin/launchctl"
|
||||
mkdir -p "$JB_TARGET/bin"
|
||||
ln -sf "$IOSBINPACK_LAUNCHCTL" "$JB_TARGET/bin/launchctl"
|
||||
log " linked usr/bin/launchctl + bin/launchctl -> $IOSBINPACK_LAUNCHCTL"
|
||||
else
|
||||
log " WARNING: iosbinpack64 launchctl not found"
|
||||
fi
|
||||
|
||||
# ═══════════ 1/7 SYMLINK /var/jb ═════════════════════════════
|
||||
log "[1/7] Creating /private/var/jb symlink..."
|
||||
CURRENT_LINK=$(readlink /private/var/jb 2>/dev/null || true)
|
||||
if [ "$CURRENT_LINK" = "$JB_TARGET" ]; then
|
||||
log " Symlink already correct"
|
||||
else
|
||||
ln -sf "$JB_TARGET" /private/var/jb
|
||||
log " /var/jb -> $JB_TARGET"
|
||||
fi
|
||||
|
||||
# ═══════════ 2/7 FIX OWNERSHIP / PERMISSIONS ═════════════════
|
||||
log "[2/7] Fixing mobile Library ownership..."
|
||||
mkdir -p /var/jb/var/mobile/Library/Preferences
|
||||
chown -R 501:501 /var/jb/var/mobile/Library
|
||||
chmod 0755 /var/jb/var/mobile/Library
|
||||
chown -R 501:501 /var/jb/var/mobile/Library/Preferences
|
||||
chmod 0755 /var/jb/var/mobile/Library/Preferences
|
||||
log " Ownership set"
|
||||
|
||||
# ═══════════ 3/7 RUN prep_bootstrap.sh ═══════════════════════
|
||||
log "[3/7] Running prep_bootstrap.sh..."
|
||||
if [ -f /var/jb/prep_bootstrap.sh ]; then
|
||||
NO_PASSWORD_PROMPT=1 /var/jb/prep_bootstrap.sh || log " prep_bootstrap.sh exited with $?"
|
||||
log " prep_bootstrap.sh completed"
|
||||
else
|
||||
log " prep_bootstrap.sh already ran (deleted itself), skipping"
|
||||
fi
|
||||
|
||||
# Re-discover PATH after prep_bootstrap
|
||||
P=""
|
||||
for d in \
|
||||
/var/jb/usr/bin /var/jb/bin /var/jb/sbin /var/jb/usr/sbin \
|
||||
/iosbinpack64/bin /iosbinpack64/usr/bin /iosbinpack64/sbin /iosbinpack64/usr/sbin \
|
||||
/usr/bin /usr/sbin /bin /sbin; do
|
||||
[ -d "$d" ] && P="$P:$d"
|
||||
done
|
||||
export PATH="${P#:}"
|
||||
log " PATH=$PATH"
|
||||
|
||||
# ═══════════ 4/7 CREATE MARKER FILES ═════════════════════════
|
||||
log "[4/7] Creating marker files..."
|
||||
for marker in .procursus_strapped .installed_dopamine; do
|
||||
if [ -f "/var/jb/$marker" ]; then
|
||||
log " $marker already exists"
|
||||
else
|
||||
: > "/var/jb/$marker"
|
||||
chown 0:0 "/var/jb/$marker"
|
||||
chmod 0644 "/var/jb/$marker"
|
||||
log " $marker created"
|
||||
fi
|
||||
done
|
||||
|
||||
# ═══════════ 5/7 INSTALL SILEO ═══════════════════════════════
|
||||
log "[5/7] Installing Sileo..."
|
||||
SILEO_DEB_PATH="/private/preboot/$BOOT_HASH/org.coolstar.sileo_2.5.1_iphoneos-arm64.deb"
|
||||
|
||||
if dpkg -s org.coolstar.sileo >/dev/null 2>&1; then
|
||||
log " Sileo already installed"
|
||||
else
|
||||
if [ -f "$SILEO_DEB_PATH" ]; then
|
||||
dpkg -i "$SILEO_DEB_PATH" || log " dpkg -i sileo exited with $?"
|
||||
log " Sileo installed"
|
||||
else
|
||||
log " WARNING: Sileo deb not found at $SILEO_DEB_PATH"
|
||||
fi
|
||||
fi
|
||||
|
||||
uicache -a 2>/dev/null || true
|
||||
log " uicache refreshed"
|
||||
|
||||
# ═══════════ 6/7 APT SETUP ══════════════════════════════════
|
||||
log "[6/7] Running apt setup..."
|
||||
|
||||
# Determine apt sources directory
|
||||
HAVOC_LIST="/var/jb/etc/apt/sources.list.d/havoc.list"
|
||||
if [ -d /etc/apt/sources.list.d ] && [ ! -d /var/jb/etc/apt/sources.list.d ]; then
|
||||
HAVOC_LIST="/etc/apt/sources.list.d/havoc.list"
|
||||
fi
|
||||
|
||||
if ! grep -rIl 'havoc.app' /etc/apt /var/jb/etc/apt 2>/dev/null | grep -q .; then
|
||||
mkdir -p "$(dirname "$HAVOC_LIST")"
|
||||
printf '%s\n' 'deb https://havoc.app/ ./' > "$HAVOC_LIST"
|
||||
log " Havoc source added: $HAVOC_LIST"
|
||||
else
|
||||
log " Havoc source already present"
|
||||
fi
|
||||
|
||||
apt-get -o Acquire::AllowInsecureRepositories=true \
|
||||
-o Acquire::AllowDowngradeToInsecureRepositories=true \
|
||||
update -qq 2>&1 || log " apt update exited with $?"
|
||||
log " apt update done"
|
||||
|
||||
apt-get -o APT::Get::AllowUnauthenticated=true \
|
||||
install -y -qq libkrw0-tfp0 2>/dev/null || true
|
||||
log " libkrw0-tfp0 done"
|
||||
|
||||
apt-get -o APT::Get::AllowUnauthenticated=true \
|
||||
upgrade -y -qq 2>/dev/null || true
|
||||
log " apt upgrade done"
|
||||
|
||||
# ═══════════ 7/7 INSTALL TROLLSTORE LITE ═════════════════════
|
||||
log "[7/7] Installing TrollStore Lite..."
|
||||
if dpkg -s com.opa334.trollstorelite >/dev/null 2>&1; then
|
||||
log " TrollStore Lite already installed"
|
||||
else
|
||||
apt-get -o APT::Get::AllowUnauthenticated=true \
|
||||
install -y -qq com.opa334.trollstorelite 2>&1 || log " TrollStore install exited with $?"
|
||||
log " TrollStore Lite installed"
|
||||
fi
|
||||
|
||||
uicache -a 2>/dev/null || true
|
||||
log " uicache refreshed"
|
||||
|
||||
# ═══════════ DONE ════════════════════════════════════════════
|
||||
: > "$DONE_MARKER"
|
||||
log "=== vphone_jb_setup.sh complete ==="
|
||||
Reference in New Issue
Block a user