How Dopamine Handles Kernel Structure Offsets and Version-Specific Changes in iOS Jailbreaking

Dopamine centralizes kernel structure offset management in BaseBin/libjailbreak/src/info.c and info.h, using a hybrid approach of dynamic runtime deserialization and hard-coded version-specific tables to maintain compatibility across iOS 15–18+ and diverse hardware configurations.

The Dopamine jailbreak must reliably locate kernel structures—proc, task, pmap, trustcache, and dozens more—whose memory layouts shift with every major iOS release, CPU family, and security subsystem (PAC, SPTM/TXM). Rather than scattering magic numbers throughout the codebase, Dopamine implements a unified offset resolution system that adapts to the runtime environment.

Dynamic vs. Hard-Coded Offset Initialization

Dopamine supports two initialization paths for populating its global offset table gSystemInfo.kernelStruct.

Dynamic offset injection allows a helper process to supply a complete dictionary of offsets at runtime. The function jbinfo_initialize_dynamic_offsets deserializes this data using SYSTEM_INFO_DESERIALIZE and overwrites any existing hard-coded values:

// From BaseBin/libjailbreak/src/info.c
void jbinfo_initialize_dynamic_offsets(xpc_object_t xdict) {
    SYSTEM_INFO_DESERIALIZE(&gSystemInfo, xdict);
    // Dynamic values now override compiled defaults
}

Hard-coded offset tables serve as the fallback when no external dictionary is provided. jbinfo_initialize_hardcoded_offsets constructs the complete offset table by inspecting the device's Darwin version, XNU version, CPU family, and security features.

Environment Detection for Kernel Structure Offsets

Before selecting offsets, Dopamine characterizes the running kernel through several system queries:

  • uname() extracts the Darwin version (darwinVersion)
  • Direct parsing determines the xnuVersion
  • host_is_arm64e() detects ARM64e architecture
  • sysctlbyname("hw.cpufamily") identifies the specific CPU family

These values drive conditional logic that applies version-specific adjustments to base offsets.

Version-Specific and Hardware-Specific Adjustments

Dopamine applies several categories of conditional adjustments before finalizing the offset table.

JITBOX adjustments modify the task_can_transfer_memory_ownership field for CPUs with JIT capabilities. The shift amount grows with newer iOS releases:

// BaseBin/libjailbreak/src/info.c
int taskJitboxAdjust = 0;
if (isJitboxDevice) {
    if (ios_version >= 18.4) taskJitboxAdjust = 0x20;
    else if (ios_version >= 16.0) taskJitboxAdjust = 0x18;
    else if (ios_version >= 15.0) taskJitboxAdjust = 0x10;
}

EL2 adjustments add +8 to pmap offsets when the kernel runs at Exception Level 2 (pmapEl2Adjust).

A11-specific pmap adjustments apply an extra offset to the pmap.type field for CPUFAMILY_ARM_MONSOON_MISTRAL devices.

iOS 27 TXM adjustments require pmapA13A14TXMiOS27Adjust = -8 for A13/A14 devices due to address-space layout changes in the TXM (Trusted Execution Monitor) environment.

Populating the Kernel Structure Offset Table

The initialization sequence fills gSystemInfo.kernelStruct with base offsets corresponding to iOS 15-style kernels, then applies successive version-conditional patches:

iOS Version Key Structural Changes
iOS 15+ Adds proc.svuid, proc.svgid, updates task_can_transfer_memory_ownership
iOS 15.2+ Migrates proc.ucred and proc.csflags into proc_ro substructure
iOS 16+ Removes proc.task field (now at proc + sizeof(proc)), updates filedesc.ofiles_start, socket.usecount
iOS 16.1+ Enables ipc_space.table_uses_smr SMR flag
iOS 16.3+/16.4 Adjusts pmap offsets, handles 16.4 beta compatibility
iOS 17+ (SPTM/TXM) Switches to SPTM/TXM structures, modifies PVH flags, updates pmap.sw_asid, IOSurface.memoryDescriptor
iOS 18+ Trustcache layout changes, VM map flag updates, additional pmap tweaks

From BaseBin/libjailbreak/src/info.c, the base assignments follow this pattern:

// iOS 15 baseline offsets
gSystemInfo.kernelStruct.proc.list_next = 0x0;
gSystemInfo.kernelStruct.proc.task = 0x10;
gSystemInfo.kernelStruct.task.map = 0x28;
// ... additional base fields

Subsequent conditional blocks mutate these values for newer releases.

Runtime Usage of Kernel Structure Offsets

Throughout Dopamine's kernel-interacting modules, code references gSystemInfo.kernelStruct rather than literal offsets. This abstraction enables single code paths to function across all supported iOS versions.

Reading the proc.pid field:

uint64_t proc = /* kernel address of proc structure */;
uint32_t pid_offset = gSystemInfo.kernelStruct.proc.pid;
uint32_t pid = kread32(proc + pid_offset);
// Automatically resolves to 0x68 on iOS 15-16, adjusted value on iOS 17+

Writing the task_can_transfer_memory_ownership field with JITBOX awareness:

uint64_t task = /* kernel address of task structure */;
uint32_t offset = gSystemInfo.kernelStruct.task.task_can_transfer_memory_ownership;
kwrite64(task + offset, new_value);
// Composite offset includes base value + taskJitboxAdjust + any version shifts

The kread32, kwrite64, and related primitives in BaseBin/libjailbreak/src/kernel.c consume these offsets to perform type-safe kernel memory operations.

Key Source Files for Offset Management

File Purpose
BaseBin/libjailbreak/src/info.c Builds gSystemInfo table, handles dynamic deserialization and hard-coded version logic
BaseBin/libjailbreak/src/info.h Declares system_info struct with nested kernelStruct, kernelConstant, and related fields
BaseBin/libjailbreak/src/kernel.c Kernel read/write primitives using gSystemInfo.kernelStruct offsets
BaseBin/libjailbreak/src/util.c Helper functions for low-level memory operations dependent on resolved offsets

Summary

  • Centralized offset management in info.c/info.h eliminates magic numbers from Dopamine's kernel code
  • Dual initialization paths support both external dynamic offset injection and self-contained hard-coded tables
  • Multi-factor environment detection considers Darwin version, XNU version, CPU family, EL level, and JITBOX presence
  • Layered version adjustments apply incremental patches from iOS 15 baseline through iOS 18+ and beyond
  • Runtime abstraction through gSystemInfo.kernelStruct enables portable kernel manipulation code

Frequently Asked Questions

How does Dopamine handle kernel structure changes between iOS versions?

Dopamine maintains a baseline offset table matching iOS 15 kernel layouts, then applies conditional adjustments for each subsequent major version. The jbinfo_initialize_hardcoded_offsets function in BaseBin/libjailbreak/src/info.c chains version checks that modify specific fields—for example, relocating proc.ucred to the proc_ro substructure for iOS 15.2+, or removing the embedded proc.task pointer entirely for iOS 16+.

Can Dopamine receive kernel offsets from an external source?

Yes. The jbinfo_initialize_dynamic_offsets function accepts an XPC dictionary containing offset values that override compiled defaults. This allows development builds or supplementary tools to inject corrected offsets without recompiling, useful for rapid iteration on beta iOS versions.

What hardware variations affect kernel structure offsets in Dopamine?

CPU family, ARM64e status, JITBOX capability, and EL2 execution level all influence offset calculations. Specific examples include A11 devices requiring pmap type adjustments, ARM64e devices needing pointer authentication awareness, and EL2 environments shifting pmap offsets by 8 bytes. The initialization code queries hw.cpufamily and host_is_arm64e() to apply these conditionals.

How does Dopamine support unreleased iOS versions like iOS 27?

The codebase includes provisional adjustments such as pmapA13A14TXMiOS27Adjust = -8 based on pre-release analysis of TXM address-space changes. These forward-looking definitions allow Dopamine to bootstrap on new iOS versions before complete offset tables are validated, with dynamic offset injection serving as a fallback for rapid patching.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →