ScrapHacks/tools/remaster/scraphacks_rs/src/mem.rs

95 lines
2.8 KiB
Rust

use std::str::FromStr;
use anyhow::anyhow;
use anyhow::bail;
use anyhow::Result;
use pelite::pattern::parse;
use pelite::pattern::save_len;
use pelite::pattern::Atom;
use pelite::pe32::{Pe, PeView};
use winsafe::co::TH32CS;
use winsafe::prelude::*;
use winsafe::HINSTANCE;
use winsafe::HPROCESSLIST;
pub(crate) struct Pattern(Vec<Atom>, usize);
impl Pattern {
pub(crate) fn set_index(mut self, idx: usize) -> Self {
self.1 = idx;
self
}
}
impl FromStr for Pattern {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(parse(s)?, 0))
}
}
impl Pattern {
pub(crate) fn scan(&self, module: Option<String>) -> Result<u32> {
let pe = get_module(module)?;
let scan = pe.scanner();
let mut save = vec![0u32; save_len(&self.0)];
if !scan.finds(&self.0, 0..u32::MAX, &mut save) {
bail!("Pattern not found");
}
save.get(self.1)
.ok_or_else(|| anyhow!("Result index out of range"))
.and_then(|r| pe.rva_to_va(*r).map_err(|e| e.into()))
}
}
pub(crate) fn get_modules() -> Result<Vec<PeView<'static>>> {
let mut res = vec![];
let pid = std::process::id();
let mut h_snap = HPROCESSLIST::CreateToolhelp32Snapshot(TH32CS::SNAPMODULE, Some(pid))?;
for module in h_snap.iter_modules() {
res.push(unsafe { PeView::module(module?.hModule.as_ptr() as *const u8) });
}
Ok(res)
}
pub(crate) fn get_module(module: Option<String>) -> Result<PeView<'static>> {
let hmodule = HINSTANCE::GetModuleHandle(module.as_deref())?;
Ok(unsafe { PeView::module(hmodule.as_ptr() as *const u8) })
}
pub(crate) fn scan(pat: &[Atom], pe: &PeView) -> Result<Vec<Vec<u32>>> {
let mut ret = vec![];
let scan = pe.scanner();
let mut m = scan.matches(pat, 0..u32::MAX);
let mut save = vec![0u32; save_len(pat)];
while m.next(&mut save) {
ret.push(
save.iter()
.map(|rva| pe.rva_to_va(*rva).map_err(|e| e.into()))
.collect::<Result<Vec<u32>>>()?,
);
}
Ok(ret)
}
pub(crate) fn search(pat: &str, idx: usize, module: Option<String>) -> Result<u32> {
pat.parse::<Pattern>()?.set_index(idx).scan(module)
}
fn addr_info(addr: u32) -> Result<()> {
let pid = std::process::id();
let mut h_snap = HPROCESSLIST::CreateToolhelp32Snapshot(TH32CS::SNAPMODULE, Some(pid))?;
for module in h_snap.iter_modules() {
let module = module?;
let module_name = module.szModule();
if module_name.to_lowercase() == "kernel32.dll" {
continue;
}
let mod_range =
unsafe { module.modBaseAddr..module.modBaseAddr.offset(module.modBaseSize as isize) };
println!("{module_name}: {mod_range:?}");
// let module = unsafe { PeView::module(module.modBaseAddr as *const u8) };
}
Ok(())
}