mod pattern;
mod cache;
mod verifier;
mod scanner;
mod builder;
pub use pattern::Pattern;
pub use builder::AobScanBuilder;
pub use cache::{clear_region_cache, clear_all_region_cache};
#[cfg(test)]
mod tests {
use super::*;
use windows::Win32::Foundation::HANDLE;
#[test]
fn test_pattern_parse_simple() {
let pattern = Pattern::from_str("48 89 5C").unwrap();
drop(pattern);
}
#[test]
fn test_pattern_parse_wildcards() {
let pattern = Pattern::from_str("48 ?? 5C ?? 90").unwrap();
drop(pattern);
}
#[test]
fn test_pattern_parse_single_wildcard() {
let pattern = Pattern::from_str("48 ? 5C").unwrap();
drop(pattern);
}
#[test]
fn test_pattern_parse_invalid() {
assert!(Pattern::from_str("").is_err());
assert!(Pattern::from_str("GG").is_err());
assert!(Pattern::from_str("100").is_err()); }
#[test]
fn test_pattern_find_anchor() {
let pattern = Pattern::from_str("?? 48 ?? 55").unwrap();
drop(pattern);
}
#[test]
fn test_pattern_only_wildcards() {
let pattern = Pattern::from_str("?? ?? ??").unwrap();
drop(pattern);
}
#[test]
fn test_multi_byte_anchor_sequence() {
let pattern = Pattern::from_str("48 89 5C ?? 90 91").unwrap();
drop(pattern);
}
#[test]
fn test_no_multi_byte_anchor_for_wildcards() {
let pattern = Pattern::from_str("48 ?? 55 ?? 90").unwrap();
drop(pattern);
}
#[test]
fn test_builder_requires_pattern() {
let handle = HANDLE(std::ptr::null_mut());
let result = AobScanBuilder::new(handle).scan();
assert!(result.is_err());
}
#[test]
fn test_builder_chain() {
let handle = HANDLE(std::ptr::null_mut());
let _builder = AobScanBuilder::new(handle)
.pattern_str("48 ?? 55").unwrap()
.start_address(0x1000)
.length(0x100)
.find_all(true);
}
#[test]
fn test_simd_scalar_consistency() {
use crate::memory_aobscan::verifier::verify_pattern;
let pattern = Pattern::from_str("48 89 5C ?? 90 91 92 93 94 95 96 97 98 99 9A 9B").unwrap();
let mut buffer = vec![0u8; 64];
buffer[0] = 0x48;
buffer[1] = 0x89;
buffer[2] = 0x5C;
for i in 4..16 {
buffer[i] = 0x90 + (i - 4) as u8;
}
let result = verify_pattern(&buffer, 0, &pattern);
assert!(result, "Pattern should match at offset 0");
}
#[test]
fn test_simd_mismatch_detection() {
use crate::memory_aobscan::verifier::verify_pattern;
let pattern = Pattern::from_str("48 89 5C ?? 90 91 92 93 94 95 96 97 98 99 9A 9B").unwrap();
let mut buffer = vec![0u8; 64];
buffer[0] = 0x48;
buffer[1] = 0x89;
buffer[2] = 0x5C;
buffer[4] = 0xFF;
let result = verify_pattern(&buffer, 0, &pattern);
assert!(!result, "Pattern should not match due to byte mismatch");
}
#[test]
fn test_prefetch_does_not_affect_correctness() {
use crate::memory_aobscan::verifier::verify_pattern;
let pattern = Pattern::from_str("48 89 5C").unwrap();
let buffer = vec![0x48, 0x89, 0x5C, 0x00, 0x00];
for offset in 0..3 {
let result = verify_pattern(&buffer, offset, &pattern);
if offset == 0 {
assert!(result, "Should match at offset 0");
} else {
assert!(!result, "Should not match at offset {}", offset);
}
}
}
}