Message
Message
[allow(dead_code)]
use std::ffi::{CStr, CString};
use std::mem::MaybeUninit;
use std::os::raw::c_void;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum SignatureScannerError {
#[error("library matching the address {0:?} not found")]
LibraryNotFound(*const ()),
#[error(transparent)]
NulError(#[from] std::ffi::NulError),
#[derive(Error, Debug)]
pub enum PatternError {
#[error("string is empty")]
EmptyString,
#[error("symbol is empty")]
EmptySymbol,
#[error("unexpected EOS")]
UnexpectedEos,
#[derive(Debug, Clone)]
pub enum Signature {
Pattern(Vec<Unit>),
Symbol(String),
}
return Ok(Signature::Symbol(symbol.to_string()));
}
Ok(Signature::Pattern(pattern))
}
}
impl SignatureScanner {
pub fn new(addr: *const ()) -> Result<Self> {
let info = lib_info(addr)?;
let (base_addr, lib_len) = lib_base_and_len(&info)?;
let end_addr = unsafe { base_addr.add(lib_len) };
let handle = lib_handle(&info)?;
if info.dli_fbase.is_null() || info.dli_fname.is_null() {
return Err(SignatureScannerError::LibraryNotFound(addr));
}
Ok(info)
}
matched_addr = ptr;
}
if matched_addr.is_null() {
Err(SignatureScannerError::NoMatches(pattern_to_string(pattern)))
} else {
Ok(matched_addr as *const _)
}
}
fn pattern_matches(mut ptr: *const u8, end_addr: *const u8, pattern: &[Unit]) ->
Result<bool> {
for unit in pattern {
if ptr >= end_addr {
return
Err(SignatureScannerError::NoMatches(pattern_to_string(pattern)));
}
if symbol_ptr.is_null() {
Err(SignatureScannerError::NoMatches(symbol_to_string(symbol)))
} else {
Ok(symbol_ptr as *const _)
}
}