sig.rs (3246B) - raw
1 use std::sync::Mutex; 2 3 use procfs::process::MMPermissions; 4 5 use crate::mapped_lib::MappedLib; 6 7 8 static SIGNATURE_CACHE: Mutex<Vec<(String, Vec<usize>)>> = Mutex::new(Vec::new()); 9 10 pub fn add_signatures(signatures: Vec<(String, Vec<usize>)>) { 11 SIGNATURE_CACHE.lock().unwrap().extend(signatures); 12 } 13 14 pub fn get_signatures() -> Vec<(String, Vec<usize>)> { 15 SIGNATURE_CACHE.lock().unwrap().clone() 16 } 17 18 pub fn find_signatures(module_base: usize, size: usize, pattern: &str, once: bool) -> Vec<usize> { 19 let mut results = Vec::new(); 20 let mut bytes = Vec::new(); 21 let mut mask = Vec::new(); 22 let mut i = 0; 23 24 if let Some(cache) = SIGNATURE_CACHE.lock().unwrap().iter().find(|(sig, _)| sig == pattern) { 25 return cache.1.clone().into_iter().map(|offset| module_base + offset).collect(); 26 } 27 28 while i < pattern.len() { 29 if pattern.chars().nth(i).unwrap() == '?' { 30 bytes.push(0); 31 mask.push('?'); 32 } else { 33 bytes.push(u8::from_str_radix(&pattern[i..i+2], 16).unwrap()); 34 mask.push('x'); 35 } 36 i += 3; 37 } 38 39 let mut i = 0; 40 let size = size - bytes.len(); 41 while i < size { 42 let mut found = true; 43 let mut j = 0; 44 45 while j < bytes.len() { 46 if mask[j] == '?' || bytes[j] == unsafe { *(module_base as *const u8).offset(i as isize + j as isize) } { 47 j += 1; 48 continue; 49 } 50 found = false; 51 break; 52 } 53 if found { 54 if once { 55 SIGNATURE_CACHE.lock().unwrap().push((pattern.to_string(), vec![i])); 56 return vec![module_base + i]; 57 } 58 results.push(module_base + i); 59 } 60 i += 1; 61 } 62 63 SIGNATURE_CACHE.lock().unwrap().push((pattern.to_string(), results.clone())); 64 results 65 } 66 67 pub fn find_signature_executable(mapped_lib: &MappedLib, pattern: &str) -> Option<usize> { 68 let executable_regions = mapped_lib.regions.iter().filter(|region| { 69 region.perms.contains(MMPermissions::EXECUTE) && region.perms.contains(MMPermissions::READ) 70 }).collect::<Vec<_>>(); 71 72 for region in executable_regions { 73 let size = (region.end - region.start) as usize; 74 let module_base = region.start as usize; 75 76 if size > 0 { 77 let results = find_signatures(module_base, size, pattern, true); 78 79 if results.is_empty() { 80 warn!("Signature not found in region: {:#x} - {:#x}", region.start, region.end); 81 } else { 82 debug!("Found {} results in region: {:#x} - {:#x}", results.len(), region.start, region.end); 83 return Some(results[0]); 84 } 85 } 86 } 87 88 None 89 } 90 91 pub fn find_signature(mapped_lib: &MappedLib, _arm64_pattern: &str, _arm64_offset: i64, _arm32_pattern: &str, _arm32_offset: i64) -> Option<usize> { 92 #[cfg(target_arch = "aarch64")] 93 { 94 return find_signature_executable(mapped_lib, _arm64_pattern).map(|address| (address as i64 + _arm64_offset) as usize); 95 } 96 #[cfg(target_arch = "arm")] 97 { 98 return find_signature_executable(mapped_lib, _arm32_pattern).map(|address| (address as i64 + _arm32_offset) as usize); 99 } 100 }