xkvm-ios-injector

module
v0.0.0-...-f14773f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 16, 2026 License: MIT

README

 ___    ___ ___  __    ___      ___ _____ ______
|\  \  /  /|\  \|\  \ |\  \    /  /|\   _ \  _   \
\ \  \/  / | \  \/  /|\ \  \  /  / | \  \\\__\ \  \
 \ \    / / \ \   ___  \ \  \/  / / \ \  \\|__| \  \
  /     \/   \ \  \\ \ \  \    / /   \ \  \    \ \  \
 /  /\   \    \ \__\\ \__\ \__/ /     \ \__\    \ \__\
/__/ /\ __\    \|__| \|__|\|__|/       \|__|     \|__|
|__|/ \|__|

The iOS tweak toolbox, in your terminal.

Inject tweaks into apps · extract them back out · convert jailbreak packages between formats.

New here? Run xkvm tui. It asks the same questions the flags do, one at a time, and runs the exact same engine under the hood.

CI Go


What is xkvm?

xkvm is a command-line tool for sideloading iOS apps. Give it an app (.ipa, .tipa, or .app) and a tweak, and it handles the parts that are easy to get wrong: wiring the tweak so it loads, re-signing the result, and repacking the container.

With xkvm you can:

  • Inject tweaks into an app. Add a tweak (.dylib, .deb, framework, or bundle), wire it up so it loads, and re-sign everything so the app still installs.
  • Extract tweaks from an app. Pull the injected tweaks out of a modified app: dylibs, frameworks, bundles, app extensions.
  • Convert jailbreak packages. Translate a tweak package between the three jailbreak styles: rootful (classic), rootless (modern /var/jb), and roothide (jbroot), and between .deb and .dylib forms.
  • Fetch tweaks from Cydia repos. Resolve a tweak by its bundle id through Canister / MobileAPT, including its dependencies.
  • Fix sideloading problems. Inject a bundled set of App Store and keychain repair dylibs, and apply compatibility patches to apps that misbehave when sideloaded.

Everything is written in Go. No external tools are required for the heavy lifting. macOS is the primary platform; the core also builds and tests on Linux.

Features

Tweak injection Add dylibs, debs, frameworks, and bundles to an app, with correct load commands (@rpath, @executable_path) and re-signing.
Tweak extraction xkvm extract pulls every injected artifact back out of an app, recording where each one lived so re-injection is automatic.
Package conversion Ports of the ecosystem's own converters: rootful → rootless → roothide, and .deb to .dylib.
Repo fetching --fetch resolves tweaks by bundle id through Canister / MobileAPT, with dependency recursion.
Shareable configs .cyan files capture every option: generate with cgen, validate with cyan-check, apply with -z.
Sideload fixes --patch injects the bundled sideload-repair dylib set; --ellekit swaps in the real ElleKit hooking runtime.
Completeness checks xkvm check verifies every bundle-relative dependency resolves, so merged tweaks don't crash at launch.
Deterministic builds Same input, same output, with zip-slip-safe extraction and pure-Go Apple-format code signatures.

First run

xkvm tui          # menu mode: answer the questions, no flags to remember

Or straight to the command line:

xkvm -i App.ipa -f MyTweak.dylib -o App-Tweaked.ipa   # inject a tweak
xkvm extract -i App-Tweaked.ipa -o tweaks/            # pull tweaks back out
xkvm rootless -i tweak.deb -o tweak-rootless.deb      # convert a package
xkvm check -i App-Tweaked.ipa                         # find missing files before you install

Installation

One-shot install — downloads the latest release binary, no Go needed:

OS One-liner
macOS / Linux (Ubuntu, Arch, ...) curl -fsSL https://raw.githubusercontent.com/xscope0/xkvm-ios-injector/main/scripts/install.sh | bash
Windows (PowerShell) irm https://raw.githubusercontent.com/xscope0/xkvm-ios-injector/main/scripts/install.ps1 | iex
Any OS with Go go install github.com/xscope0/xkvm-ios-injector/cmd/xkvm@latest

The installers detect your OS and architecture, download the matching release asset, and put xkvm on your PATH. Before the first release ships, they fall back to go install automatically. Set XKVM_PREFIX (bash) to choose the install location (default: ~/.local/bin, or /opt/homebrew/bin on Apple Silicon with Homebrew).

From source (requires Go 1.26+):

git clone https://github.com/xscope0/xkvm-ios-injector.git
cd xkvm-ios-injector
make build          # produces ./bin/xkvm

Check that it works:

xkvm --help

Shell completion (optional)

Tab-completion for flags and subcommands is built in. Generate the script for your shell and load it from your config file:

bash:

xkvm completion bash | sudo tee /etc/bash_completion.d/xkvm > /dev/null

Or, if you use Homebrew's bash (or just want it per-user):

mkdir -p ~/.bash_completion.d
xkvm completion bash > ~/.bash_completion.d/xkvm
# add this line to ~/.bashrc:
# source ~/.bash_completion.d/xkvm

zsh:

mkdir -p ~/.zfunc
xkvm completion zsh > ~/.zfunc/_xkvm
# add these lines to ~/.zshrc:
# fpath+=~/.zfunc
# autoload -Uz compinit && compinit

fish:

xkvm completion fish > ~/.config/fish/completions/xkvm.fish

If you installed xkvm to a different location, make sure that location is on your PATH so the completion script can find it.

Quick start

Inject a tweak into an app:

xkvm -i App.ipa -o Patched.ipa -f MyTweak.dylib

Inject several tweaks and fakesign (AppSync / TrollStore):

xkvm -i App.ipa -o Patched.ipa -f TweakA.dylib -f TweakB.deb -s

Extract the tweaks from a modified app:

xkvm extract -i Patched.ipa -o extracted-tweaks/

Convert a tweak package for a different jailbreak:

xkvm rootless -i classic.deb -o modern.deb        # rootful → rootless
xkvm rootless -i classic.deb -o xina.deb --xina   # rootful → rootless, Xina style
xkvm rootful  -i modern.deb  -o classic.deb       # rootless → rootful (either style)
xkvm roothide -i modern.deb  -o jbroot.deb        # rootless → roothide
xkvm undeb    -i tweak.deb   -o artifacts/        # unpack a .deb
xkvm debify   -i MyTweak.dylib -o MyTweak.deb     # .dylib → .deb

Fetch a tweak from a Cydia repo:

xkvm -i App.ipa -o Patched.ipa --fetch com.example.tweak

Download an app from the App Store by Apple ID (the ipatool / PancakeStore flow):

xkvm decrypt 310633997 --apple-id you@example.com --password …   # latest version
xkvm decrypt https://apps.apple.com/us/app/…/id310633997          # …or a link or bundle id
xkvm decrypt --logout                                            # forget the saved login

Commands

Command What it does
xkvm -i <app> ... Inject tweaks, modify the app, and re-sign it
extract Pull tweaks (dylibs, frameworks, bundles, app extensions) out of an app
rootless Convert a rootful package to the modern rootless layout (--xina for the Xina short-path style)
rootful Convert a rootless package back to the classic rootful layout
roothide Convert a rootless package to a roothide-jailbreak package
debify Build a MobileSubstrate .deb from a dylib or payload directory
undeb Unpack a .deb into its tweak artifacts
check Verify bundle-relative dependencies resolve (merge completeness)
cyan-check Validate a .cyan config file before applying it
cgen Turn your flags into a shareable .cyan config file
decrypt Download an App Store app by Apple ID (with sinfs + metadata) for tweaking
device Control a connected iPhone/iPad: pair, info, install, launch, syslog (go-ios)

Device control in one breath

xkvm device list                  # who's plugged in
xkvm device pair                  # tap "Trust" on the phone, run again
xkvm device install App-Tweaked.ipa   # stream it straight onto the device
xkvm device launch com.example.app    # run it, print the pid
xkvm device syslog                # parsed logs, Ctrl-C to stop
xkvm device omega                 # clear revoke + cert blacklists (Omega)

device omega is the jailbreak.party Omega blacklist remover, ported to the native stack: a partial-backup restore that replaces the revoke and certificate-validity databases with directories the system can't write to — Apple forgets every revoke. Version policy: iOS 16-18 and 26 are supported (26.1 live-verified), <16, 19-25 and >=27 are hard-blocked, and only future unreleased iOS (28+) gets the untested caution. Apple never released iOS 19-25: it moved 18 -> 26 with year-based versioning, so there was never a 19-25 untested gap; on iOS 27 the backup system changed and the restore could reset your data. Turn off Find My and back up first; it asks you to type CONTINUE. Same feature lives in the TUI under device → omega.

device is the other half of the loop: build the .ipa with inject, install it with device, watch its logs with device syslog — no SideStore or Xcode. Backed by go-ios (the same pure-Go talk-to-Apple stack as the Mach-O tooling). See docs/device-control.md for the full surface. The same control surface is in the TUI under the device category — pair, info, battery, apps (launch/uninstall the picked app), install, launch by bundle id, kill by pid, and a live syslog screen.

Note for iOS 17+: launch/kill/install/omega need a developer tunnel the same way pymobiledevice3 needs a mounted Developer Disk Image; xkvm tells you the exact command when it hits that gate. pair/info/battery/ apps work without it, and one physical phone showing up on both USB and WiFi counts as one device.

Common options

Flag What it does
-i, --input The app to modify (.ipa, .tipa, or .app)
-o, --output Where to write the result (defaults to overwriting the input)
-f, --file A tweak to inject — repeatable (dylibs, debs, frameworks, bundles)
-z, --cyan A .cyan config file to apply — repeatable
--fetch Fetch a tweak by bundle id via Canister / MobileAPT
--ellekit Use the real ElleKit hooking runtime
--patch Inject the bundled sideload-repair dylib set (implies --fakesign)
-s, --fakesign Fakesign all binaries (AppSync / TrollStore)
-b / -n / -v / -m Change bundle id, name, app version, or minimum OS version
-k, --icon Change the app icon

Run xkvm --help for the complete list.

How it works

  • Pure-Go Mach-O editing and code signing — built on blacktop/go-macho and its pkg/codesign, producing Apple-format signatures macOS itself validates. No ldid or install_name_tool needed.
  • Faithful package conversion — the converters are ports of the ecosystem's own tools (rootless-patcher, RootHidePatcher), pinned byte-for-byte against upstream output by golden tests.
  • Safety by default — zip-slip-safe container handling, deterministic builds, and a post-conversion audit that flags surviving rootful paths.

Documentation

Project status

Milestone Content Status
M0 Scaffold: CLI, logging, CI done
M1 Containers: ipa/deb/plist, extract command done
M2 Injection parity (hybrid toolchain) done (superseded by M3)
M3 Pure-Go Mach-O (go-macho / codesign) done
M4 Azule fetch: Canister / MobileAPT done
M5 iOS on-device: decrypt, cross-compile planned
M5.5 Device control: pair/install/launch/syslog (go-ios) done
M6 Ship: brew tap, releases, docs planned

Contributing

Contributions are welcome — bug reports, feature ideas, and pull requests. See CONTRIBUTING.md to get started. Every behavior change ships with a test; the house style is golden tests that pin converters byte-for-byte against upstream output.

Acknowledgments

xkvm descends from two lineages and borrows conventions from several more:

  • cyan / pyzule-rw (Unlicense) — the app-modifier / tweak-injector lineage xkvm descends from
  • Azule (archived) — repo fetching and App Store decryption ideas
  • Feather (GPL-3.0) — sideloading and ElleKit conventions
  • rootless-patcher (MIT) — rootless conversion semantics
  • RootHidePatcher (GPL) — roothide conversion semantics (reference only)
  • Derootifier (GPL-3.0) — format reference for --tweakinject
  • ElleKit — the hooking runtime
  • blacktop/go-macho (MIT) — Mach-O parsing and code signing

License

The xkvm source code is licensed under the MIT License.

xkvm also bundles third-party components (the ElleKit runtime, sideload-repair dylibs, and a Cephei framework) under their own licenses. See NOTICE for the full provenance.

Directories

Path Synopsis
cmd
xkvm command
Command xkvm is the entry point for xKVM, the iOS app modifier & tweak injector (cyan + Azule heritage, rewritten in Go).
Command xkvm is the entry point for xKVM, the iOS app modifier & tweak injector (cyan + Azule heritage, rewritten in Go).
internal
app
Package app implements the xkvm processing pipeline.
Package app implements the xkvm processing pipeline.
appbundle
Package appbundle operates on an extracted *.app bundle: metadata edits (name/version/bundle id/min-OS), plist merging, icon replacement, watch app / extension removal, and mass fakesigning/thinning.
Package appbundle operates on an extracted *.app bundle: metadata edits (name/version/bundle id/min-OS), plist merging, icon replacement, watch app / extension removal, and mass fakesigning/thinning.
artifact
Package artifact collects injectable file types from a directory tree: *.dylib files and *.appex / *.framework / *.bundle directories, following cyan's extract_deb conventions.
Package artifact collects injectable file types from a directory tree: *.dylib files and *.appex / *.framework / *.bundle directories, following cyan's extract_deb conventions.
cli
Package cli wires the xkvm command line: flag definitions, help text and subcommands (xkvm, xkvm cgen, ...).
Package cli wires the xkvm command line: flag definitions, help text and subcommands (xkvm, xkvm cgen, ...).
cyanfile
Package cyanfile parses and generates .cyan config archives (the cyan/pyzule-rw shareable-patch format: a zip with config.json + inject/ payloads + optional icon.idk / merge.plist / new.entitlements).
Package cyanfile parses and generates .cyan config archives (the cyan/pyzule-rw shareable-patch format: a zip with config.json + inject/ payloads + optional icon.idk / merge.plist / new.entitlements).
deb
Package deb extracts jailbreak tweak packages (.deb) and returns the injectable artifacts (dylibs, frameworks, appex, bundles) that cyan's extract_deb collects.
Package deb extracts jailbreak tweak packages (.deb) and returns the injectable artifacts (dylibs, frameworks, appex, bundles) that cyan's extract_deb collects.
decrypt
Package decrypt downloads App Store apps by Apple ID (the ipatool / PancakeStore flow) so they can be injected and sideloaded.
Package decrypt downloads App Store apps by Apple ID (the ipatool / PancakeStore flow) so they can be injected and sideloaded.
device
Package device wraps go-ios (github.com/danielpaulus/go-ios) with the xkvm contract: typed errors with remediation text, a deterministic device-resolution policy, and a Handler seam so every operation is testable without hardware.
Package device wraps go-ios (github.com/danielpaulus/go-ios) with the xkvm contract: typed errors with remediation text, a deterministic device-resolution policy, and a Handler seam so every operation is testable without hardware.
extras
Package extras embeds the hooking frameworks xkvm auto-injects (CydiaSubstrate, Orion, Cephei, CepheiUI, CepheiPrefs, ElleKit) and the sideload-fix dylibs --patch injects — the same set cyan ships in its extras/ directory.
Package extras embeds the hooking frameworks xkvm auto-injects (CydiaSubstrate, Orion, Cephei, CepheiUI, CepheiPrefs, ElleKit) and the sideload-fix dylibs --patch injects — the same set cyan ships in its extras/ directory.
inject
Package inject implements tweak injection into an extracted app bundle, ported from cyan's MainExecutable.inject(): deb expansion, per-type placement (dylib/framework → Frameworks, appex → PlugIns, other → root), common-dependency fixing (CydiaSubstrate→ElleKit-style paths, Orion, Cephei*), auto-injection of missing hooking frameworks from extras/, and entitlement preservation across the binary edits.
Package inject implements tweak injection into an extracted app bundle, ported from cyan's MainExecutable.inject(): deb expansion, per-type placement (dylib/framework → Frameworks, appex → PlugIns, other → root), common-dependency fixing (CydiaSubstrate→ElleKit-style paths, Orion, Cephei*), auto-injection of missing hooking frameworks from extras/, and entitlement preservation across the binary edits.
ipa
Package ipa handles .ipa/.tipa containers: extraction of the app bundle from a Payload/ archive and repacking with configurable compression.
Package ipa handles .ipa/.tipa containers: extraction of the app bundle from a Payload/ archive and repacking with configurable compression.
log
Package log implements xkvm's console output conventions, mirroring cyan's terminal style: [*] info, [?] warning, [!] error, [<] prompt.
Package log implements xkvm's console output conventions, mirroring cyan's terminal style: [*] info, [?] warning, [!] error, [<] prompt.
patch
Package patch implements Feather-style togglable compatibility patches applied to an extracted app bundle.
Package patch implements Feather-style togglable compatibility patches applied to an extracted app bundle.
plist
Package plist wraps howett.net/plist for Info.plist-style files: binary and XML decoding, binary encoding (the format real app Info.plists ship in, and the safest default when rewriting), and XML encoding for plists that were authored as XML.
Package plist wraps howett.net/plist for Info.plist-style files: binary and XML decoding, binary encoding (the format real app Info.plists ship in, and the safest default when rewriting), and XML encoding for plists that were authored as XML.
rootless
Rootful conversion (rootless deb -> rootful deb), the reverse of both the standard rootless pipeline (rootless-patcher) and the Xina-style pipeline (Xinam1nePatcher — see NOTICE).
Rootful conversion (rootless deb -> rootful deb), the reverse of both the standard rootless pipeline (rootless-patcher) and the Xina-style pipeline (Xinam1nePatcher — see NOTICE).
testutil
Package testutil builds real Mach-O fixtures for xkvm's end-to-end tests: the app main executable and a "tweak" dylib are produced by the actual Go toolchain on the host, then exercised through the native (pure-Go) macho operations.
Package testutil builds real Mach-O fixtures for xkvm's end-to-end tests: the app main executable and a "tweak" dylib are produced by the actual Go toolchain on the host, then exercised through the native (pure-Go) macho operations.
tui
Art and color helpers for the xkvm TUI.
Art and color helpers for the xkvm TUI.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL