Skip to content

Commit 572f4ac

Browse files
committed
fix(resetprop): 修复属性伪装会话在前后台切换时的状态同步问题
- 调整 companion watcher 逻辑,应用进入后台超过 2 秒后恢复原始属性,回到前台时重新应用伪装属性 - 将属性写入、删除和恢复流程抽取为批量操作,统一普通属性与 delete_props 的处理方式 - 缩短 watcher 轮询间隔并补充日志输出,进程退出时仅在伪装仍生效时执行最终恢复
1 parent c2b3356 commit 572f4ac

1 file changed

Lines changed: 76 additions & 17 deletions

File tree

src/companion.rs

Lines changed: 76 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ use std::{
44
io::{Read, Write},
55
os::unix::net::UnixStream,
66
thread,
7-
time::Duration,
7+
time::{Duration, Instant},
88
};
99

10-
use log::{error, warn};
10+
use log::{error, info, warn};
1111
use serde::{Deserialize, Serialize};
1212
use zygisk_api::api::{V4, ZygiskApi};
1313

@@ -213,7 +213,13 @@ fn apply_resetprop_session(
213213
resetprop_delete(&resetprop_path, key)?;
214214
}
215215

216-
spawn_restore_watcher(request.pid, backups, resetprop_path)?;
216+
spawn_restore_watcher(
217+
request.pid,
218+
request.props,
219+
request.delete_props,
220+
backups,
221+
resetprop_path,
222+
)?;
217223

218224
Ok(backups_for_response)
219225
}
@@ -269,6 +275,8 @@ fn resetprop_delete(path: &str, key: &str) -> anyhow::Result<()> {
269275

270276
fn spawn_restore_watcher(
271277
pid: u32,
278+
props: HashMap<String, String>,
279+
delete_props: Vec<String>,
272280
backups: Vec<PropBackup>,
273281
resetprop_path: String,
274282
) -> anyhow::Result<()> {
@@ -279,16 +287,14 @@ fn spawn_restore_watcher(
279287
if libc::setsid() == -1 {
280288
libc::_exit(1);
281289
}
282-
wait_for_process_inactive(pid);
283-
for entry in backups {
284-
if let Err(e) =
285-
apply_resetprop(&resetprop_path, &entry.key, &entry.original_value)
286-
{
287-
error!(
288-
"Failed to restore property {} for pid {}: {}",
289-
entry.key, pid, e
290-
);
291-
}
290+
if let Err(e) = watch_process_state_and_sync_props(
291+
pid,
292+
&props,
293+
&delete_props,
294+
&backups,
295+
&resetprop_path,
296+
) {
297+
error!("Watcher failed for pid {}: {}", pid, e);
292298
}
293299
libc::_exit(0);
294300
}
@@ -297,19 +303,72 @@ fn spawn_restore_watcher(
297303
}
298304
}
299305

300-
fn wait_for_process_inactive(pid: u32) {
306+
fn watch_process_state_and_sync_props(
307+
pid: u32,
308+
props: &HashMap<String, String>,
309+
delete_props: &[String],
310+
backups: &[PropBackup],
311+
resetprop_path: &str,
312+
) -> anyhow::Result<()> {
313+
const POLL_INTERVAL: Duration = Duration::from_millis(200);
314+
const BACKGROUND_DEBOUNCE: Duration = Duration::from_secs(2);
315+
301316
let proc_path = format!("/proc/{pid}");
317+
let mut is_spoof_applied = true;
318+
let mut background_since: Option<Instant> = None;
319+
302320
loop {
303321
if !std::path::Path::new(&proc_path).exists() {
322+
if is_spoof_applied {
323+
restore_props_batch(resetprop_path, backups)?;
324+
}
304325
break;
305326
}
306327

307-
if !is_process_in_top_app(pid) {
308-
break;
328+
if is_process_in_top_app(pid) {
329+
background_since = None;
330+
if !is_spoof_applied {
331+
apply_props_batch(resetprop_path, props, delete_props)?;
332+
is_spoof_applied = true;
333+
info!("restore watcher re-applied spoof props for pid {}", pid);
334+
}
335+
} else {
336+
let bg_start = background_since.get_or_insert_with(Instant::now);
337+
if is_spoof_applied && bg_start.elapsed() >= BACKGROUND_DEBOUNCE {
338+
restore_props_batch(resetprop_path, backups)?;
339+
is_spoof_applied = false;
340+
info!("restore watcher restored props for pid {}", pid);
341+
}
309342
}
310343

311-
thread::sleep(Duration::from_millis(500));
344+
thread::sleep(POLL_INTERVAL);
312345
}
346+
347+
Ok(())
348+
}
349+
350+
fn apply_props_batch(
351+
resetprop_path: &str,
352+
props: &HashMap<String, String>,
353+
delete_props: &[String],
354+
) -> anyhow::Result<()> {
355+
for (key, value) in props {
356+
apply_resetprop(resetprop_path, key, value)?;
357+
}
358+
359+
for key in delete_props {
360+
resetprop_delete(resetprop_path, key)?;
361+
}
362+
363+
Ok(())
364+
}
365+
366+
fn restore_props_batch(resetprop_path: &str, backups: &[PropBackup]) -> anyhow::Result<()> {
367+
for entry in backups {
368+
apply_resetprop(resetprop_path, &entry.key, &entry.original_value)?;
369+
}
370+
371+
Ok(())
313372
}
314373

315374
fn is_process_in_top_app(pid: u32) -> bool {

0 commit comments

Comments
 (0)