ARM64e Device Support Requirements and PAC Bypass Needs for Dopamine: A Deep Dive

Dopamine requires ARM64e devices to run a PAC bypass library before executing kernel exploits, with support tiers determined by CPU family and Secure Process Token Manager (SPTM) availability..

The opa334/Dopamine jailbreak targets iOS 15 through 18 and beyond, but ARM64e devices introduce unique constraints due to Pointer Authentication Codes (PAC). This article breaks down how Dopamine detects ARM64e hardware, determines version compatibility, and enforces PAC bypass requirements based on the actual source implementation.

How Dopamine Detects ARM64e Architecture

Dopamine identifies ARM64e devices at runtime through sysctl queries rather than compile-time definitions. The detection logic resides in DOEnvironmentManager.m.

The isArm64e Method

The -isArm64e method reads the hw.cpusubtype sysctl and compares it against CPU_SUBTYPE_ARM64E:

// DOEnvironmentManager.m (lines 215-221)
- (BOOL)isArm64e
{
    cpu_subtype_t subtype;
    size_t size = sizeof(subtype);
    sysctlbyname("hw.cpusubtype", &subtype, &size, NULL, 0);
    return subtype == CPU_SUBTYPE_ARM64E;
}

View source: DOEnvironmentManager.m#L215-L221

This runtime check allows Dopamine to differentiate between plain ARM64 (A9-A11) and ARM64e (A12+) devices without recompilation.

Version Support Matrix for ARM64e Devices

Once ARM64e is confirmed, -versionSupportString applies additional CPU family and SPTM checks to determine exact iOS support ranges.

CPU Family Classification

Dopamine distinguishes between two ARM64e generations:

CPU Family Devices Constant
A12/A13 iPhone XS/XR/11 series CPUFAMILY_ARM_VORTEX_TEMPEST or CPUFAMILY_ARM_LIGHTNING_THUNDER
A14+ iPhone 12 and later Other ARM64e families

SPTM Detection

The Secure Process Token Manager (SPTM) indicates newer hardware security features. Dopamine checks this via -isSPTM, which examines the hw.targettype or equivalent hardware properties.

Complete Support Logic

// DOEnvironmentManager.m (lines 443-563) - simplified structure
- (NSString *)versionSupportString
{
    if ([self isArm64e]) {
        // A12/A13 with PPL-only path
        if ([self isA12A13Family]) {
            return @"iOS 15.0 - 18.7.1, iOS 26.0 - 26.0.1";
        }
        // ARM64e without SPTM
        else if (![self isSPTM]) {
            return @"iOS 15.0 - 17.3.1 (PPL)";
        }
        // ARM64e with SPTM
        else {
            return @"iOS 17.0 - 17.3.1 (SPTM)";
        }
    }
    // Plain ARM64
    return @"iOS 15.0 - 18.7.1";
}

View source: DOEnvironmentManager.m#L443-L563

ARM64e Support Summary

Configuration iOS Range Exploit Path
A12/A13 (Vortex/Tempest or Lightning/Thunder) 15.0 – 18.7.1, 26.0 – 26.0.1 PPL-only
ARM64e without SPTM 15.0 – 17.3.1 PPL (traditional)
ARM64e with SPTM 17.0 – 17.3.1 SPTM-based
Plain ARM64 15.0 – 18.7.1 No PAC requirements

PAC Bypass: Mandatory for ARM64e Exploitation

Pointer Authentication (PAC) on ARM64e devices cryptographically signs pointers and authenticates them on use. Dopamine cannot execute arbitrary kernel code without first defeating this protection.

PAC Bypass Enforcement in DOJailbreaker.m

The jailbreak manager explicitly validates PAC bypass availability before proceeding:

// DOJailbreaker.m (lines 183-184)
if (!pacBypassLoaded) {
    return [NSError errorWithDomain:DOJailbreakerErrorDomain
                               code:DOErrorPACBypassMissing
                           userInfo:@{NSLocalizedDescriptionKey: 
                                      @"PAC bypass is required but we did not find any"}];
}

View source: DOJailbreaker.m#L183-L184

Bypass Loading and Initialization

After locating a PAC bypass library, Dopamine loads and initializes it:

// DOJailbreaker.m (lines 204-206)
void *handle = dlopen(pacBypassPath, RTLD_NOW);
if (!handle) {
    return [NSError errorWithDomain:DOJailbreakerErrorDomain
                               code:DOErrorPACBypassLoadFailed
                           userInfo:@{NSLocalizedDescriptionKey: 
                                      [NSString stringWithFormat:@"Failed to load PAC bypass: %s", dlerror()]}];
}

View source: DOJailbreaker.m#L204-L206

Low-Level PAC Primitives

The libjailbreak component defines PAC-related constants used throughout the exploit chain:

// primitives.h
#define PAC_MASK 0xFFFFFFFFFFFF
#define PAC_STRIP(ptr) ((void *)((uintptr_t)(ptr) & PAC_MASK))
#define SIGN(ptr, ctx) sign_pointer(ptr, ctx)

View source: primitives.h

The usesPACBypass flag in libjailbreak propagates state to dependent operations:

// info.h / info.c
bool usesPACBypass;
void setUsesPACBypass(bool enabled);
bool getUsesPACBypass(void);

View source: info.h

Practical Implementation: Checking Device Readiness

Developers and advanced users can programmatically verify ARM64e status and PAC bypass requirements:

#import "DOEnvironmentManager.h"

- (void)checkJailbreakReadiness
{
    DOEnvironmentManager *env = [DOEnvironmentManager sharedManager];
    
    // Step 1: Determine architecture
    BOOL isArm64e = [env isArm64e];
    NSLog(@"Architecture: %@", isArm64e ? @"ARM64e" : @"ARM64");
    
    // Step 2: Get compatible iOS range
    NSString *supportString = [env versionSupportString];
    NSLog(@"Supported versions: %@", supportString);
    
    // Step 3: Verify PAC bypass (ARM64e only)
    if (isArm64e) {
        BOOL hasBypass = [[NSFileManager defaultManager] 
                          fileExistsAtPath:@"/usr/lib/pac_bypass.dylib"];
        NSLog(@"PAC bypass available: %@", hasBypass ? @"YES" : @"NO");
    }
}

UI Integration: Presenting PAC Options to Users

The settings controller exposes PAC bypass selection when required:

// DOSettingsController.m
- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == PACBypassSection) {
        DOEnvironmentManager *env = [DOEnvironmentManager sharedManager];
        if (![env isArm64e]) {
            // Hide PAC options for ARM64 devices
            return [self disabledCellWithText:@"Not required for this device"];
        }
        return [self pacBypassSelectionCell];
    }
    // ...
}

View source: DOSettingsController.m

Summary

  • ARM64e detection occurs via hw.cpusubtype sysctl in -isArm64e (DOEnvironmentManager.m)
  • Version support branches on CPU family (A12/A13 vs. newer) and SPTM presence in -versionSupportString
  • A12/A13 devices receive the broadest support (15.0–18.7.1, 26.0–26.0.1) through PPL-only exploitation
  • Newer ARM64e devices without SPTM support 15.0–17.3.1; with SPTM, 17.0–17.3.1
  • PAC bypass is mandatory for all ARM64e operations; DOJailbreaker.m aborts with error if unavailable
  • Low-level primitives in libjailbreak provide PAC stripping and signing utilities

Frequently Asked Questions

What happens if an ARM64e device lacks a PAC bypass?

Dopamine aborts the jailbreak sequence with the error "PAC bypass is required but we did not find any" returned from -[DOJailbreaker runExploitWithError:] at line 183–184 of DOJailbreaker.m. The exploit loading halts before any kernel memory access occurs.

Why do A12/A13 devices have different support than A14+ ARM64e devices?

A12/A13 use the PPL (Page Protection Layer) exploit path exclusively, which supports iOS 15 through 18 and the iOS 26 betas. Later ARM64e devices introduced SPTM (Secure Process Token Manager) hardware requiring different exploit primitives, restricting support to iOS 17.0–17.3.1 when SPTM is present or 15.0–17.3.1 when operating in legacy PPL mode.

Can plain ARM64 devices use PAC bypass libraries?

No. PAC bypasses are specifically designed for ARM64e pointer authentication mechanisms. Plain ARM64 devices (A9–A11) lack PAC hardware and thus skip PAC-related checks entirely in Dopamine's codebase, as confirmed by the -isArm64e conditional wrapping all PAC-dependent operations.

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 →