# How Dopamine Integrates the Fugu14 Exploit for Kernel Call (kcall) Functionality

> Discover how Dopamine integrates the Fugu14 exploit for kernel call functionality. Learn how it creates kernel threads to execute arbitrary kernel functions from user space.

- Repository: [Lars Fröder/Dopamine](https://github.com/opa334/Dopamine)
- Tags: internals
- Published: 2026-08-12

---

**Dopamine uses a Fugu14-style kernel-call primitive implemented in `libjailbreak` that creates a dedicated kernel thread and maps kernel stack memory to execute arbitrary kernel functions from user space.**

The Dopamine jailbreak tool provides **kernel call (kcall)** capabilities through a Fugu14-derived exploit primitive. This architecture, found in the `opa334/Dopamine` repository, allows user-space code to safely invoke kernel functions by leveraging a specially crafted thread state. Although the original Fugu14 code evolved from earlier FuguI4 implementations, the core integration pattern and primitive registration mechanism remain consistent across versions.

## How Fugu14 kcall Initialization Works

Dopamine loads the Fugu14 kcall primitive during startup through a coordinated sequence across multiple source files.

### Loading the Primitive at Startup

In [`BaseBin/libjailbreak/src/main.c`](https://github.com/opa334/Dopamine/blob/main/BaseBin/libjailbreak/src/main.c), the initialization code includes the Fugu14 kcall headers and triggers primitive setup:

```c
#include "kcall_Fugu14.h"
#include "kcall_arm64.h"

// During libjailbreak initialization
jbclient_get_fugu14_kcall();  // Internally calls fugu14_kcall_init()

```

The `fugu14_kcall_init()` function performs two critical operations:

- Creates a **dedicated kernel-call thread** in the kernel
- Maps a **kernel stack** for that thread to use during execution

These steps establish the foundation for safe kernel function invocation without corrupting the calling process's kernel state.

### Registering with the Global Primitive Interface

Once initialized, `fugu14_kcall_init()` registers the primitive by setting the global function pointer in [`BaseBin/libjailbreak/src/kcall_Fugu14.c`](https://github.com/opa334/Dopamine/blob/main/BaseBin/libjailbreak/src/kcall_Fugu14.c):

```c
gPrimitives.kcall = fugu14_kcall;

```

This registration makes the Fugu14 implementation visible to all Dopamine components through the generic `kcall` abstraction defined in [`BaseBin/libjailbreak/src/primitives.c`](https://github.com/opa334/Dopamine/blob/main/BaseBin/libjailbreak/src/primitives.c).

## The KRW Provider Wrapper Architecture

Dopamine separates the low-level exploit primitive from higher-level code through a **generic KRW (Kernel Read-Write) provider interface**.

### kcall_wrapper: The Unified Entry Point

The [`Packages/libkrw-provider/src/main.c`](https://github.com/opa334/Dopamine/blob/main/Packages/libkrw-provider/src/main.c) file implements `kcall_wrapper()`, which validates availability and forwards calls:

```c
int kcall_wrapper(uint64_t *result, uint64_t func, int argc, const uint64_t *argv)
{
    if (!is_kcall_available()) {
        return -1;  // Primitive not initialized
    }
    return gPrimitives.kcall(result, func, argc, argv);
}

```

This wrapper ensures that:
- All kcall requests validate primitive availability first
- The underlying exploit implementation can be swapped without changing caller code
- Error handling is centralized and consistent

### Availability Checking

The `is_kcall_available()` function in [`BaseBin/libjailbreak/src/primitives.c`](https://github.com/opa334/Dopamine/blob/main/BaseBin/libjailbreak/src/primitives.c) performs a simple NULL check:

```c
bool is_kcall_available(void)
{
    return gPrimitives.kcall != NULL;
}

```

If Fugu14 initialization failed, this returns `false` and all kcall attempts return an error code rather than crashing.

## Executing Kernel Calls with Fugu14

The core `fugu14_kcall()` function in [`BaseBin/libjailbreak/src/kcall_Fugu14.c`](https://github.com/opa334/Dopamine/blob/main/BaseBin/libjailbreak/src/kcall_Fugu14.c) handles the actual kernel execution through careful thread state manipulation.

### Thread State Construction

When invoked, `fugu14_kcall()` builds a custom **ARM64 thread state** that:

1. Sets the program counter to the target kernel function address
2. Configures registers `x0`–`x7` with up to 8 arguments
3. Installs a safe return gadget using `kgadget(str_x8_x0)` — the "str x8, [x0] ; ret" sequence

### Safe Return Mechanism

The gadget at `kgadget(str_x8_x0)` provides controlled exit from kernel execution:

- **Stores** the return value (in `x8`) to a user-controlled address
- **Returns** to a precomputed safe location, avoiding kernel panic

The prepared thread state is written into the signed kernel thread via `kwritebuf()`, then the thread is resumed. Execution transfers to the kernel function, which runs to completion and returns through the gadget.

## Practical Usage Examples

### Standard kcall from User Code

Most Dopamine components use the public `kcall()` interface:

```objc
// Objective-C bridge to kernel runtime
uint64_t result;
uint64_t targetAddress = 0xFFFFFFF0075B0000;  // Kernel symbol address

int ret = kcall(&result, targetAddress, 0, NULL);
if (ret == 0) {
    NSLog(@"kcall succeeded – value = 0x%llx", result);
} else {
    NSLog(@"kcall unavailable or failed: %d", ret);
}

```

This call chains through `kcall_wrapper()` → `gPrimitives.kcall` → `fugu14_kcall()`.

### Direct Primitive Access (Advanced)

For specialized scenarios, the raw Fugu14 primitive is exposed:

```c
// Direct primitive invocation (bypasses availability checks)
extern int fugu14_kcall(uint64_t func, int argc, const uint64_t *argv);

uint64_t args[2] = { 0x1, 0x2 };
uint64_t kret = fugu14_kcall(0xFFFFFFF0074C3C80, 2, args);

```

Direct use is discouraged unless the caller implements its own safety validation.

## Key Source Files and Their Roles

| File | Purpose |
|------|---------|
| [`BaseBin/libjailbreak/src/kcall_Fugu14.h`](https://github.com/opa334/Dopamine/blob/main/BaseBin/libjailbreak/src/kcall_Fugu14.h) | API declarations: `fugu14_kcall_init()`, `jbclient_get_fugu14_kcall()` |
| [`BaseBin/libjailbreak/src/kcall_Fugu14.c`](https://github.com/opa334/Dopamine/blob/main/BaseBin/libjailbreak/src/kcall_Fugu14.c) | Core implementation: thread creation, state preparation, `fugu14_kcall()` execution |
| [`BaseBin/libjailbreak/src/main.c`](https://github.com/opa334/Dopamine/blob/main/BaseBin/libjailbreak/src/main.c) | Startup initialization that triggers Fugu14 kcall setup |
| [`Packages/libkrw-provider/src/main.c`](https://github.com/opa334/Dopamine/blob/main/Packages/libkrw-provider/src/main.c) | Generic `kcall_wrapper()` that dispatches to registered primitives |
| [`BaseBin/libjailbreak/src/primitives.c`](https://github.com/opa334/Dopamine/blob/main/BaseBin/libjailbreak/src/primitives.c) | Global primitive registry and `is_kcall_available()` check |

## Summary

- **Dopamine integrates Fugu14 as a pluggable kcall primitive** through `libjailbreak`, not as a standalone exploit
- **Initialization creates a dedicated kernel thread and stack** via `fugu14_kcall_init()` during startup
- **Registration through `gPrimitives.kcall`** decouples the exploit implementation from higher-level code
- **The `kcall_wrapper()` interface** provides safe, checked access with uniform error handling
- **Thread state manipulation with safe return gadgets** enables reliable kernel function execution without panics

## Frequently Asked Questions

### What is kcall in the context of Dopamine?

**kcall (kernel call) is Dopamine's mechanism for executing arbitrary kernel functions from user space.** It solves the problem of needing to invoke kernel routines—such as for process credentials, memory management, or security policy—after the initial jailbreak exploit has already elevated privileges. The Fugu14-based implementation provides this through a persistent kernel thread rather than temporary exploit primitives.

### Why does Dopamine use Fugu14 specifically for kcall instead of other exploits?

**Fugu14 provides a particularly clean primitive for controlled kernel thread execution.** The exploit's original design for iOS 14.5–14.8 included reliable thread state manipulation that translates well to persistent kcall needs. Dopamine adapted this pattern because it offers predictable register control, safe return paths through gadgets, and minimal kernel surface area—making it more stable than approaches that repeatedly trigger new vulnerabilities.

### Can kcall fail or become unavailable after Dopamine starts?

**Yes, kcall availability depends on successful initialization at startup.** If `fugu14_kcall_init()` fails—due to kernel structure offsets, memory allocation failures, or security mitigations—the `gPrimitives.kcall` pointer remains NULL. Subsequent calls to `is_kcall_available()` return `false`, and `kcall_wrapper()` returns `-1` without attempting kernel access. This graceful degradation prevents crashes but may limit jailbreak functionality depending on which operations require kernel calls.

### How does the kcall return value get back to user space?

**The return value travels through a deliberately chosen kernel gadget.** The `kgadget(str_x8_x0)` sequence—"store x8 to [x0], then return"—allows the kcall implementation to designate a user-mapped address where the kernel function's return value (placed in `x8` by the ARM64 calling convention) is written. The `kwritebuf()` operation sets up this destination address in the thread state before execution, ensuring the value is safely extractable after the kernel thread suspends.