mirror of
https://github.com/a2x/cs2-dumper.git
synced 2025-10-08 05:10:02 +08:00
Simplify some code
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use anyhow::{Result, bail};
|
||||
|
||||
use log::debug;
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::source2::KeyButton;
|
||||
|
||||
pub type ButtonMap = BTreeMap<String, imem>;
|
||||
|
||||
pub fn buttons(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<ButtonMap> {
|
||||
pub fn buttons<P: Process + MemoryView>(process: &mut P) -> Result<ButtonMap> {
|
||||
let module = process.module_by_name("client.dll")?;
|
||||
|
||||
let buf = process
|
||||
@@ -35,17 +35,17 @@ pub fn buttons(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<ButtonMap>
|
||||
}
|
||||
|
||||
fn read_buttons(
|
||||
process: &mut IntoProcessInstanceArcBox<'_>,
|
||||
mem: &mut impl MemoryView,
|
||||
module: &ModuleInfo,
|
||||
list_addr: Address,
|
||||
) -> Result<ButtonMap> {
|
||||
let mut map = ButtonMap::new();
|
||||
|
||||
let mut cur_button = Pointer64::<KeyButton>::from(process.read_addr64(list_addr).data_part()?);
|
||||
let mut cur_button = Pointer64::<KeyButton>::from(mem.read_addr64(list_addr).data_part()?);
|
||||
|
||||
while !cur_button.is_null() {
|
||||
let button = process.read_ptr(cur_button).data_part()?;
|
||||
let name = process.read_utf8(button.name.address(), 32).data_part()?;
|
||||
let button = mem.read_ptr(cur_button).data_part()?;
|
||||
let name = mem.read_utf8(button.name.address(), 32).data_part()?;
|
||||
let rva = (cur_button.address() - module.base) + offset_of!(KeyButton.state) as imem;
|
||||
|
||||
debug!(
|
||||
|
@@ -9,20 +9,16 @@ use memflow::prelude::v1::*;
|
||||
use pelite::pe64::exports::Export;
|
||||
use pelite::pe64::{Pe, PeView};
|
||||
|
||||
use crate::mem::read_addr64_rip;
|
||||
use crate::source2::InterfaceReg;
|
||||
|
||||
pub type InterfaceMap = BTreeMap<String, BTreeMap<String, umem>>;
|
||||
|
||||
pub fn interfaces(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<InterfaceMap> {
|
||||
pub fn interfaces<P: Process + MemoryView>(process: &mut P) -> Result<InterfaceMap> {
|
||||
process
|
||||
.module_list()?
|
||||
.iter()
|
||||
.filter(|module| module.name.as_ref() != "crashandler64.dll")
|
||||
.filter_map(|module| {
|
||||
if module.name.as_ref() == "crashhandler64.dll" {
|
||||
return None;
|
||||
}
|
||||
|
||||
let buf = process
|
||||
.read_raw(module.base, module.size as _)
|
||||
.data_part()
|
||||
@@ -39,9 +35,7 @@ pub fn interfaces(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<Interfa
|
||||
.ok()?;
|
||||
|
||||
if let Export::Symbol(symbol) = ci_export {
|
||||
let list_addr = read_addr64_rip(process, module.base + symbol)
|
||||
.data_part()
|
||||
.ok()?;
|
||||
let list_addr = read_addr64_rip(process, module.base + symbol).ok()?;
|
||||
|
||||
return read_interfaces(process, module, list_addr)
|
||||
.ok()
|
||||
@@ -55,18 +49,18 @@ pub fn interfaces(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<Interfa
|
||||
}
|
||||
|
||||
fn read_interfaces(
|
||||
process: &mut IntoProcessInstanceArcBox<'_>,
|
||||
mem: &mut impl MemoryView,
|
||||
module: &ModuleInfo,
|
||||
list_addr: Address,
|
||||
) -> Result<BTreeMap<String, umem>> {
|
||||
let mut ifaces = BTreeMap::new();
|
||||
|
||||
let mut cur_reg = Pointer64::<InterfaceReg>::from(process.read_addr64(list_addr).data_part()?);
|
||||
let mut cur_reg = Pointer64::<InterfaceReg>::from(mem.read_addr64(list_addr).data_part()?);
|
||||
|
||||
while !cur_reg.is_null() {
|
||||
let reg = process.read_ptr(cur_reg).data_part()?;
|
||||
let name = process.read_utf8(reg.name.address(), 128).data_part()?;
|
||||
let instance = read_addr64_rip(process, reg.create_fn.address())?;
|
||||
let reg = mem.read_ptr(cur_reg).data_part()?;
|
||||
let name = mem.read_utf8(reg.name.address(), 128).data_part()?;
|
||||
let instance = read_addr64_rip(mem, reg.create_fn.address())?;
|
||||
let value = instance.wrapping_sub(module.base).to_umem();
|
||||
|
||||
debug!(
|
||||
@@ -84,3 +78,9 @@ fn read_interfaces(
|
||||
|
||||
Ok(ifaces)
|
||||
}
|
||||
|
||||
fn read_addr64_rip(mem: &mut impl MemoryView, addr: Address) -> Result<Address> {
|
||||
let disp = mem.read::<i32>(addr + 0x3).data_part()?;
|
||||
|
||||
Ok(addr + 0x7 + disp)
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ pub struct AnalysisResult {
|
||||
pub schemas: SchemaMap,
|
||||
}
|
||||
|
||||
pub fn analyze_all(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<AnalysisResult> {
|
||||
pub fn analyze_all<P: Process + MemoryView>(process: &mut P) -> Result<AnalysisResult> {
|
||||
let buttons = analyze(process, buttons);
|
||||
|
||||
info!("found {} buttons", buttons.len());
|
||||
@@ -75,10 +75,10 @@ pub fn analyze_all(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<Analys
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn analyze<F, T>(process: &mut IntoProcessInstanceArcBox<'_>, f: F) -> T
|
||||
fn analyze<P, F, T>(process: &mut P, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut IntoProcessInstanceArcBox<'_>) -> Result<T>,
|
||||
P: Process + MemoryView,
|
||||
F: FnOnce(&mut P) -> Result<T>,
|
||||
T: Default,
|
||||
{
|
||||
let name = type_name::<F>();
|
||||
|
@@ -7,10 +7,10 @@ use log::{debug, error};
|
||||
use memflow::prelude::v1::*;
|
||||
|
||||
use pelite::pattern;
|
||||
use pelite::pattern::{save_len, Atom};
|
||||
use pelite::pattern::{Atom, save_len};
|
||||
use pelite::pe64::{Pe, PeView, Rva};
|
||||
|
||||
use phf::{phf_map, Map};
|
||||
use phf::{Map, phf_map};
|
||||
|
||||
pub type OffsetMap = BTreeMap<String, BTreeMap<String, Rva>>;
|
||||
|
||||
@@ -127,7 +127,7 @@ pattern_map! {
|
||||
},
|
||||
}
|
||||
|
||||
pub fn offsets(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<OffsetMap> {
|
||||
pub fn offsets<P: Process + MemoryView>(process: &mut P) -> Result<OffsetMap> {
|
||||
let mut map = BTreeMap::new();
|
||||
|
||||
let modules: [(&str, fn(PeView) -> BTreeMap<String, u32>); 5] = [
|
||||
|
@@ -1,7 +1,7 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::ffi::CStr;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use anyhow::{Result, bail};
|
||||
|
||||
use log::debug;
|
||||
|
||||
@@ -60,7 +60,7 @@ pub struct TypeScope {
|
||||
pub enums: Vec<Enum>,
|
||||
}
|
||||
|
||||
pub fn schemas(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<SchemaMap> {
|
||||
pub fn schemas<P: Process + MemoryView>(process: &mut P) -> Result<SchemaMap> {
|
||||
let schema_system = read_schema_system(process)?;
|
||||
let type_scopes = read_type_scopes(process, &schema_system)?;
|
||||
|
||||
@@ -78,17 +78,17 @@ pub fn schemas(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<SchemaMap>
|
||||
}
|
||||
|
||||
fn read_class_binding(
|
||||
process: &mut IntoProcessInstanceArcBox<'_>,
|
||||
mem: &mut impl MemoryView,
|
||||
binding_ptr: Pointer64<SchemaClassBinding>,
|
||||
) -> Result<Class> {
|
||||
let binding = process.read_ptr(binding_ptr).data_part()?;
|
||||
let binding = mem.read_ptr(binding_ptr).data_part()?;
|
||||
|
||||
let module_name = process
|
||||
let module_name = mem
|
||||
.read_utf8_lossy(binding.module_name.address(), 128)
|
||||
.data_part()
|
||||
.map(|s| format!("{}.dll", s))?;
|
||||
|
||||
let name = process
|
||||
let name = mem
|
||||
.read_utf8_lossy(binding.name.address(), 4096)
|
||||
.data_part()?;
|
||||
|
||||
@@ -97,15 +97,15 @@ fn read_class_binding(
|
||||
}
|
||||
|
||||
let parent = binding.base_classes.non_null().and_then(|ptr| {
|
||||
let base_class = process.read_ptr(ptr).data_part().ok()?;
|
||||
let parent_class = process.read_ptr(base_class.prev).data_part().ok()?;
|
||||
let base_class = mem.read_ptr(ptr).data_part().ok()?;
|
||||
let parent_class = mem.read_ptr(base_class.prev).data_part().ok()?;
|
||||
|
||||
let module_name = process
|
||||
let module_name = mem
|
||||
.read_utf8_lossy(parent_class.module_name.address(), 128)
|
||||
.data_part()
|
||||
.ok()?;
|
||||
|
||||
let name = process
|
||||
let name = mem
|
||||
.read_utf8_lossy(parent_class.name.address(), 4096)
|
||||
.data_part()
|
||||
.ok()?;
|
||||
@@ -119,8 +119,8 @@ fn read_class_binding(
|
||||
}))
|
||||
});
|
||||
|
||||
let fields = read_class_binding_fields(process, &binding)?;
|
||||
let metadata = read_class_binding_metadata(process, &binding)?;
|
||||
let fields = read_class_binding_fields(mem, &binding)?;
|
||||
let metadata = read_class_binding_metadata(mem, &binding)?;
|
||||
|
||||
debug!(
|
||||
"found class: {} at {:#X} (module name: {}) (parent name: {:?}) (metadata count: {}) (field count: {})",
|
||||
@@ -142,7 +142,7 @@ fn read_class_binding(
|
||||
}
|
||||
|
||||
fn read_class_binding_fields(
|
||||
process: &mut IntoProcessInstanceArcBox<'_>,
|
||||
mem: &mut impl MemoryView,
|
||||
binding: &SchemaClassBinding,
|
||||
) -> Result<Vec<ClassField>> {
|
||||
if binding.fields.is_null() {
|
||||
@@ -150,28 +150,28 @@ fn read_class_binding_fields(
|
||||
}
|
||||
|
||||
(0..binding.field_count).try_fold(Vec::new(), |mut acc, i| {
|
||||
let field = process.read_ptr(binding.fields.at(i as _)).data_part()?;
|
||||
let field = mem.read_ptr(binding.fields.at(i as _)).data_part()?;
|
||||
|
||||
if field.schema_type.is_null() {
|
||||
if field.r#type.is_null() {
|
||||
return Ok(acc);
|
||||
}
|
||||
|
||||
let name = process
|
||||
let name = mem
|
||||
.read_utf8_lossy(field.name.address(), 4096)
|
||||
.data_part()?;
|
||||
|
||||
let schema_type = process.read_ptr(field.schema_type).data_part()?;
|
||||
let r#type = mem.read_ptr(field.r#type).data_part()?;
|
||||
|
||||
// TODO: Parse this properly.
|
||||
let type_name = process
|
||||
.read_utf8_lossy(schema_type.name.address(), 128)
|
||||
let type_name = mem
|
||||
.read_utf8_lossy(r#type.name.address(), 128)
|
||||
.data_part()?
|
||||
.replace(" ", "");
|
||||
|
||||
acc.push(ClassField {
|
||||
name,
|
||||
type_name,
|
||||
offset: field.single_inheritance_offset,
|
||||
offset: field.offset,
|
||||
});
|
||||
|
||||
Ok(acc)
|
||||
@@ -179,7 +179,7 @@ fn read_class_binding_fields(
|
||||
}
|
||||
|
||||
fn read_class_binding_metadata(
|
||||
process: &mut IntoProcessInstanceArcBox<'_>,
|
||||
mem: &mut impl MemoryView,
|
||||
binding: &SchemaClassBinding,
|
||||
) -> Result<Vec<ClassMetadata>> {
|
||||
if binding.static_metadata.is_null() {
|
||||
@@ -187,7 +187,7 @@ fn read_class_binding_metadata(
|
||||
}
|
||||
|
||||
(0..binding.static_metadata_count).try_fold(Vec::new(), |mut acc, i| {
|
||||
let metadata = process
|
||||
let metadata = mem
|
||||
.read_ptr(binding.static_metadata.at(i as _))
|
||||
.data_part()?;
|
||||
|
||||
@@ -195,15 +195,15 @@ fn read_class_binding_metadata(
|
||||
return Ok(acc);
|
||||
}
|
||||
|
||||
let name = process
|
||||
let name = mem
|
||||
.read_utf8_lossy(metadata.name.address(), 4096)
|
||||
.data_part()?;
|
||||
|
||||
let network_value = process.read_ptr(metadata.network_value).data_part()?;
|
||||
let network_value = mem.read_ptr(metadata.network_value).data_part()?;
|
||||
|
||||
let metadata = match name.as_str() {
|
||||
"MNetworkChangeCallback" => unsafe {
|
||||
let name = process
|
||||
let name = mem
|
||||
.read_utf8_lossy(network_value.value.name_ptr.address(), 4096)
|
||||
.data_part()?;
|
||||
|
||||
@@ -212,11 +212,11 @@ fn read_class_binding_metadata(
|
||||
"MNetworkVarNames" => unsafe {
|
||||
let var_value = network_value.value.var_value;
|
||||
|
||||
let name = process
|
||||
let name = mem
|
||||
.read_utf8_lossy(var_value.name.address(), 4096)
|
||||
.data_part()?;
|
||||
|
||||
let type_name = process
|
||||
let type_name = mem
|
||||
.read_utf8_lossy(var_value.type_name.address(), 128)
|
||||
.data_part()?
|
||||
.replace(" ", "");
|
||||
@@ -233,12 +233,12 @@ fn read_class_binding_metadata(
|
||||
}
|
||||
|
||||
fn read_enum_binding(
|
||||
process: &mut IntoProcessInstanceArcBox<'_>,
|
||||
mem: &mut impl MemoryView,
|
||||
binding_ptr: Pointer64<SchemaEnumBinding>,
|
||||
) -> Result<Enum> {
|
||||
let binding = process.read_ptr(binding_ptr).data_part()?;
|
||||
let binding = mem.read_ptr(binding_ptr).data_part()?;
|
||||
|
||||
let name = process
|
||||
let name = mem
|
||||
.read_utf8_lossy(binding.name.address(), 4096)
|
||||
.data_part()?;
|
||||
|
||||
@@ -246,7 +246,7 @@ fn read_enum_binding(
|
||||
bail!("empty enum name");
|
||||
}
|
||||
|
||||
let members = read_enum_binding_members(process, &binding)?;
|
||||
let members = read_enum_binding_members(mem, &binding)?;
|
||||
|
||||
debug!(
|
||||
"found enum: {} at {:#X} (alignment: {}) (member count: {})",
|
||||
@@ -259,38 +259,36 @@ fn read_enum_binding(
|
||||
Ok(Enum {
|
||||
name,
|
||||
alignment: binding.align_of,
|
||||
size: binding.enumerator_count,
|
||||
size: binding.enum_count,
|
||||
members,
|
||||
})
|
||||
}
|
||||
|
||||
fn read_enum_binding_members(
|
||||
process: &mut IntoProcessInstanceArcBox<'_>,
|
||||
mem: &mut impl MemoryView,
|
||||
binding: &SchemaEnumBinding,
|
||||
) -> Result<Vec<EnumMember>> {
|
||||
if binding.enumerators.is_null() {
|
||||
if binding.enums.is_null() {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
(0..binding.enumerator_count).try_fold(Vec::new(), |mut acc, i| {
|
||||
let enumerator = process
|
||||
.read_ptr(binding.enumerators.at(i as _))
|
||||
.data_part()?;
|
||||
(0..binding.enum_count).try_fold(Vec::new(), |mut acc, i| {
|
||||
let r#enum = mem.read_ptr(binding.enums.at(i as _)).data_part()?;
|
||||
|
||||
let name = process
|
||||
.read_utf8_lossy(enumerator.name.address(), 4096)
|
||||
let name = mem
|
||||
.read_utf8_lossy(r#enum.name.address(), 4096)
|
||||
.data_part()?;
|
||||
|
||||
acc.push(EnumMember {
|
||||
name,
|
||||
value: unsafe { enumerator.value.ulong } as i64,
|
||||
value: unsafe { r#enum.value.ulong } as i64,
|
||||
});
|
||||
|
||||
Ok(acc)
|
||||
})
|
||||
}
|
||||
|
||||
fn read_schema_system(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<SchemaSystem> {
|
||||
fn read_schema_system<P: Process + MemoryView>(process: &mut P) -> Result<SchemaSystem> {
|
||||
let module = process.module_by_name("schemasystem.dll")?;
|
||||
|
||||
let buf = process
|
||||
@@ -318,14 +316,14 @@ fn read_schema_system(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<Sch
|
||||
}
|
||||
|
||||
fn read_type_scopes(
|
||||
process: &mut IntoProcessInstanceArcBox<'_>,
|
||||
mem: &mut impl MemoryView,
|
||||
schema_system: &SchemaSystem,
|
||||
) -> Result<Vec<TypeScope>> {
|
||||
let type_scopes = &schema_system.type_scopes;
|
||||
|
||||
(0..type_scopes.size).try_fold(Vec::new(), |mut acc, i| {
|
||||
let type_scope_ptr = type_scopes.element(process, i as _)?;
|
||||
let type_scope = process.read_ptr(type_scope_ptr).data_part()?;
|
||||
let type_scope_ptr = type_scopes.element(mem, i as _)?;
|
||||
let type_scope = mem.read_ptr(type_scope_ptr).data_part()?;
|
||||
|
||||
let module_name = unsafe { CStr::from_ptr(type_scope.name.as_ptr()) }
|
||||
.to_string_lossy()
|
||||
@@ -333,16 +331,16 @@ fn read_type_scopes(
|
||||
|
||||
let classes: Vec<_> = type_scope
|
||||
.class_bindings
|
||||
.elements(process)?
|
||||
.elements(mem)?
|
||||
.iter()
|
||||
.filter_map(|ptr| read_class_binding(process, *ptr).ok())
|
||||
.filter_map(|ptr| read_class_binding(mem, *ptr).ok())
|
||||
.collect();
|
||||
|
||||
let enums: Vec<_> = type_scope
|
||||
.enum_bindings
|
||||
.elements(process)?
|
||||
.elements(mem)?
|
||||
.iter()
|
||||
.filter_map(|ptr| read_enum_binding(process, *ptr).ok())
|
||||
.filter_map(|ptr| read_enum_binding(mem, *ptr).ok())
|
||||
.collect();
|
||||
|
||||
if classes.is_empty() && enums.is_empty() {
|
||||
|
Reference in New Issue
Block a user