Skip to content

Commit 50817f1

Browse files
committed
feat(props): stealth writes, nuke operations, and smart enforcement
Upgrade resetprop-rs from v0.2.0 to v0.4.0 (local path dep) to gain set_stealth (no serial bump/futex wake), nuke (count-preserving delete with arena compaction), and nuke_persist (on-disk protobuf cleanup). Spoof table now skips props that don't exist on the device to avoid creating phantom fingerprinting surface. Nuke tables added for PIF and custom ROM props that leak module/ROM identity. Persist-prefixed props route through nuke_persist so they don't survive reboot.
1 parent 54ae30b commit 50817f1

6 files changed

Lines changed: 83 additions & 15 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ thiserror = "= 2.0.18"
1616
libc = "= 0.2.180"
1717
rand = "= 0.8.5"
1818
zip = { version = "= 8.1.0", default-features = false, features = ["deflate"] }
19-
resetprop = { git = "https://github.com/Enginex0/resetprop-rs" }
19+
resetprop = { path = "external/resetprop-rs/crates/resetprop" }
2020

2121
[dev-dependencies]
2222
tempfile = "3"

src/prop/enforcer.rs

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,46 @@
11
use resetprop::PropSystem;
2-
use tracing::trace;
2+
use tracing::{debug, trace, warn};
33

4-
pub(super) fn enforce_once(sys: &PropSystem, props: &[(&str, &str)]) {
4+
pub(super) fn enforce_stealth(sys: &PropSystem, props: &[(&str, &str)]) {
5+
let (mut spoofed, mut skipped) = (0u32, 0u32);
56
for &(name, value) in props {
6-
let current = sys.get(name);
7-
if current.as_deref() != Some(value) {
8-
trace!(prop = name, from = ?current, to = value, "enforce");
9-
let _ = sys.set(name, value);
7+
match sys.get(name) {
8+
Some(current) if current != value => {
9+
trace!(prop = name, from = current, to = value, "stealth");
10+
let _ = sys.set_stealth(name, value);
11+
spoofed += 1;
12+
}
13+
Some(_) => skipped += 1,
14+
None => skipped += 1,
1015
}
1116
}
17+
debug!(spoofed, skipped, "enforce_stealth");
18+
}
19+
20+
pub(super) fn nuke_props(sys: &PropSystem, names: &[&str]) {
21+
let (mut nuked, mut absent) = (0u32, 0u32);
22+
for &name in names {
23+
if sys.get(name).is_none() {
24+
absent += 1;
25+
continue;
26+
}
27+
trace!(prop = name, "nuke");
28+
let result = if name.starts_with("persist.") {
29+
sys.nuke_persist(name)
30+
} else {
31+
sys.nuke(name)
32+
};
33+
match result {
34+
Ok(true) => nuked += 1,
35+
Ok(false) => absent += 1,
36+
Err(e) => {
37+
warn!(prop = name, err = %e, "nuke failed, falling back to hexpatch");
38+
let _ = sys.hexpatch_delete(name);
39+
nuked += 1;
40+
}
41+
}
42+
}
43+
if nuked > 0 {
44+
debug!(nuked, absent, "nuke_props");
45+
}
1246
}

src/prop/mod.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,26 @@ pub fn run_prop_watch() -> Result<()> {
3232
}
3333
};
3434

35+
enforcer::nuke_props(&sys, table::NUKE_PIF);
36+
enforcer::nuke_props(&sys, table::NUKE_CUSTOM_ROM);
37+
3538
let props: Vec<(&str, &str)> = table::GENERAL
3639
.iter()
3740
.map(|p| (p.name, p.value))
3841
.collect();
39-
enforcer::enforce_once(&sys, &props);
42+
enforcer::enforce_stealth(&sys, &props);
4043

4144
let size = config.brene.vbmeta_size.to_string();
42-
let _ = sys.set("ro.boot.vbmeta.size", &size);
45+
if sys.get("ro.boot.vbmeta.size").as_deref() != Some(&size) {
46+
let _ = sys.set_stealth("ro.boot.vbmeta.size", &size);
47+
}
4348

44-
if !config.brene.verified_boot_hash.is_empty() {
45-
let _ = sys.set("ro.boot.vbmeta.digest", &config.brene.verified_boot_hash);
49+
let hash = &config.brene.verified_boot_hash;
50+
if !hash.is_empty() && sys.get("ro.boot.vbmeta.digest").as_deref() != Some(hash.as_str()) {
51+
let _ = sys.set_stealth("ro.boot.vbmeta.digest", hash);
4652
}
4753

48-
info!("general prop spoofing applied");
54+
info!("prop spoofing applied (stealth mode)");
4955
Ok(())
5056
}
5157

src/prop/table.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,32 @@ pub(super) static GENERAL: &[PropEntry] = &[
3535
PropEntry { name: "ro.boot.warranty_bit", value: "0" },
3636
PropEntry { name: "ro.warranty_bit", value: "0" },
3737
];
38+
39+
// Props that leak PIF module presence
40+
pub(super) static NUKE_PIF: &[&str] = &[
41+
"persist.sys.pihooks.status",
42+
"persist.sys.pihooks",
43+
"ro.pihooks.enable",
44+
"persist.pihooks.mainline_update",
45+
"persist.sys.pixelprops.pi",
46+
"persist.sys.pixelprops.gms",
47+
"persist.sys.pixelprops.gphotos",
48+
"persist.sys.pixelprops.netflix",
49+
];
50+
51+
// Props that leak custom ROM identity
52+
pub(super) static NUKE_CUSTOM_ROM: &[&str] = &[
53+
"ro.lineage.build.version",
54+
"ro.lineage.build.version.plat_sdk",
55+
"ro.lineage.version",
56+
"ro.lineage.display.version",
57+
"ro.lineage.releasetype",
58+
"ro.lineageaudio.version",
59+
"ro.crdroid.build.version",
60+
"ro.crdroid.version",
61+
"ro.crdroid.display.version",
62+
"ro.modversion",
63+
"ro.romversion",
64+
"ro.rom.build.display.id",
65+
"ro.custom.build.version",
66+
];

0 commit comments

Comments
 (0)