This is an automated archive made by the Lemmit Bot.

The original was posted on /r/jailbreak by /u/JapanStar49 on 2024-10-28 02:19:22+00:00.


CyberKit has been in many ways been a proof-of-concept, so it’s only fitting that it would eventually get a write-up explaining how it works. I’ll be doing this write-up with respect to the current development branch, currently at . The purpose of this is to explain what CyberKit commits do, because I think the knowledge of how to make a browser with a third-party browser engine for jailbroken iOS should be documented somewhere other than by reading CyberKit commit history (which includes unhelpful generated commits in the hundreds of thousands of lines that I’ve never read either).

For those of you unfamiliar, CyberKit is a fork of WebKit, which is the open-source browser engine used, and mandated, by iOS before 17.4. (Since CyberKit came out before 17.4, the ability to use alternative browser engines than the system WebKit is arguably yet another feature stolen by Apple from jailbreakers.)

CyberKit is not a browser, although like WebKit, releases are provided with browsers in order to use it effectively. It’s actually a collection of frameworks that provide an alternative newer implementation of the system frameworks with the same names. Conveniently, this property means that (virtually) any app that has a dependency on a WebKit framework (such as WebKit.framework) can be made to depend on CyberKit instead, because dynamic libraries store their dependencies in load commands that can easily be edited without even having the source code of the app. Even MobileMiniBrowser releases are now generated this way.

While it is a jailbreak application, a lot of CyberKit development is just taking previously removed code from WebKit history, and finding ways around the various obstacles iOS put in our way, intentionally or not.

If you’re compiling yourself, open the workspace, set the build and intermediates directory to “WebKitBuild” relative to the workspace, and run the targets “Everything up to WebKit” and then “MobileMiniBrowser”.


The first thing we need to do is configure jetsam. We actually only have ever needed this so far for the XPC services that actually do the work (for proof, see the legacy jetsam configuration wiki page), because iOS assigns abysmally low jetsam limits by default to XPC services (think 6-8MB of memory allowed, which is why iOS 17.4+ had to switch over to extensions when it applied the newly introduced BrowserKit to WebKit as well).

The jetsam configuration commit handles this by inserting some memorystatus_control syscalls (this requires an entitlement, more on those later) in the XPC service entry point file. The special __attribute__ ((constructor)) syntax (for tweak devs reading, this is what the preprocessor %ctor Logos directive stands for) causes the jetsamConfigurator function to run at load time, before even the main function (entry point), so we can easily raise our jetsam limits to a more manageable 840 MB.

Next, we set some configurations to globally set the deployment target of CyberKit (because WebKit doesn’t set one, so it defaults to the Xcode SDK version, which is obviously bad for us).

The fakesign script is there to automatically build DEB and TrollStore IPA releases from an app — such as the example barebones WebKit browser known as MobileMiniBrowser, which by itself is actually only 202 KB decompressed excluding any app icon (not a typo, it really isn’t even a single megabyte) — and build folder, and put everything together (because WebKit doesn’t provide on-device iOS build scripts for obvious reasons). We fakesign WebKit because we need to be jailbroken anyways to get enough entitlements. This is where CyberKit’s entitlements (the list is not perfect, but gets the job done — it was obtained experimentally from logs and through lists of entitlements) are appended to the existing entitlements, if any, of each framework and the app itself, and the app’s dependencies are corrected. Because we obviously can’t just use the system WebKit which is stored in the dyld shared cache, this step is costly in terms of storage space — for instance, MobileMiniBrowser is now as high as 1.65 GB decompressed after doing this.

Skipping ahead momentarily, we have two other new scripts. The ICU compile script (mostly thanks to ) allows us to bundle the latest version of the open-source ICU library as well, because the system framework version gets outdated with the release of new Unicode versions, and although not a part of WebKit itself, it is a required dependency. The semi-rename script fixes bundle identifiers, because they must be unique for things to work properly and there’s no reason we shouldn’t correct this.

The next commit fixes more configuration issues, such as forcing WebKit to base the decision of XPC services vs. 17.4+ extensions on the deployment target instead of the SDK version. We also need to add WebKitSwiftOverlay to the target because it wasn’t actually integrated into WebKit.framework until just hours ago on the main branch (!) — see — and browsers written in Swift (e.g. Firefox) depend on these Swift implementations being there.

Anything else (this part probably is actually the majority of CyberKit effort, although technically less challenging) is effectively debugging — just finding fixes (usually implemented by using conditional compilation, often by setting values in PlatformHave.h to their historical values (WebKit removes/simplifies these conditions that become redundant to them after they stop supporting an iOS version), to exclude code that depends on new APIs) as needed to make it compile, link, and run. If you’re able to read code in Objective-C (and hopefully write some too), this stuff is actually something you could do (assuming you had the time to devote to it).