# How the JB Finalization LaunchDaemon Bootstraps Sileo, apt, and TrollStore in vphone-cli

> Discover how the JB finalization LaunchDaemon bootstraps Sileo, apt, and TrollStore in vphone-cli. Learn the automatic setup process for your jailbroken virtual iPhone.

- Repository: [Lakr/vphone-cli](https://github.com/Lakr233/vphone-cli)
- Tags: internals
- Published: 2026-09-13

---

**The JB finalization LaunchDaemon automatically mounts the root filesystem, configures apt sources, and installs Sileo, apt, and TrollStore on the first normal boot of a jailbroken virtual iPhone.**

When you create a virtual iPhone using `vphone-cli` with the jailbreak (JB) or experimental firmware variant, the tool injects a root-level LaunchDaemon that executes once the VM finishes its initial restore. According to the source code in `Lakr233/vphone-cli`, this mechanism ensures the jailbreak environment is fully operational before the user interacts with the system.

## Triggering the Daemon on First Boot

The orchestration logic resides in [`sources/vphone-cli/VPhoneCreateOrchestrator.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneCreateOrchestrator.swift), which detects when the user selects a jailbreak-capable firmware variant. When `variantOption` is set to `.jb` or `.exp`, the CLI prints a finalization notice and prepares the LaunchDaemon payload.

```swift
if variantOption == .jb || variantOption == .exp {
    print("\n=== JB Finalize ===")
    print("[*] JB finalization will run automatically on first normal boot")
    print("    via /cores/vphone_jb_setup.sh (LaunchDaemon).")
    print("    Monitor progress via vphoned file browser: /var/log/vphone_jb_setup.log")
}

```

This output signals that the script at [`/cores/vphone_jb_setup.sh`](https://github.com/Lakr233/vphone-cli/blob/main//cores/vphone_jb_setup.sh) has been embedded into the VM image as `/Library/LaunchDaemons/com.lakr233.vphone.jbsetup.plist`. The daemon is configured to run with root privileges immediately after the kernel finishes mounting the root filesystem.

## Inside the JB Finalization Script

The bulk of the bootstrap logic lives in [`scripts/vphone_jb_setup.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/vphone_jb_setup.sh) (installed inside the VM as [`/cores/vphone_jb_setup.sh`](https://github.com/Lakr233/vphone-cli/blob/main//cores/vphone_jb_setup.sh)). The script performs a sequence of atomic setup tasks to transform the vanilla iOS environment into a functional jailbreak platform.

### Mounting the Filesystem

Before modifying system directories, the script remounts the root partition in read-write mode. This is essential because the virtual iPhone boots initially with a read-only snapshot to prevent corruption during the restore process.

```bash
#!/bin/bash

# Mount rootfs read-write

mount -uw /

```

Without this step, subsequent attempts to write to `/etc/apt/` or `/Applications/` would fail with permission errors.

### Configuring the apt Repository

Next, the script establishes the package manager infrastructure. It creates a source list pointing to the custom firmware (CFW) repository hosted locally within the VM environment.

```bash

# Set up apt source pointing to the CFW repo

cat <<EOF > /etc/apt/sources.list.d/vphone-cfw.list
deb [trusted=yes] http://localhost:8080/packages ./
EOF

# Update package index

apt-get update

```

The `[trusted=yes]` flag bypasses GPG signature checks, allowing the installation of locally compiled packages during the first boot sequence.

### Installing Sileo and TrollStore

With apt operational, the script installs the graphical package manager **Sileo** and the permanent signing utility **TrollStore**. It uses the package manager to resolve dependencies and unpack the binaries into their respective system locations.

```bash

# Install required packages

apt-get install -y apt sileo trollstore

# Alternative manual extraction if deb files are pre-cached

# dpkg -i /var/cache/apt/archives/sileo.deb

# dpkg -i /var/cache/apt/archives/trollstore.deb

```

These commands place the Sileo application bundle in `/Applications/Sileo.app` and the TrollStore helper in its designated daemon directory.

### Registering System Daemons

After installation, the script loads the LaunchDaemons for both applications so they persist across subsequent reboots and become available in the iOS UI.

```bash

# Enable their LaunchDaemons

launchctl load /Library/LaunchDaemons/com.sileo.server.plist
launchctl load /Library/LaunchDaemons/com.trollstore.daemon.plist

# Log completion

echo "JB finalization complete" >> /var/log/vphone_jb_setup.log

```

This step ensures that Sileo’s background server and TrollStore’s persistence daemon start immediately, completing the bootstrap cycle.

## Monitoring the Bootstrap Process

Because the finalization occurs inside the VM without direct video output, `vphone-cli` provides a host-side monitoring mechanism. The orchestrator instructs users to watch `/var/log/vphone_jb_setup.log` via the `vphoned` file browser interface.

From the host Swift code, you can stream this log in real time:

```swift
let logPath = "/var/log/vphone_jb_setup.log"
vphoneControl.downloadFile(at: logPath) { data in
    print(String(decoding: data, as: UTF8.self))
}

```

This allows developers to verify that apt updates completed successfully and that Sileo and TrollStore were installed without errors.

## Summary

- **VPhoneCreateOrchestrator.swift** detects JB variants and notifies the user that finalization will run automatically via [`/cores/vphone_jb_setup.sh`](https://github.com/Lakr233/vphone-cli/blob/main//cores/vphone_jb_setup.sh).
- The LaunchDaemon `/Library/LaunchDaemons/com.lakr233.vphone.jbsetup.plist` executes the script with root privileges on the first normal boot.
- The script **remounts the root filesystem** read-write to enable system modifications.
- It **configures apt** by adding a trusted source list pointing to the CFW repository.
- It **installs Sileo, apt, and TrollStore** using `apt-get` or `dpkg`.
- It **registers the daemons** for Sileo and TrollStore using `launchctl load`.
- Progress is logged to `/var/log/vphone_jb_setup.log`, which the host can monitor via the vsock file browser.

## Frequently Asked Questions

### How does the LaunchDaemon know to run only on the first boot?

The LaunchDaemon is installed with a `RunAtLoad` key set to `true` in its plist, but the underlying script [`/cores/vphone_jb_setup.sh`](https://github.com/Lakr233/vphone-cli/blob/main//cores/vphone_jb_setup.sh) typically removes itself or the plist after successful execution. This prevents the bootstrap routine from running on subsequent reboots, ensuring it acts as a one-time finalization hook.

### Can I modify the packages installed during JB finalization?

Yes. The source file [`scripts/vphone_jb_setup.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/vphone_jb_setup.sh) is part of the repository and can be edited before building the `vphone-cli` binary. Adding or removing `apt-get install` lines allows you to customize which packages are deployed when the VM first boots.

### Where can I check if the bootstrap failed inside the VM?

Check the log file at `/var/log/vphone_jb_setup.log` inside the virtual iPhone filesystem. If the file is missing or truncated, the LaunchDaemon likely failed to start; if it contains error messages from `apt-get` or `dpkg`, the package installation encountered dependency conflicts or repository connectivity issues.

### Is the LaunchDaemon signed or code-signed for iOS?

The `vphone-cli` project targets virtualized iOS environments where signature checks are relaxed or disabled. According to the source, the daemon runs inside a custom firmware (CFW) image that trusts unsigned binaries, allowing the bootstrap script to execute without Apple's standard code signature validation.