
CVE-2026-43499 استغلال صلاحيات الجذر عند كل إقلاع — المنطق الأساسي (arm64 Android GKI 6.6)
الكود الأساسي لاستغلال الكتابة العشوائية في عنوان ذاكرة النواة CVE-2026-43499 (Futex PI UAF)، المستخدم لتجاوز SELinux والحصول على صلاحيات root.
يحتوي هذا المستودع فقط على الكود المصدري للمنطق الأساسي للاستغلال (
src/) وحزمة الثنائي الواحد (wrapper/).src/target.hهو قالب، يجب ملء معاملات جهازك الخاصة لتشغيله (انظر "تكييف الجهاز" أدناه).
# 环境要求: Android NDK r29+ (API 35, aarch64)
export ANDROID_NDK_ROOT=/path/to/android-ndk
# 构建纯逻辑产物
make
# → build/unplus (exploit 二进制)
# → build/unplus_preload.so (preload 库)
الناتج عبارة عن ملفي ELF، لا يتضمنان أي ثنائيات خارجية.
لتغليف الاستغلال مع الحمولات الخارجية (magiskpolicy / ksud / kernelsu.ko) في ثنائي واحد يعمل بضغطة واحدة، يجب توفير هذه الحمولات الخارجية بنفسك ثم استخدام wrapper/ للتغليف:
# 1. 先构建 src/ 产物(见上)
# 2. 生成 payload 数据(payload_data.h 不在仓库,由用户自生成,含外部二进制字节流)
cd wrapper
python3 embed_payloads.py \
--unplus ../build/unplus \
--preload ../build/unplus_preload.so \
--magiskpolicy <path> \
--ksud <path> \
--kernelsu <path> \
--out payload/
# 3. 编译单二进制
make # → wrapper/build/unplus
src/
├── target.h 设备参数模板(◆ FILL IN 标记处需填你的设备值)
├── offset.h target.h 的路由胶水(经 -DTARGET_CONFIG_H 注入)
├── unplus.h 编排头 + 共享声明(含 P0 alias / data_addr 等派生宏)
├── main.c 入口编排
├── stage1.c Write 1/2:SELinux 关闭 + cred 覆写
├── root.c Android root 落地(SELinux golden 修复 + sepolicy + KSU allowlist)
├── slide.c KASLR leak
├── fops.c configfs/fops 路由 + 内核基址推导
├── route.c PI futex 路由线程
├── direct_write.c direct read 原语
├── pipe_direct.c direct pselect write
├── pipe_physrw.c pipe physrw 原语
├── util.c 工具函数
├── utils.h 通用工具(日志、procfs 路径)
├── kernelsnitch.h 架构层(ARM64/x86 identity-map)
├── futex_hash.h 内核 jhash 移植(通用)
└── timeutils.h 架构层计时(ARM/x86/AMD)
يحتوي src/target.h على نوعين من الثوابت:
◆ FILL IN: خاصة بالجهاز/النواة، يجب ملء قيمك الخاصة. تستخدم القالب قيماً نائبة مثل 0xDEADBEEF...، يمكن تجميعها لكنها ستنهار عند التشغيل.تغيير الجهاز = ملء جزء ◆ FILL IN. لمعرفة ماهية كل حقل وكيفية الحصول عليه، انظر 附录:字段说明.
الحقول ذات ◆ FILL IN في target.h مقسمة حسب الغرض:
خبرة عامة: جميع الإزاحات من نوع *_OFF يمكن الحصول عليها من جهاز لديه صلاحيات root عبر kallsyms_lookup_name لجلب عنوان الرمز ثم طرح KIMAGE_TEXT_BASE. أما TARGET_PCPU_* وTARGET_SELINUX_GOLDEN فهما قيمتان وقت التشغيل/التفريغ ولا يمكن الحصول عليهما من الصورة الثابتة.
WTFPL — Do What The Fuck You Want To Public License.
| 分组 | 字段(示例) | 含义 / 获取方式 |
|---|
| Build identity | BUILD_VARIANT_LABEL、BUILD_FINGERPRINT | سلسلة تعريف عشوائية تُستخدم في السجلات. املأ build fingerprint لجهازك |
| Memory layout | KIMAGE_TEXT_BASE、P0_PHYS_OFFSET、VMEMMAP_START 等 | تخطيط العناوين الافتراضية/الفيزيائية للنواة. عادةً ما تتوفر قيم افتراضية لـ arm64 VA39؛ تحقق منها عبر IKCONFIG / kallsyms / /proc/iomem |
| ASHMEM | ASHMEM_IOCTL_OFF ... ASHMEM_MISC_FOPS_OFF | إزاحات رموز أعضاء fops المختلفة لمشغل ashmem + misc. مثل kallsyms_lookup_name("ashmem_fops") |
| CONFIGFS / PIPE / VFS | CONFIGFS_READ_ITER_OFF、ANON_PIPE_BUF_OPS_OFF、KMALLOC_CACHES_OFF 等 | إزاحات configfs للقراءة/الكتابة وsplice وpipe_buf_ops وkmalloc_caches. استعلم عنها عبر kallsyms |
| SELinux | SELINUX_ENFORCING_OFF、SELINUX_BLOB_SIZES_OFF、SECURITY_HOOK_HEADS_OFF | إزاحات selinux_state / selinux_blob_sizes / security_hook_heads. SELINUX_ENFORCING_OFF هي نقطة الارتكاز لمطابقة بناء النواة، ويجب أن تكون دقيقة |
| Core kernel symbols | INIT_TASK_OFF、INIT_CRED_OFF、ENTRY_TASK_PERCPU_OFF 等 | إزاحات init_task / init_cred / entry_task / __per_cpu_offset / root_task_group. استعلم عبر kallsyms؛ ENTRY_TASK_PERCPU_OFF هو إزاحة __entry_task داخل قسم percpu |
| Per-CPU runtime | TARGET_PCPU_BASE_ADDR、TARGET_PCPU_UNIT_SIZE | عنوان التشغيل لكتلة per-CPU (بعد KASLR)، يتغير عند كل إقلاع. يتطلب تفريغاً (dump) وقت التشغيل؛ UNIT_SIZE يعتمد على عدد وحدات المعالجة المركزية |
| SLIDE (KASLR leak) | SLIDE_NFULNL_LOGGER_OFF、SLIDE_RANDOM_BOOT_ID_DATA_OFF 等 | إزاحات رموز بيانات النواة المستخدمة لتسريب KASLR (nfulnl_logger / boot_id data وغيرها). استعلم عبر kallsyms |
| SELinux golden | TARGET_SELINUX_GOLDEN | قالب booleans للـ 16 بايت الأولى من selinux_state، ثابت عبر إعادة التشغيل لكنه يختلف لكل جهاز. يجب الحصول عليه من تفريغ selinux_state لجهازك. البايت 0 هو موضع enforcing، وتكتب الدالة المُستدعِية 0x00 لتعني permissive |
| pipe inode info | PIPE_INODE_INFO_*、PIPE_HEAD_OFF 等 | تخطيط بنية pipe_inode_info، عادةً ما يكون ثابتاً داخل عائلة GKI نفسها، لكن يجب التحقق منه عند تغيير بناء النواة |