Discussion CyberKit Explained: A Technical Overview
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 https://github.com/UInt2048/CyberKit/commits/dc62ebde43c51e543ec740e447cb3e5603dc58a7/. 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