mirror of
https://github.com/Lakr233/vphone-cli.git
synced 2026-09-02 02:34:29 +00:00
camera: libvcamcaptured + cameracaptured TweakLoader allowlist + install wiring
libvcamcaptured.dylib is loaded into /usr/libexec/cameracaptured via
TweakLoader and registers a synthetic FigCaptureSource backed by the
vphone shm region. From AVF's point of view there is now a normal
"vphone:vcam:0" camera device that streams BGRA frames at the
session's requested width/height.
scripts/vcamcaptured/ .gitignore (drop built .dylib),
Makefile, libvcamcaptured.m,
libvcamcaptured.plist (filter:
Executables=["cameracaptured"]).
scripts/tweakloader/TweakLoader.m add /usr/libexec/cameracaptured
to kVPhoneAllowedDaemonPaths so
TweakLoader engages in a daemon
(not just .app/) processes.
scripts/cfw_install_exp.sh build_libvcamcaptured() helper
(clang + CoreMedia/CoreVideo/
Foundation, ldid-signed) and
new [JB-4.1] section that
scp's the dylib + plist into
procursus/Library/MobileSubstrate/
DynamicLibraries.
Pairs with the host vphone-cli camera server + vphoned vcam vsock
listener already in this branch.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
committed by
zqxwce
co-authored by
Claude Opus 4.7
parent
c8de9c9cb7
commit
9b4e25569b
@@ -87,20 +87,43 @@ elif [[ ! -f "$JB_SYSOS_DMG" ]]; then
|
||||
fi
|
||||
|
||||
if [[ -f "$JB_SYSOS_DMG" ]]; then
|
||||
# Mount, patch chunks, unmount. Idempotent: re-running on an already
|
||||
# patched DMG is a no-op (patcher detects already-patched form).
|
||||
echo "[*] hv_vmm DSC patch: mounting cached SystemOS DMG..."
|
||||
# Mount, patch chunks (hv_vmm + camera, same cryptex), unmount.
|
||||
# Idempotent: re-running on an already-patched DMG is a no-op
|
||||
# (hv_vmm patcher detects already-patched cstrings; camera patcher
|
||||
# refuses pre-patched function entries unless --force is passed).
|
||||
echo "[*] DSC patches: mounting cached SystemOS DMG..."
|
||||
mkdir -p "$JB_MNT_SYSOS"
|
||||
sudo hdiutil detach "$JB_MNT_SYSOS" -force 2>/dev/null || true
|
||||
sudo hdiutil attach -mountpoint "$JB_MNT_SYSOS" "$JB_SYSOS_DMG" -nobrowse -owners off
|
||||
|
||||
JB_DSC_CHUNKS_DIR="$JB_MNT_SYSOS/System/Library/Caches/com.apple.dyld"
|
||||
JB_DSC_HEADER="$JB_DSC_CHUNKS_DIR/dyld_shared_cache_arm64e"
|
||||
if [[ -d "$JB_DSC_CHUNKS_DIR" ]]; then
|
||||
echo "[*] hv_vmm DSC patch: patching chunks under $JB_DSC_CHUNKS_DIR..."
|
||||
"$SCRIPT_DIR/patch_hv_vmm_userland.sh" dsc "$JB_DSC_CHUNKS_DIR"
|
||||
echo "[+] hv_vmm DSC patch: chunks patched"
|
||||
|
||||
# Camera DSC patches make `cameracaptured` return a single
|
||||
# synthetic `vphone-cam` device and stub out the AVFoundation
|
||||
# init-time validation that would otherwise crash on it. With
|
||||
# these + the /product/camera DT node (added at fw_patch time),
|
||||
# Camera.app's icon shows on Home Screen and the app launches
|
||||
# without immediately bailing. Patch #6 (the BL-site sanity
|
||||
# check inside _captureSourceServer_handleCopySourcesMessage)
|
||||
# is 26.5-build-specific; the patcher aborts cleanly on any
|
||||
# other build, leaving hv_vmm's changes intact.
|
||||
if [[ -f "$JB_DSC_HEADER" ]]; then
|
||||
echo "[*] camera DSC patch: patching chunks under $JB_DSC_CHUNKS_DIR..."
|
||||
if "$SCRIPT_DIR/patch_camera_userland.sh" dsc "$JB_DSC_CHUNKS_DIR" "$JB_DSC_HEADER"; then
|
||||
echo "[+] camera DSC patch: chunks patched"
|
||||
else
|
||||
echo "[!] camera DSC patch: failed (likely build-version mismatch); continuing"
|
||||
fi
|
||||
else
|
||||
echo "[-] camera DSC patch: $JB_DSC_HEADER not found, skipping"
|
||||
fi
|
||||
else
|
||||
echo "[-] hv_vmm DSC patch: $JB_DSC_CHUNKS_DIR not found, skipping"
|
||||
echo "[-] DSC patches: $JB_DSC_CHUNKS_DIR not found, skipping"
|
||||
fi
|
||||
|
||||
sudo hdiutil detach "$JB_MNT_SYSOS" -force
|
||||
@@ -223,6 +246,35 @@ build_tweakloader() {
|
||||
echo "$out"
|
||||
}
|
||||
|
||||
# Builds the libvcamcaptured.dylib injected into /usr/libexec/cameracaptured
|
||||
# via the TweakLoader allowlist. Output goes to TEMP_DIR; caller scp's the
|
||||
# binary + companion plist to procursus/Library/MobileSubstrate/DynamicLibraries.
|
||||
build_libvcamcaptured() {
|
||||
local src="$SCRIPT_DIR/vcamcaptured/libvcamcaptured.m"
|
||||
local out="$TEMP_DIR/libvcamcaptured.dylib"
|
||||
local sdk cc
|
||||
|
||||
[[ -f "$src" ]] || die "Missing libvcamcaptured source at $src"
|
||||
|
||||
sdk="$(xcrun --sdk iphoneos --show-sdk-path)"
|
||||
cc="$(xcrun --sdk iphoneos -f clang)"
|
||||
|
||||
"$cc" -isysroot "$sdk" \
|
||||
-arch arm64e \
|
||||
-miphoneos-version-min=15.0 \
|
||||
-dynamiclib \
|
||||
-fobjc-arc -Os \
|
||||
-install_name /var/jb/usr/lib/libvcamcaptured.dylib \
|
||||
-framework CoreMedia \
|
||||
-framework CoreVideo \
|
||||
-framework Foundation \
|
||||
-o "$out" \
|
||||
"$src"
|
||||
|
||||
ldid_sign "$out"
|
||||
echo "$out"
|
||||
}
|
||||
|
||||
remote_mount() {
|
||||
local dev="$1" mnt="$2" opts="${3:-rw}"
|
||||
ssh_cmd "/bin/mkdir -p $mnt"
|
||||
@@ -479,6 +531,29 @@ ssh_cmd "/bin/chmod 0755 /mnt5/$BOOT_HASH/$JB_DIR_NAME/procursus/usr/lib/TweakLo
|
||||
|
||||
echo " [+] TweakLoader installed to procursus/usr/lib/TweakLoader.dylib"
|
||||
|
||||
# ═══════════ JB-4.1 INSTALL libvcamcaptured ═════════════════════════
|
||||
# Inject dylib loaded into /usr/libexec/cameracaptured (via TweakLoader
|
||||
# allowlist in TweakLoader.m's kVPhoneAllowedDaemonPaths). Hosts the
|
||||
# synthetic FigCaptureSource + shm-frame reader paired with vphoned's
|
||||
# vsock 1338 listener on the guest side.
|
||||
echo ""
|
||||
echo "[JB-4.1] Building and installing libvcamcaptured..."
|
||||
LIBVCAM_OUT="$(build_libvcamcaptured)"
|
||||
LIBVCAM_DIR="/mnt5/$BOOT_HASH/$JB_DIR_NAME/procursus/Library/MobileSubstrate/DynamicLibraries"
|
||||
ssh_cmd "/bin/mkdir -p $LIBVCAM_DIR"
|
||||
scp_to "$LIBVCAM_OUT" "$LIBVCAM_DIR/libvcamcaptured.dylib"
|
||||
ssh_cmd "/usr/sbin/chown 0:0 $LIBVCAM_DIR/libvcamcaptured.dylib"
|
||||
ssh_cmd "/bin/chmod 0755 $LIBVCAM_DIR/libvcamcaptured.dylib"
|
||||
|
||||
# The plist tells TweakLoader to load the dylib only inside cameracaptured
|
||||
# (Filter.Executables = ["cameracaptured"]); keep it next to the dylib.
|
||||
LIBVCAM_PLIST="$SCRIPT_DIR/vcamcaptured/libvcamcaptured.plist"
|
||||
if [[ -f "$LIBVCAM_PLIST" ]]; then
|
||||
scp_to "$LIBVCAM_PLIST" "$LIBVCAM_DIR/libvcamcaptured.plist"
|
||||
ssh_cmd "/bin/chmod 0644 $LIBVCAM_DIR/libvcamcaptured.plist"
|
||||
fi
|
||||
echo " [+] libvcamcaptured installed to procursus/Library/MobileSubstrate/DynamicLibraries/"
|
||||
|
||||
# ═══════════ JB-5 DEPLOY FIRST-BOOT SETUP ══════════════════════
|
||||
echo ""
|
||||
echo "[JB-5] Deploying first-boot setup..."
|
||||
@@ -609,6 +684,7 @@ fi
|
||||
echo ""
|
||||
echo "[*] Unmounting device filesystems..."
|
||||
ssh_cmd "/sbin/umount /mnt1 2>/dev/null || true"
|
||||
ssh_cmd "/sbin/umount /mnt2 2>/dev/null || true"
|
||||
ssh_cmd "/sbin/umount /mnt3 2>/dev/null || true"
|
||||
ssh_cmd "/sbin/umount /mnt5 2>/dev/null || true"
|
||||
|
||||
|
||||
@@ -44,16 +44,35 @@ static NSString *TLExecutablePath(void) {
|
||||
return argv0 ?: @"";
|
||||
}
|
||||
|
||||
// Daemons the loader is explicitly allowed to load tweaks into, even though
|
||||
// they're not under a `.app/` path. Keep this list narrow — every daemon
|
||||
// added here is a process where a buggy tweak can crash a launchd-managed
|
||||
// service and destabilize boot.
|
||||
//
|
||||
// This list ONLY applies to tweaks WITHOUT Filter.Frameworks. Framework-
|
||||
// filtered tweaks engage in every process and self-limit based on which
|
||||
// frameworks are actually loaded — they don't need per-daemon entries here.
|
||||
static NSString *const kVPhoneAllowedDaemonPaths[] = {
|
||||
@"/usr/libexec/cameracaptured", // libvcamcaptured (Filter.Executables match)
|
||||
};
|
||||
|
||||
static BOOL TLShouldRunInCurrentProcess(void) {
|
||||
NSString *execPath = TLExecutablePath();
|
||||
if (!execPath.length) return NO;
|
||||
|
||||
// vphone's hook runtime injects broadly, including launch-critical daemons
|
||||
// like xpcproxy, logd, notifyd, sshd, shells, and helper tools. Restrict the
|
||||
// user tweak loader to app binaries only so it does not destabilize boot or
|
||||
// process launch paths.
|
||||
// user tweak loader to app binaries only — plus an allowlist of daemons
|
||||
// that explicitly opt in (see `kVPhoneAllowedDaemonPaths`).
|
||||
if ([execPath containsString:@".app/"]) return YES;
|
||||
|
||||
for (size_t i = 0;
|
||||
i < sizeof(kVPhoneAllowedDaemonPaths) /
|
||||
sizeof(kVPhoneAllowedDaemonPaths[0]);
|
||||
i++) {
|
||||
if ([execPath isEqualToString:kVPhoneAllowedDaemonPaths[i]]) return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
*.dylib
|
||||
@@ -0,0 +1,23 @@
|
||||
# libvcamcaptured — dylib loaded into cameracaptured via LC_LOAD_DYLIB
|
||||
|
||||
SRCS := $(wildcard *.m)
|
||||
OUT := libvcamcaptured.dylib
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OUT)
|
||||
|
||||
$(OUT): $(SRCS) $(wildcard *.h)
|
||||
@echo "=== Building libvcamcaptured (arm64e, iphoneos, dylib) ==="
|
||||
xcrun -sdk iphoneos clang -arch arm64e -Os -fobjc-arc \
|
||||
-dynamiclib \
|
||||
-install_name /var/jb/usr/lib/libvcamcaptured.dylib \
|
||||
-I. \
|
||||
-o $@ $(SRCS) \
|
||||
-framework Foundation \
|
||||
-framework CoreMedia \
|
||||
-framework CoreVideo
|
||||
@echo " built OK ($$(stat -f%z $(OUT)) bytes)"
|
||||
|
||||
clean:
|
||||
rm -f $(OUT)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Filter</key>
|
||||
<dict>
|
||||
<key>Executables</key>
|
||||
<array>
|
||||
<string>cameracaptured</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
Reference in New Issue
Block a user