Hello, there was some issues with the tests so I didn't get to try - although, there shouldn't be any issue. If there is please tell me and I'll take care of it.
Also, why not reimplement the pattern scanner as following?
/// Find `pattern` indice in `self.size`-sized raw parts of `self.bytes`, returns either
/// `Pointer<T>` or `std::io::Error`
///
/// # Arguments
///
/// `pattern` - Array, can contain wildcard (`0`) which'll be ignored in matching
///
/// # Example
///
/// ```
/// module.find_pattern_bytes::<u8>(b"\x55\x8B\xEC").expect("Failed finding prologue")
/// ```
///
/// # Safety
///
/// Computes `from_raw_parts` from raw pointer of `self.size` and walks section,
/// which is considered `unsafe`
pub fn find_pattern_bytes<T>(&self, pattern: &[u8]) -> Result<Pointer<T>, Error> {
/// Custom predicate for iterator position finder
fn match_with_wildcard(wildcard_array: &[u8], memory_view: &[u8]) -> bool {
!wildcard_array
.iter()
.zip(memory_view)
.map(|x| if *x.0 == 0 { true } else { *x.0 == *x.1 })
.any(|x| !x)
}
let indice = unsafe {
std::slice::from_raw_parts(self.get_bytes(), self.get_size() - pattern.len())
.windows(pattern.len())
.position(|x| match_with_wildcard(pattern, x))
.ok_or(Error::new(
ErrorKind::InvalidData,
format_args!(
"Failed finding subsequence {:x?} in slice sequence",
pattern
)
.to_string(),
))?
};
Ok(Pointer::new((self.get_bytes() as usize + indice) as _))
}
/// This is a wrapper for it's [base function](Module::find_pattern_bytes)
///
/// # Arguments
///
/// `pattern` - String which'll get split by whitespaces. If a resulting substring
/// contains `'?'`, it'll be mapped to `0` in the iterator, otherwise, it'll be turned into it's
/// hexadecimal form. If it's not contained within hexadecimal alphanumerical bounds, it'll
/// panic
pub fn find_pattern<T>(&self, pattern: &str) -> Result<Pointer<T>, Error> {
fn string_to_vec(pattern: &str) -> Vec<u8> {
pattern
.split_whitespace()
.map(|x| {
if x.contains('?') {
0
} else {
u8::from_str_radix(x, 16)
.expect("Substring not contained within hexadecimal alphanumeric form")
}
})
.collect()
}
self.find_pattern_bytes(string_to_vec(pattern).as_slice())
}
I do it like that personally. Should also work on externals with little modification inside the find_pattern_bytes based on cfg.