From 3ccd7c0b19d636f7d3226996733867be478a7b08 Mon Sep 17 00:00:00 2001 From: renoseven Date: Fri, 25 Jul 2025 20:11:02 +0800 Subject: [PATCH] syscared: fix active & deactive process list calculation error Signed-off-by: renoseven --- syscared/src/patch/driver/upatch/mod.rs | 39 +++++++++------ syscared/src/patch/driver/upatch/target.rs | 57 +++++++++++++++------- 2 files changed, 64 insertions(+), 32 deletions(-) diff --git a/syscared/src/patch/driver/upatch/mod.rs b/syscared/src/patch/driver/upatch/mod.rs index cc00f531..58f01df9 100644 --- a/syscared/src/patch/driver/upatch/mod.rs +++ b/syscared/src/patch/driver/upatch/mod.rs @@ -23,7 +23,7 @@ use std::{ }; use anyhow::{bail, ensure, Result}; -use log::{debug, warn}; +use log::{debug, info, warn}; use parking_lot::RwLock; use uuid::Uuid; @@ -207,12 +207,11 @@ impl UserPatchDriver { patch_target.clean_dead_process(&process_list); let all_patches = patch_target.all_patches().collect::>(); - let need_actived = patch_target.need_actived(&process_list); - for (uuid, patch_file) in all_patches { + let need_actived = patch_target.need_actived_process(&process_list, &uuid); if !need_actived.is_empty() { - debug!( - "Upatch: Activating patch '{}' ({}) for process {:?}", + info!( + "Upatch: Activating patch '{}' ({}) on new process {:?}", uuid, target_elf.display(), need_actived, @@ -220,10 +219,10 @@ impl UserPatchDriver { } for &pid in &need_actived { match sys::active_patch(&uuid, pid, target_elf, &patch_file) { - Ok(_) => patch_target.add_process(pid), + Ok(_) => patch_target.process_register_patch(pid, &uuid), Err(e) => { warn!( - "Upatch: Failed to active patch '{}' for process {}, {}", + "Upatch: Failed to active patch '{}' on process {}, {}", uuid, pid, e.to_string().to_lowercase(), @@ -266,7 +265,13 @@ impl UserPatchDriver { let start_watch = !patch_target.is_patched(); // Active patch - let need_actived = patch_target.need_actived(&process_list); + let need_actived = patch_target.need_actived_process(&process_list, &patch.uuid); + info!( + "Upatch: Activating patch '{}' ({}) on process {:?}", + patch.uuid, + patch.target_elf.display(), + need_actived, + ); let mut results = Vec::new(); for pid in need_actived { @@ -290,10 +295,10 @@ impl UserPatchDriver { // Process results for (pid, result) in results { match result { - Ok(_) => patch_target.add_process(pid), + Ok(_) => patch_target.process_register_patch(pid, &patch.uuid), Err(e) => { warn!( - "Upatch: Failed to active patch '{}' for process {}, {}", + "Upatch: Failed to active patch '{}' on process {}, {}", patch.uuid, pid, e.to_string().to_lowercase(), @@ -322,10 +327,16 @@ impl UserPatchDriver { patch_target.clean_dead_process(&process_list); // Deactive patch - let need_deactive = patch_target.need_deactived(&process_list); + let need_deactived = patch_target.need_deactived_process(&process_list, &patch.uuid); + info!( + "Upatch: Deactivating patch '{}' ({}) on process {:?}", + patch.uuid, + patch.target_elf.display(), + need_deactived, + ); let mut results = Vec::new(); - for pid in need_deactive { + for pid in need_deactived { let result = sys::deactive_patch(&patch.uuid, pid, &patch.target_elf, &patch.patch_file); results.push((pid, result)); @@ -347,10 +358,10 @@ impl UserPatchDriver { // Process results for (pid, result) in results { match result { - Ok(_) => patch_target.remove_process(pid), + Ok(_) => patch_target.process_unregister_patch(pid, &patch.uuid), Err(e) => { warn!( - "Upatch: Failed to deactive patch '{}' for process {}, {}", + "Upatch: Failed to deactive patch '{}' on process {}, {}", patch.uuid, pid, e.to_string().to_lowercase(), diff --git a/syscared/src/patch/driver/upatch/target.rs b/syscared/src/patch/driver/upatch/target.rs index e0e9f882..a2a5f81e 100644 --- a/syscared/src/patch/driver/upatch/target.rs +++ b/syscared/src/patch/driver/upatch/target.rs @@ -24,36 +24,57 @@ use crate::patch::entity::UserPatch; #[derive(Debug, Default)] pub struct PatchTarget { - process_list: HashSet, - patch_map: HashMap, // uuid -> patch file + process_map: HashMap>, // pid -> patch list + patch_map: HashMap, // uuid -> patch file collision_map: HashMap>, // function old addr -> patch collision list } impl PatchTarget { - pub fn add_process(&mut self, pid: i32) { - self.process_list.insert(pid); + pub fn process_register_patch(&mut self, pid: i32, uuid: &Uuid) { + self.process_map.entry(pid).or_default().insert(*uuid); } - pub fn remove_process(&mut self, pid: i32) { - self.process_list.remove(&pid); + pub fn process_unregister_patch(&mut self, pid: i32, uuid: &Uuid) { + if let Some(patch_list) = self.process_map.get_mut(&pid) { + patch_list.remove(uuid); + } } - pub fn clean_dead_process(&mut self, process_list: &HashSet) { - self.process_list.retain(|pid| process_list.contains(pid)); + pub fn need_actived_process(&self, process_list: &HashSet, uuid: &Uuid) -> HashSet { + let mut need_actived = HashSet::with_capacity(process_list.len()); + + for pid in process_list { + match self.process_map.get(pid) { + Some(patch_list) => { + if !patch_list.contains(uuid) { + need_actived.insert(*pid); + } + } + None => { + need_actived.insert(*pid); + } + } + } + + need_actived } - pub fn need_actived(&self, process_list: &HashSet) -> HashSet { - process_list - .difference(&self.process_list) - .copied() - .collect() + pub fn need_deactived_process(&self, process_list: &HashSet, uuid: &Uuid) -> HashSet { + let mut need_deactived = HashSet::with_capacity(process_list.len()); + + for pid in process_list { + if let Some(patch_list) = self.process_map.get(pid) { + if patch_list.contains(uuid) { + need_deactived.insert(*pid); + } + } + } + + need_deactived } - pub fn need_deactived(&self, process_list: &HashSet) -> HashSet { - process_list - .intersection(&self.process_list) - .copied() - .collect() + pub fn clean_dead_process(&mut self, process_list: &HashSet) { + self.process_map.retain(|pid, _| process_list.contains(pid)); } } -- Gitee