Load the camera hooks without a bootstrap and add the environment update

The camera hooks were built and shipped but never reached the guest, so
Camera.app could not show a streamed frame. cfw install now places
libvcamcaptured.dylib and libcamfix.dylib in /usr/lib beside the launchd
hook and SystemHook. SystemHook treats /usr/libexec/cameracaptured as an
injection target and loads the daemon hook there, and loads libcamfix into
app processes that have AVFoundation loaded. Both hooks install their own
Objective-C method replacements, so neither needs ElleKit or a bootstrap.

A running guest gets changed copies of those four libraries through the
new vphoned environment update. environment.status reports the SHA-256 of
each library in /usr/lib; environment.install checks the uploaded copies,
remounts / read-write when needed, renames each library into place and
remounts / read-only again, because jailbreak detection reads a writable
root as rootful. It stops cameracaptured when a camera hook or SystemHook
changed and reports when the launchd hook needs a guest restart. The VM
process runs the update once per connection, after the vphoned
self-update, uploading only libraries whose hashes differ.

Not yet verified in a guest; the validation steps are in
Research/0_binary_patch_comparison.md and Research/vphoned_http_api.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Lakr233
2026-09-25 14:57:12 +07:00
co-authored by Claude Opus 5.5
parent 961f18c075
commit fc57dca56b
12 changed files with 316 additions and 29 deletions
@@ -254,7 +254,7 @@ struct VPhoneCustomFirmwareInstaller {
)
try patchWatchdog(system: system, work: work)
try installVphoned(system: system, work: work)
try installLaunchHook(system: system)
try installEnvironment(system: system)
try patchMachO(
system: system,
work: work,
@@ -382,8 +382,10 @@ struct VPhoneCustomFirmwareInstaller {
try replace(temp, at: launchd, mode: 0o644)
}
private func installLaunchHook(system: URL) throws {
for name in ["launchdhook-vphone.dylib", "SystemHook-vphone.dylib"] {
// The launchd hook, SystemHook and the camera hooks. SystemHook loads the
// camera hooks from /usr/lib without a bootstrap or tweak loader.
private func installEnvironment(system: URL) throws {
for name in VPhoneGuestEnvironment.libraries {
let source = try VPhoneGuestBinaries.resolve(name)
try replace(source, at: system.appendingPathComponent("usr/lib/\(name)"), mode: 0o755)
}