mirror of
https://github.com/a2x/cs2-dumper.git
synced 2026-04-17 19:49:58 +08:00
Merge dev branch into main
This commit is contained in:
95
src/analysis/offsets.rs
Normal file
95
src/analysis/offsets.rs
Normal file
@@ -0,0 +1,95 @@
|
||||
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(Debug, 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,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user