Introduce Patchless Variant

This commit is contained in:
Maximilian Paß
2026-04-08 18:29:01 +03:00
committed by zqxwce
parent 3024223b0c
commit b81fa62a11
5 changed files with 120 additions and 65 deletions
+15 -3
View File
@@ -109,8 +109,12 @@ help:
.PHONY: setup_machine setup_tools
setup_machine:
@if [ "$(filter 1 true yes YES TRUE,$(JB))" != "" ] && [ "$(filter 1 true yes YES TRUE,$(DEV))" != "" ]; then \
echo "Error: JB=1 and DEV=1 are mutually exclusive"; \
@if count=0; \
[ -n "$(filter 1 true yes YES TRUE,$(JB))" ] && count=$$((count+1)); \
[ -n "$(filter 1 true yes YES TRUE,$(DEV))" ] && count=$$((count+1)); \
[ -n "$(filter 1 true yes YES TRUE,$(LESS))" ] && count=$$((count+1)); \
[ $$count -gt 1 ]; then \
echo "Error: JB=1, DEV=1, and LESS=1 are mutually exclusive"; \
exit 1; \
fi
SUDO_PASSWORD="$(SUDO_PASSWORD)" \
@@ -118,6 +122,7 @@ setup_machine:
zsh $(SCRIPTS)/setup_machine.sh \
$(if $(filter 1 true yes YES TRUE,$(JB)),--jb,) \
$(if $(filter 1 true yes YES TRUE,$(DEV)),--dev,) \
$(if $(filter 1 true yes YES TRUE,$(LESS)),--less,) \
$(if $(filter 1 true yes YES TRUE,$(SKIP_PROJECT_SETUP)),--skip-project-setup,)
setup_tools:
@@ -265,7 +270,7 @@ boot_dfu: build boot_binary_check
# Firmware pipeline
# ═══════════════════════════════════════════════════════════════════
.PHONY: fw_prepare fw_patch fw_patch_dev fw_patch_jb
.PHONY: fw_prepare fw_patch fw_patch_less fw_patch_dev fw_patch_jb
fw_prepare:
cd $(VM_DIR) && bash "$(CURDIR)/$(SCRIPTS)/fw_prepare.sh"
@@ -273,6 +278,13 @@ fw_prepare:
fw_patch: patcher_build
"$(CURDIR)/$(PATCHER_BINARY)" patch-firmware --vm-directory "$(CURDIR)/$(VM_DIR)" --variant regular
fw_patch_less: patcher_build
@sh -c 'if [ "$$(id -u)" -ne 0 ]; then \
echo "fw_patch_less must be run via sudo" >&2; \
exit 1; \
fi; \
"$(CURDIR)/$(PATCHER_BINARY)" patch-firmware --vm-directory "$(CURDIR)/$(VM_DIR)" --variant less'
fw_patch_dev: patcher_build
"$(CURDIR)/$(PATCHER_BINARY)" patch-firmware --vm-directory "$(CURDIR)/$(VM_DIR)" --variant dev
+5 -2
View File
@@ -17,11 +17,12 @@ Boot a virtual iPhone (iOS 26) via Apple's Virtualization.framework using PCC re
## Firmware Variants
Three patch variants are available with increasing levels of security bypass:
Four patch variants are available with increasing levels of security bypass:
| Variant | Boot Chain | CFW | Make Targets |
| --------------- | :---------: | :-------: | ---------------------------------- |
| **Regular** | 1 patch | 10 phases | `fw_patch` + `cfw_install` |
| **Patchless** | 2 patches | 2 phases | `fw_patch_less` (sudo) |
| **Regular** | 41 patches | 10 phases | `fw_patch` + `cfw_install` |
| **Development** | 52 patches | 12 phases | `fw_patch_dev` + `cfw_install_dev` |
| **Jailbreak** | 112 patches | 14 phases | `fw_patch_jb` + `cfw_install_jb` |
@@ -103,6 +104,7 @@ git clone --recurse-submodules https://github.com/Lakr233/vphone-cli.git
```bash
make setup_machine # full automation through "First Boot" (includes restore/ramdisk/CFW)
# options: NONE_INTERACTIVE=1 SUDO_PASSWORD=...
# LESS=1 for patchless variant (- AMFI, SSV, Img4, TXM bypasses)
# DEV=1 for dev variant (+ TXM entitlement/debug bypasses)
# JB=1 for jailbreak variant (+ full security bypass)
```
@@ -116,6 +118,7 @@ make vm_new # create VM directory with manifest (config.plist)
# options: CPU=8 MEMORY=8192 DISK_SIZE=64
make fw_prepare # download IPSWs, extract, merge, generate manifest
make fw_patch # patch boot chain (regular variant)
# or: sudo make fw_patch_less # patchless variant (- AMFI, SSV, Img4, TXM bypasses)
# or: make fw_patch_dev # dev variant (+ TXM entitlement/debug bypasses)
# or: make fw_patch_jb # jailbreak variant (+ full security bypass)
```
+35 -2
View File
@@ -58,6 +58,7 @@ NONE_INTERACTIVE_RAW="${NONE_INTERACTIVE:-0}"
NONE_INTERACTIVE=0
JB_MODE=0
DEV_MODE=0
LESS_MODE=0
SKIP_PROJECT_SETUP=0
die() {
@@ -736,6 +737,19 @@ run_make() {
make "$@"
}
run_make_sudo() {
local label="$1"
shift
echo ""
echo "=== ${label} ==="
if [[ -n "${SUDO_PASSWORD:-}" ]]; then
sudo -A -- make "$@"
else
sudo -- make "$@"
fi
}
start_boot_dfu() {
mkdir -p "$LOG_DIR"
@@ -944,6 +958,9 @@ parse_args() {
--dev)
DEV_MODE=1
;;
--less)
LESS_MODE=1
;;
--skip-project-setup)
SKIP_PROJECT_SETUP=1
;;
@@ -954,6 +971,7 @@ Usage: setup_machine.sh [--jb] [--dev] [--skip-project-setup]
Options:
--jb Use jailbreak firmware patching + jailbreak CFW install.
--dev Use dev firmware patching + dev CFW install.
--less Use patchless firmware patching + CFW install.
--skip-project-setup Skip setup_tools/build stage.
Environment:
@@ -980,8 +998,8 @@ main() {
local cfw_install_target="cfw_install"
local mode_label="base"
if [[ "$JB_MODE" -eq 1 && "$DEV_MODE" -eq 1 ]]; then
die "--jb and --dev are mutually exclusive"
if (( JB_MODE + DEV_MODE + LESS_MODE > 1 )); then
die "--jb, --dev, and --less are mutually exclusive"
fi
if [[ "$JB_MODE" -eq 1 ]]; then
@@ -992,6 +1010,10 @@ main() {
fw_patch_target="fw_patch_dev"
cfw_install_target="cfw_install_dev"
mode_label="dev"
elif [[ "$LESS_MODE" -eq 1 ]]; then
fw_patch_target="fw_patch_less"
cfw_install_target=""
mode_label="less"
fi
echo "[*] setup_machine mode: ${mode_label}, project_setup=$([[ "$SKIP_PROJECT_SETUP" -eq 1 ]] && echo "skip" || echo "run"), non_interactive=${NONE_INTERACTIVE}"
@@ -1015,7 +1037,11 @@ main() {
run_make "Firmware prep" vm_new
run_make "Firmware prep" fw_prepare
if [[ "$LESS_MODE" -eq 0 ]]; then
run_make "Firmware patch" "$fw_patch_target"
else
run_make_sudo "Firmware patch" "$fw_patch_target"
fi
echo ""
echo "=== Restore phase ==="
@@ -1026,6 +1052,8 @@ main() {
run_make "Restore" restore RESTORE_UDID="$DEVICE_UDID" RESTORE_ECID="0x$DEVICE_ECID"
wait_for_post_restore_reboot
stop_boot_dfu
if [[ "$LESS_MODE" -eq 0 ]]; then
echo "[*] Waiting ${POST_KILL_SETTLE_DELAY}s for cleanup before ramdisk stage..."
sleep "$POST_KILL_SETTLE_DELAY"
@@ -1070,6 +1098,7 @@ main() {
BOOT_FIFO_FD=""
rm -f "$BOOT_FIFO" || true
BOOT_FIFO=""
fi
if [[ "$JB_MODE" -eq 1 ]]; then
echo ""
@@ -1084,7 +1113,11 @@ main() {
echo "Setup completed."
echo "=== Boot analysis ==="
if [[ "$LESS_MODE" -eq 0 ]]; then
run_boot_analysis
else
run_make "Start VM" boot
fi
}
main "$@"
@@ -24,6 +24,7 @@ public final class FirmwarePipeline {
// MARK: - Variant
public enum Variant: String, Sendable {
case less
case regular
case dev
case jb
@@ -173,7 +174,7 @@ public final class FirmwarePipeline {
inRestoreDir: false,
searchPatterns: ["AVPBooter*.bin"],
patcherFactories: {
if variant != .regular {
if variant != .less {
return [
{ data, verbose in
AVPBooterPatcher(data: data, verbose: verbose)
@@ -191,9 +192,9 @@ public final class FirmwarePipeline {
searchPatterns: ["Firmware/dfu/iBSS.vresearch101.RELEASE.im4p"],
patcherFactories: {
return switch variant {
case .regular:
case .less:
[]
case .dev:
case .regular, .dev:
[{ data, verbose in
IBootPatcher(data: data, mode: .ibss, verbose: verbose)
}]
@@ -210,16 +211,16 @@ public final class FirmwarePipeline {
}()
))
// 3. iBEC The automatic patching is disabled for the regular variant (you can still just place a custom component there).
// 3. iBEC The automatic patching is disabled for the patchless variant (you can still just place a custom component there).
components.append(ComponentDescriptor(
name: "iBEC",
inRestoreDir: true,
searchPatterns: ["Firmware/dfu/iBEC.vresearch101.RELEASE.im4p"],
patcherFactories: {
return switch variant {
case .regular:
case .less:
[]
case .dev, .jb:
case .regular, .dev, .jb:
[{ data, verbose in
IBootPatcher(data: data, mode: .ibec, verbose: verbose)
}]
@@ -227,16 +228,16 @@ public final class FirmwarePipeline {
}()
))
// 4. LLB The automatic patching is disabled for the regular variant (you can still just place a custom component there).
// 4. LLB The automatic patching is disabled for the patchless variant (you can still just place a custom component there).
components.append(ComponentDescriptor(
name: "LLB",
inRestoreDir: true,
searchPatterns: ["Firmware/all_flash/LLB.vresearch101.RELEASE.im4p"],
patcherFactories: {
return switch variant {
case .regular:
case .less:
[]
case .dev, .jb:
case .regular, .dev, .jb:
[{ data, verbose in
IBootPatcher(data: data, mode: .llb, verbose: verbose)
}]
@@ -251,8 +252,12 @@ public final class FirmwarePipeline {
searchPatterns: ["Firmware/txm.iphoneos.research.im4p"],
patcherFactories: {
return switch variant {
case .regular:
case .less:
[]
case .regular:
[{ data, verbose in
TXMPatcher(data: data, verbose: verbose)
}]
case .dev, .jb:
[{ data, verbose in
TXMDevPatcher(data: data, verbose: verbose)
@@ -268,9 +273,9 @@ public final class FirmwarePipeline {
searchPatterns: ["kernelcache.research.vphone600"],
patcherFactories: {
return switch variant {
case .regular:
case .less:
[]
case .dev:
case .regular, .dev:
[{ data, verbose in
KernelPatcher(data: data, verbose: verbose)
}]
@@ -304,11 +309,11 @@ public final class FirmwarePipeline {
searchPatterns: ["BuildManifest.plist"],
patcherFactories: {
return switch variant {
case .regular:
case .less:
[{ data, verbose in
CryptexFilesystemPatcher(buildManiest: data, restoreDir: try! self.findRestoreDirectory(), verbose: verbose)
}]
case .dev, .jb:
case .regular, .dev, .jb:
[]
}
}()
@@ -321,11 +326,11 @@ public final class FirmwarePipeline {
searchPatterns: ["BuildManifest.plist"],
patcherFactories: {
return switch variant {
case .regular:
case .less:
[{ data, verbose in
ManifestHashPatcher(data: data, restoreDir: try? self.findRestoreDirectory(), verbose: verbose)
}]
case .dev, .jb:
case .regular, .dev, .jb:
[]
}
}()
+2
View File
@@ -108,12 +108,14 @@ struct VPhoneBootCLI: ParsableCommand {
struct PatchFirmwareCLI: ParsableCommand {
enum VariantOption: String, CaseIterable, ExpressibleByArgument {
case less
case regular
case dev
case jb
var pipelineVariant: FirmwarePipeline.Variant {
switch self {
case .less: .less
case .regular: .regular
case .dev: .dev
case .jb: .jb