## https://sploitus.com/exploit?id=2C4626EC-5D29-5719-A889-0A6859D3A7F6
# unplus
CVE-2026-43499 (Futex PI UAF): The core logic code for writing arbitrary data to the kernel address, used to bypass SELinux and gain root access. This repository only contains the core exploit logic source code (`src/`) and the single binary packer (`wrapper/`). `src/target.h` is a **template**; you need to fill in the parameters of your own device to run it (see below βDevice Adaptationβ).
## Building
### Core Logic (`src/`)
```bash
# Environment requirements: Android NDK r29+ (API 35, aarch64)
export ANDROID_NDK_ROOT=/path/to/android-ndk
# Build the pure logic product
make
# β build/unplus (exploit binary)
# β build/unplus_preload.so (preload library)
```
The output are two ELF files, without any external binaries embedded within them.
### Complete Single Binary Packing (`wrapper/`)
To package the exploit and external loads (magiskpolicy / ksud / kernelsu.ko) into a single, ready-to-run binary, you need to prepare these external loads and then use `wrapper/` to package them:
```bash
# 1. First, build the `src/` output (see above).
# 2. Generate the payload data (payload_data.h is not in the repository; users should generate it themselves, containing the external binary stream).
cd wrapper
python3 embed_payloads.py \
--unplus ../build/unplus \
--preload ../build/unplus_preload.so \
--magiskpolicy \
--ksud \
--kernelsu \
--out payload/
# 3. Compile the single binary
make # β wrapper/build/unplus
```
## Source Code Structure
```
src/
βββ target.h Device parameter template (β FILL IN marked sections require your device values)
βββ offset.h Routing glue for target.h (injected via -DTARGET_CONFIG_H)
βββ unplus.h Orchestration header + shared declarations (including P0 alias / data_addr and derived macros)
βββ main.c Entry orchestration
βββ stage1.c Write 1/2: SELinux disabling + cred overwriting
βββ root.c Android root implementation (SELinux golden fix + sepolicy + KSU allowlist)
βββ slide.c KASLR leak
βββ fops.c Configfs/fops routing + kernel base address derivation
βββ route.c PI futex routing thread
βββ direct_write.c Direct read primitive
βββ pipe_direct.c Direct pselect write
βββ pipe_physrw.c Pipe physrw primitive
βββ util.c Utility functions
βββ utils.h General utilities (logging, procfs paths)
βββ kernelsnitch.h Architecture layer (ARM64/x86 identity map)
βββ futex_hash.h Kernel jhash migration (general)
βββ timeutils.h Architecture layer timing (ARM/x86/AMD)
```
## Device Adaptation
`src/target.h` has two types of constants:
- **β FILL IN marked sections**: These are device/kernel-related sections; you must fill in your own values. The template uses `0xDEADBEEF...` as placeholders, which can be compiled but will fail when run.
- **Unmarked sections**: GKI 6.6 invariants (struct field offsets); usually do not need to be changed. Changing devices requires filling in the `β FILL IN` sections. See below β[Appendix: Field Descriptions](#Appendix:FieldDescriptions)β for details on each field and how to obtain them.
In `target.h`, the `β FILL IN` fields are grouped by purpose:
| Group | Field (Example) | Meaning / How to Obtain |
|-------|-------------------|--------------------------|
|------|------------|----------------|
| **Build identity** | `BUILD_VARIANT_LABEL`, `BUILD_FINGERPRINT` | Any identifier string used for logs. Fill in the build fingerprint of your device. |
| **Memory layout** | `KIMAGE_TEXT_BASE`, `P0_PHYS_OFFSET`, `VMEMMAP_START`, etc. | Kernel virtual/physical address layout. `arm64 VA39` is usually set to the default value; confirm from `IKCONFIG`, `kallsyms`, `/proc/iomem`. |
| **ASHMEM** | `ASHMEM_IOCTL_OFF`β¦ `ASHMEM_MISC_FOPS_OFF` | Members of the ashmem driverβs fops functions and misc symbol offsets. Use `kallsyms_lookup_name("ashmem_fops")` etc. |
| **CONFIGFS / PIPE / VFS** | `CONFIGFS_READ_ITER_OFF`, `ANON_PIPE_BUF_OPS_OFF`, `KMALLOC_CACHES_OFF`, etc. | Configfs read/write, splice, pipe_buf_ops, kmalloc_caches offsets. Check with `kallsyms`. |
| **SELinux** | `SELINUX_ENFORCING_OFF`, `SELINUX_BLOB_SIZES_OFF`, `SECURITY_HOOK_HEADS_OFF` | Offsets for `selinux_state`, `selinux_blob_sizes`, `security_hook_heads`. **`SELINUX_ENFORCING_OFF` is a kernel build-matching anchor point** and must be precise. |
| **Core kernel symbols** | `INIT_TASK_OFF`, `INIT_CRED_OFF`, `ENTRY_TASK_PERCPU_OFF`, etc. | Offsets for `init_task`, `init_cred`, `entry_task`, `__per_cpu_offset`, `root_task_group`. Check with `kallsyms`; `ENTRY_TASK_PERCPU_OFF` is the offset of `__entry_task` within the percpu section. |
| **Per-CPU runtime** | `TARGET_PCPU_BASE_ADDR`, `TARGET_PCPU_UNIT_SIZE` | **Runtime address** of per-CPU chunks (after KASLR), changes with each boot. Requires runtime dumping; `UNIT_SIZE` depends on the number of CPUs. |
| **SLIDE (KASLR leak)** | `SLIDE_NFULNL_LOGGER_OFF`, `SLIDE_RANDOM_BOOT_ID_DATA_OFF`, etc. | Kernel data symbols for KASLR leaks (e.g., nfulnl_logger, boot_id_data). Check with `kallsyms`. |
| **SELinux golden** | `TARGET_SELINUX_GOLDEN` | The first 16 bytes of `selinux_state` as a boolean template. Stable across restarts but varies per device. Need to obtain `selinux_state` from your device. `byte0` indicates the enforcing bit; setting it to 0x00 means permissive. |
| **Pipe inode info** | `PIPE_INODE_INFO_*`γ`PIPE_HEAD_OFF`, etc. | Structure layout of `pipeinode_info`; usually stable within the GKI family. Must be verified when switching between kernel builds. |
**General notes**: All `*_OFF` type offsets can be obtained by using `kallsyms_lookup_name` on the root device, then subtracting `KIMAGE_TEXT_BASE`. `TARGET_PCPU_*` and `TARGET_SELINUX_GOLDEN` are runtime/dump values and cannot be obtained from static images. ## License
[WTFPL](LICENSE) β Do What The Fuck You Want To Public License. ## Acknowledgments
- CyberMeowfia team β pipe physrw privilege framework
- Community device adaptation references