pub mod resolver;
mod builder;
pub use resolver::{MemoryAddress, AddressBase, AddressOp, ParseError, ResolveError, PointerSize};
pub use crate::memory_aobscan::AobScanBuilder;
#[derive(Clone, Debug)]
pub enum AddressSource {
Static(MemoryAddress),
AobScan {
pattern: String,
start_address: usize,
length: usize,
find_first: bool,
},
}
impl AddressSource {
pub fn from_static(address: MemoryAddress) -> Self {
AddressSource::Static(address)
}
pub fn from_pattern(pattern: &str) -> Result<Self, ParseError> {
MemoryAddress::parse(pattern).map(AddressSource::Static)
}
pub fn from_pattern_x86(pattern: &str) -> Result<Self, ParseError> {
MemoryAddress::new_x86(pattern).map(AddressSource::Static)
}
pub fn from_pattern_x64(pattern: &str) -> Result<Self, ParseError> {
MemoryAddress::new_x64(pattern).map(AddressSource::Static)
}
pub fn from_aob(pattern: &str) -> Result<Self, String> {
Ok(AddressSource::AobScan {
pattern: pattern.to_string(),
start_address: 0,
length: 0,
find_first: true,
})
}
pub fn from_aob_with_options(pattern: &str, start: usize, length: usize, find_first: bool) -> Result<Self, String> {
Ok(AddressSource::AobScan {
pattern: pattern.to_string(),
start_address: start,
length,
find_first,
})
}
}
impl std::convert::TryFrom<&str> for AddressSource {
type Error = ParseError;
fn try_from(s: &str) -> Result<Self, Self::Error> {
MemoryAddress::parse(s).map(AddressSource::Static)
}
}
impl AddressSource {
pub fn from_aob_scan(pattern: &str) -> Result<Self, String> {
Ok(AddressSource::AobScan {
pattern: pattern.to_string(),
start_address: 0,
length: 0,
find_first: true,
})
}
pub fn from_aob_scan_range(pattern: &str, start: usize, length: usize) -> Result<Self, String> {
Ok(AddressSource::AobScan {
pattern: pattern.to_string(),
start_address: start,
length,
find_first: true,
})
}
pub fn resolve(&self, handle: windows::Win32::Foundation::HANDLE, pid: u32) -> Result<usize, Box<dyn std::error::Error>> {
match self {
AddressSource::Static(addr) => {
addr.resolve_address(handle, pid)
.map_err(|e| Box::new(e) as Box<dyn std::error::Error>)
}
AddressSource::AobScan { pattern, start_address, length, find_first } => {
let results = AobScanBuilder::new(handle)
.pattern_str(pattern)?
.start_address(*start_address)
.length(*length)
.find_all(!find_first)
.scan()
.map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?;
if results.is_empty() {
Err(format!("AOB pattern '{}' not found", pattern).into())
} else {
Ok(results[0])
}
}
}
}
}