sig.rs (3211B) - 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 while i < size { 41 let mut found = true; 42 let mut j = 0; 43 44 while j < bytes.len() { 45 if mask[j] == '?' || bytes[j] == unsafe { *(module_base as *const u8).offset(i as isize + j as isize) } { 46 j += 1; 47 continue; 48 } 49 found = false; 50 break; 51 } 52 if found { 53 if once { 54 SIGNATURE_CACHE.lock().unwrap().push((pattern.to_string(), vec![i])); 55 return vec![module_base + i]; 56 } 57 results.push(module_base + i); 58 } 59 i += 1; 60 } 61 62 SIGNATURE_CACHE.lock().unwrap().push((pattern.to_string(), results.clone())); 63 results 64 } 65 66 pub fn find_signature_executable(mapped_lib: &MappedLib, pattern: &str) -> Option<usize> { 67 let executable_regions = mapped_lib.regions.iter().filter(|region| { 68 region.perms.contains(MMPermissions::EXECUTE) && region.perms.contains(MMPermissions::READ) 69 }).collect::<Vec<_>>(); 70 71 for region in executable_regions { 72 let size = (region.end - region.start) as usize; 73 let module_base = region.start as usize; 74 75 if size > 0 { 76 let results = find_signatures(module_base, size, pattern, true); 77 78 if results.is_empty() { 79 warn!("Signature not found in region: {:#x} - {:#x}", region.start, region.end); 80 } else { 81 debug!("Found {} results in region: {:#x} - {:#x}", results.len(), region.start, region.end); 82 return Some(results[0]); 83 } 84 } 85 } 86 87 None 88 } 89 90 pub fn find_signature(mapped_lib: &MappedLib, _arm64_pattern: &str, _arm64_offset: i64, _arm32_pattern: &str, _arm32_offset: i64) -> Option<usize> { 91 #[cfg(target_arch = "aarch64")] 92 { 93 return find_signature_executable(mapped_lib, _arm64_pattern).map(|address| (address as i64 + _arm64_offset) as usize); 94 } 95 #[cfg(target_arch = "arm")] 96 { 97 return find_signature_executable(mapped_lib, _arm32_pattern).map(|address| (address as i64 + _arm32_offset) as usize); 98 } 99 }