Skip to content

Enginex0/resetprop-rs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

18 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ”§ resetprop-rs

Pure Rust Android Property Manipulation

Get. Set. Delete. Hexpatch. No Magisk required.

v0.2.0 Android 10+ Rust Telegram


Note

resetprop-rs is a standalone reimplementation of Magisk's resetprop in pure Rust. It does not depend on Magisk, forked bionic, or any custom Android symbols. Works with any root solution β€” KSU, Magisk, APatch, or bare su.


🧬 What is resetprop-rs?

Android system properties live in mmap'd shared memory at /dev/__properties__/. Each file is a 128KB arena containing a prefix trie with BST siblings β€” the same data structure since Android 10.

Magisk's resetprop can manipulate these, but it's locked into Magisk's build system β€” it depends on a forked bionic with custom symbols (__system_property_find2, __system_property_delete, etc.) that don't exist in stock Android. You can't extract it as a standalone binary.

resetprop-rs reimplements the entire property area format in pure Rust. No bionic symbols. No Magisk dependency. Ships as a ~320KB static binary and an embeddable library crate.

It also introduces --hexpatch-delete β€” a stealth operation that no existing tool provides.


πŸ”₯ Why resetprop-rs?

πŸ”“ Truly Standalone β€” Zero runtime dependencies. No Magisk, no forked libc, no JNI. A single static binary that works on any rooted Android device.

πŸ₯· Hexpatch Delete β€” Instead of detaching trie nodes (detectable by enumeration gaps), overwrites property name bytes with realistic dictionary words. Trie structure stays intact. Serial counters preserved. Invisible to __system_property_foreach.

πŸ“¦ Embeddable Library β€” resetprop crate with typed errors, no anyhow. Drop it into your Rust project and manipulate properties programmatically.

⚑ Tiny Footprint β€” ~320KB ARM64, ~240KB ARMv7. Hand-rolled CLI parser, panic=abort, LTO, single codegen unit. Only dependency: libc.

πŸ§ͺ Tested Off-Device β€” 29 unit tests against synthetic property areas. Verified: get, set, overwrite, delete, hexpatch, trie integrity, serial preservation, name consistency, boundary conditions.


✨ Features

Property Operations

  • Get β€” single property or list all
  • Set β€” direct mmap write, bypasses property_service
  • Delete β€” trie node detach + value/name wipe
  • Hexpatch Delete β€” dictionary-based name destruction, serial-preserving
  • Batch Load β€” -f flag loads name=value pairs from file

Library API

  • PropArea β€” single property file: open, get, set, delete, hexpatch, foreach
  • PropSystem β€” multi-file scan across /dev/__properties__/
  • Typed errors β€” NotFound, AreaCorrupt, PermissionDenied, AreaFull, Io, ValueTooLong
  • RO fallback β€” automatically falls back to read-only when write access is denied

Format Support

  • Short values β€” ≀91 bytes, inline in prop_info
  • Long values β€” Android 12+, >92 bytes via self-relative arena offset
  • Serial protocol β€” spin-wait on dirty bit, verification loop for concurrent reads
  • Length-first comparison β€” matches AOSP's cmp_prop_name exactly

Stealth

  • Runtime harvest β€” replacement segments drawn from the device's own property vocabulary (unfingerprintable)
  • Randomized selection β€” OS-seeded entropy picks different names each run
  • 3-tier fallback β€” harvest pool β†’ static dictionary (~95 words) β†’ dot-split compound generation
  • Plausible value β€” mangled properties show value 0 instead of empty string
  • Name consistency β€” trie segments and prop_info name written from same source (no cross-validation mismatch)
  • Length-bucketed β€” replacement is always exact same byte length as original
  • Shared segment detection β€” skips renaming prefixes used by other properties
  • No serial bump β€” preserves counter bits, avoiding NativeTest detection

πŸ“‹ Requirements

Important

Write operations (set, delete, hexpatch) require root access with appropriate SELinux context. Read operations (get, list) work for any user since property files are world-readable.

You need:

  1. Android 10 or above
  2. Root access (KernelSU, Magisk, APatch, or equivalent)
  3. ARM64 or ARMv7 device

πŸš€ Quick Start

  1. Download the latest binary from Releases
  2. Push to device β€” adb push resetprop-arm64-v8a /data/local/tmp/resetprop
  3. Set executable β€” adb shell chmod +x /data/local/tmp/resetprop
  4. Run with root β€” adb shell su -c /data/local/tmp/resetprop
# List all properties
resetprop

# Get a single property
resetprop ro.build.type

# Set a property (direct mmap, no init notification)
resetprop -n ro.build.type user

# Delete a property
resetprop -d ro.debuggable

# Stealth delete β€” name bytes replaced with dictionary words
resetprop --hexpatch-delete ro.lineage.version

# Batch set from file
resetprop -f props.txt

πŸ“š Library Usage

Add to your Cargo.toml:

[dependencies]
resetprop = { git = "https://github.com/Enginex0/resetprop-rs" }
use resetprop::PropSystem;

let sys = PropSystem::open()?;

if let Some(val) = sys.get("ro.build.type") {
    println!("{val}");
}

sys.set("ro.build.type", "user")?;
sys.delete("ro.debuggable")?;
sys.hexpatch_delete("ro.lineage.version")?;

for (name, value) in sys.list() {
    println!("[{name}]: [{value}]");
}

πŸ—οΈ Building

Requires Android NDK for cross-compilation:

export ANDROID_NDK_HOME=/path/to/ndk
./build.sh

Outputs stripped binaries to out/:

ABI Binary Size
arm64-v8a resetprop-arm64-v8a ~320KB
armeabi-v7a resetprop-armeabi-v7a ~240KB

The build uses opt-level=s, LTO, panic=abort, strip, and single codegen unit for minimal binary size.

No NDK? Fork the repo and go to Actions β†’ Build β†’ Run workflow β€” GitHub builds both binaries for you. Download them from the workflow artifacts.


🧠 How It Works

Property Area Format

Each file in /dev/__properties__/ is a 128KB mmap'd arena:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Header (128 bytes)                  β”‚
β”‚   [0x00] bytes_used: u32            β”‚
β”‚   [0x04] serial: AtomicU32          β”‚
β”‚   [0x08] magic: 0x504f5250 "PROP"   β”‚
β”‚   [0x0C] version: 0xfc6ed0ab        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Arena (bump-allocated, append-only) β”‚
β”‚   β”Œβ”€ prop_trie_node ──────────┐    β”‚
β”‚   β”‚ namelen(4) prop(4) left(4)β”‚    β”‚
β”‚   β”‚ right(4) children(4)      β”‚    β”‚
β”‚   β”‚ name[namelen+1] (aligned) β”‚    β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚   β”Œβ”€ prop_info ───────────────┐    β”‚
β”‚   β”‚ serial(4) value[92]       β”‚    β”‚
β”‚   β”‚ name[] (full dotted name) β”‚    β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Property names split on dots into a prefix trie. Each trie level uses a BST for siblings, compared length-first then lexicographically (not standard strcmp).

Hexpatch Delete

Standard delete detaches the trie node β€” but apps enumerating properties can detect the gap. Hexpatch delete takes a different approach:

Before: ro.lineage.version = "18.1"
After:  ro.codec.charger = "0"
  1. Harvest all property segments from the device into a length-bucketed pool
  2. Walk the trie path, collecting each segment's node offset
  3. For each non-shared segment, pick a same-length replacement (harvest β†’ dict β†’ dot-split compound)
  4. Overwrite name bytes in-place, randomized selection each run
  5. Write mangled name to prop_info from the same chosen segments (single source of truth)
  6. Set value to 0 with correct serial encoding β€” indistinguishable from a boot-time property
  7. Do not bump the serial counter β€” avoids NativeTest serial-monitoring detection

πŸ“± Compatibility

Status
Android 10 – 15
Architecture ARM64, ARMv7
Value format Short (≀91B) + Long (Android 12+, >92B)
Root KernelSU, Magisk, APatch, any su

πŸ’¬ Community

Telegram


πŸ™ Credits

Contributors


πŸ“„ License

This project is licensed under the MIT License.


πŸ”§ Because the best property manipulation is the one init never noticed.

About

Pure Rust implementation of Android resetprop with hexpatch-delete capability

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors