mirror of
https://github.com/a2x/cs2-dumper.git
synced 2025-05-01 03:25:35 +08:00
96 lines
2.5 KiB
Rust
96 lines
2.5 KiB
Rust
use std::collections::BTreeMap;
|
|
use std::mem;
|
|
use std::str::FromStr;
|
|
|
|
use log::{debug, error};
|
|
|
|
use memflow::prelude::v1::*;
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::config::{Operation, Signature, CONFIG};
|
|
use crate::error::{Error, Result};
|
|
|
|
pub type OffsetMap = BTreeMap<String, Vec<Offset>>;
|
|
|
|
#[derive(Deserialize, Serialize)]
|
|
pub struct Offset {
|
|
pub name: String,
|
|
pub value: u32,
|
|
}
|
|
|
|
pub fn offsets(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<OffsetMap> {
|
|
let mut map = BTreeMap::new();
|
|
|
|
for (module_name, sigs) in CONFIG.signatures.iter().flatten() {
|
|
let module = process.module_by_name(module_name)?;
|
|
|
|
let mut offsets: Vec<_> = sigs
|
|
.iter()
|
|
.filter_map(|sig| match read_offset(process, &module, sig) {
|
|
Ok(offset) => Some(offset),
|
|
Err(err) => {
|
|
error!("{}", err);
|
|
|
|
None
|
|
}
|
|
})
|
|
.collect();
|
|
|
|
if !offsets.is_empty() {
|
|
offsets.sort_unstable_by(|a, b| a.name.cmp(&b.name));
|
|
|
|
map.insert(module_name.to_string(), offsets);
|
|
}
|
|
}
|
|
|
|
Ok(map)
|
|
}
|
|
|
|
fn read_offset(
|
|
process: &mut IntoProcessInstanceArcBox<'_>,
|
|
module: &ModuleInfo,
|
|
signature: &Signature,
|
|
) -> Result<Offset> {
|
|
let buf = process.read_raw(module.base, module.size as _)?;
|
|
|
|
let addr = skidscan::Signature::from_str(&signature.pattern)?
|
|
.scan(&buf)
|
|
.ok_or_else(|| Error::SignatureNotFound(signature.name.clone()))?;
|
|
|
|
let mut result = module.base + addr;
|
|
|
|
for op in &signature.operations {
|
|
result = match op {
|
|
Operation::Add { value } => result + *value,
|
|
Operation::Rip { offset, len } => {
|
|
let offset: i32 = process.read(result + offset.unwrap_or(3))?;
|
|
|
|
(result + offset) + len.unwrap_or(7)
|
|
}
|
|
Operation::Read => process.read_addr64(result)?,
|
|
Operation::Slice { start, end } => {
|
|
let buf = process.read_raw(result + *start, end - start)?;
|
|
|
|
let mut bytes = [0; mem::size_of::<usize>()];
|
|
|
|
bytes[..buf.len()].copy_from_slice(&buf);
|
|
|
|
usize::from_le_bytes(bytes).into()
|
|
}
|
|
Operation::Sub { value } => result - *value,
|
|
};
|
|
}
|
|
|
|
let value = (result - module.base)
|
|
.try_into()
|
|
.map_or_else(|_| result.to_umem() as u32, |v| v);
|
|
|
|
debug!("found offset: {} at {:#X}", signature.name, value);
|
|
|
|
Ok(Offset {
|
|
name: signature.name.clone(),
|
|
value,
|
|
})
|
|
}
|