From 127cd110bbeb09e012403cd0cfc4c49a3783cd36 Mon Sep 17 00:00:00 2001 From: a2x <45197573+a2x@users.noreply.github.com> Date: Sat, 2 Mar 2024 01:02:58 +1000 Subject: [PATCH] Remove redundant doc comments --- src/builder/cpp_file_builder.rs | 6 +- src/builder/csharp_file_builder.rs | 6 +- src/builder/file_builder.rs | 57 --------- src/builder/json_file_builder.rs | 13 +- src/builder/mod.rs | 15 +-- src/builder/python_file_builder.rs | 6 +- src/builder/rust_file_builder.rs | 2 - src/builder/yaml_file_builder.rs | 6 +- src/config.rs | 51 ++------ src/dumper/interfaces.rs | 67 +--------- src/dumper/mod.rs | 63 ++------- src/dumper/offsets.rs | 24 +--- src/dumper/schemas.rs | 20 +-- src/main.rs | 51 +++----- src/sdk/schema_class_field_data.rs | 42 +----- src/sdk/schema_class_info.rs | 54 +------- src/sdk/schema_system.rs | 27 +--- src/sdk/schema_system_type_scope.rs | 34 +---- src/sdk/schema_type.rs | 36 +----- src/sdk/schema_type_declared_class.rs | 24 +--- src/sdk/utl_ts_hash.rs | 111 +--------------- src/util/address.rs | 74 ----------- src/util/module.rs | 105 ++------------- src/util/process.rs | 178 ++------------------------ 24 files changed, 103 insertions(+), 969 deletions(-) diff --git a/src/builder/cpp_file_builder.rs b/src/builder/cpp_file_builder.rs index fbcfc87..f59c7ba 100644 --- a/src/builder/cpp_file_builder.rs +++ b/src/builder/cpp_file_builder.rs @@ -1,9 +1,7 @@ -use super::FileBuilder; - use std::io::{Result, Write}; -/// A structure representing a builder for C++ header files. -/// The builder implements the `FileBuilder` trait. +use super::FileBuilder; + #[derive(Clone, Debug, PartialEq)] pub struct CppFileBuilder; diff --git a/src/builder/csharp_file_builder.rs b/src/builder/csharp_file_builder.rs index d4bbb6e..5661e23 100644 --- a/src/builder/csharp_file_builder.rs +++ b/src/builder/csharp_file_builder.rs @@ -1,9 +1,7 @@ -use super::FileBuilder; - use std::io::{Result, Write}; -/// A structure representing a builder for C# files. -/// The builder implements the `FileBuilder` trait. +use super::FileBuilder; + #[derive(Clone, Debug, PartialEq)] pub struct CSharpFileBuilder; diff --git a/src/builder/file_builder.rs b/src/builder/file_builder.rs index 237ee9c..c089d71 100644 --- a/src/builder/file_builder.rs +++ b/src/builder/file_builder.rs @@ -1,42 +1,10 @@ use std::io::{Result, Write}; -/// A trait that defines the file builder operations. pub trait FileBuilder { - /// Returns the extension of the file. - /// - /// # Arguments - /// - /// * `&mut self` - A mutable reference to the `FileBuilder` struct. - /// - /// # Returns - /// - /// * `&str` - A string slice containing the extension of the file. fn extension(&mut self) -> &str; - /// Writes to the top level of the file. The output destination is `output`. - /// - /// # Arguments - /// - /// * `&mut self` - A mutable reference to the `FileBuilder` struct. - /// * `output` - An object implementing Write trait where the top level will be written. - /// - /// # Returns - /// - /// * `Result<()>` - A generic Result type indicating the operations outcome. fn write_top_level(&mut self, output: &mut dyn Write) -> Result<()>; - /// Writes a namespace to the output. - /// - /// # Arguments - /// - /// * `&mut self` - A mutable reference to the `FileBuilder` struct. - /// * `output` - An object implementing Write trait where the namespace will be written. - /// * `name` - The name of the namespace. - /// * `comment` - An optional comment. If present, this comment will be included in the output. - /// - /// # Returns - /// - /// * `Result<()>` - A generic Result type indicating the operations outcome. fn write_namespace( &mut self, output: &mut dyn Write, @@ -44,20 +12,6 @@ pub trait FileBuilder { comment: Option<&str>, ) -> Result<()>; - /// Writes a variable to the output. - /// - /// # Arguments - /// - /// * `&mut self` - A mutable reference to the `FileBuilder` struct. - /// * `output` - An object implementing Write trait where the variable will be written. - /// * `name` - The name of the variable. - /// * `value` - The value of the variable. - /// * `comment` - An optional comment. If present, this comment will be included in the output. - /// * `indentation` - An optional indentation value. If present, the variable will be written with the specified indentation. - /// - /// # Returns - /// - /// * `Result<()>` - A generic Result type indicating the operations outcome. fn write_variable( &mut self, output: &mut dyn Write, @@ -67,16 +21,5 @@ pub trait FileBuilder { indentation: Option, ) -> Result<()>; - /// Writes a closure to the output. - /// - /// # Arguments - /// - /// * `&mut self` - A mutable reference to the `FileBuilder` struct. - /// * `output` - An object implementing Write trait where the closure will be written. - /// * `eof` - A boolean value, if true, indicates that this is the last element to write to the output. - /// - /// # Returns - /// - /// * `Result<()>` - A generic Result type indicating the operations outcome. fn write_closure(&mut self, output: &mut dyn Write, eof: bool) -> Result<()>; } diff --git a/src/builder/json_file_builder.rs b/src/builder/json_file_builder.rs index 1010fed..969e33f 100644 --- a/src/builder/json_file_builder.rs +++ b/src/builder/json_file_builder.rs @@ -1,27 +1,22 @@ -use super::FileBuilder; - -use serde::Serialize; - use std::collections::BTreeMap; use std::io::{Result, Write}; -/// Represents a JSON offset value with an optional comment. +use serde::Serialize; + +use super::FileBuilder; + #[derive(Clone, Debug, Default, PartialEq, Serialize)] struct JsonOffsetValue { value: usize, comment: Option, } -/// Represents a JSON module, which contains data in the form of a `BTreeMap` of string keys and -/// `JsonOffsetValue` values, as well as an optional comment. #[derive(Clone, Debug, Default, PartialEq, Serialize)] struct JsonModule { data: BTreeMap, comment: Option, } -/// A structure representing a builder for JSON files. -/// The builder implements the `FileBuilder` trait. #[derive(Clone, Debug, Default, PartialEq)] pub struct JsonFileBuilder { data: BTreeMap, diff --git a/src/builder/mod.rs b/src/builder/mod.rs index 3dd999f..7c5ed90 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -6,7 +6,7 @@ pub use python_file_builder::PythonFileBuilder; pub use rust_file_builder::RustFileBuilder; pub use yaml_file_builder::YamlFileBuilder; -pub use std::io::{Result, Write}; +use std::io::{Result, Write}; pub mod cpp_file_builder; pub mod csharp_file_builder; @@ -16,26 +16,13 @@ pub mod python_file_builder; pub mod rust_file_builder; pub mod yaml_file_builder; -/// `FileBuilder` is an enum that defines different kinds of file builders. -/// Each variant corresponds to a builder for a particular type of file. #[derive(Clone, Debug, PartialEq)] pub enum FileBuilderEnum { - /// Represents a builder for C++ header files. CppFileBuilder(CppFileBuilder), - - /// Represents a builder for C# files. CSharpFileBuilder(CSharpFileBuilder), - - /// Represents a builder for JSON files. JsonFileBuilder(JsonFileBuilder), - - /// Represents a builder for Python files. PythonFileBuilder(PythonFileBuilder), - - /// Represents a builder for Rust files. RustFileBuilder(RustFileBuilder), - - /// Represents a builder for YAML files. YamlFileBuilder(YamlFileBuilder), } diff --git a/src/builder/python_file_builder.rs b/src/builder/python_file_builder.rs index 9e85e90..13d130c 100644 --- a/src/builder/python_file_builder.rs +++ b/src/builder/python_file_builder.rs @@ -1,9 +1,7 @@ -use super::FileBuilder; - use std::io::{Result, Write}; -/// A structure representing a builder for Python files. -/// The builder implements the `FileBuilder` trait. +use super::FileBuilder; + #[derive(Clone, Debug, PartialEq)] pub struct PythonFileBuilder; diff --git a/src/builder/rust_file_builder.rs b/src/builder/rust_file_builder.rs index f6cf2a9..cdf27e0 100644 --- a/src/builder/rust_file_builder.rs +++ b/src/builder/rust_file_builder.rs @@ -2,8 +2,6 @@ use super::FileBuilder; use std::io::{Result, Write}; -/// A structure representing a builder for Rust files. -/// The builder implements the `FileBuilder` trait. #[derive(Clone, Debug, Default, PartialEq)] pub struct RustFileBuilder; diff --git a/src/builder/yaml_file_builder.rs b/src/builder/yaml_file_builder.rs index 27eb34f..6604d81 100644 --- a/src/builder/yaml_file_builder.rs +++ b/src/builder/yaml_file_builder.rs @@ -1,9 +1,7 @@ -use super::FileBuilder; - use std::io::{Result, Write}; -/// A structure representing a builder for Yaml files. -/// The builder implements the `FileBuilder` trait. +use super::FileBuilder; + #[derive(Clone, Debug, Default, PartialEq)] pub struct YamlFileBuilder; diff --git a/src/config.rs b/src/config.rs index 31d5625..f8a56c4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,72 +1,41 @@ use serde::{Deserialize, Serialize}; -/// Represents an operation that can be performed on a memory address. #[derive(Debug, Deserialize, Serialize)] #[serde(tag = "type", rename_all = "camelCase")] pub enum Operation { - /// Represents an `add` operation. - /// - /// `value` is the value to add. - Add { value: usize }, - - /// Represents a `dereference` operation. - /// - /// `times` is the number of times to dereference the address. If `None`, the number of times will be `1`. - /// `size` is the size of the resulting value. If `None`, the size will be `8`. + Add { + value: usize, + }, Deref { times: Option, size: Option, }, - - /// Represents an operation to resolve the absolute address of a relative call. - /// - /// `offset` is the offset of the displacement value. If `None`, the offset will be `0x1`. - /// `length` is the length of the instruction. If `None`, the length will be `0x5`. Jmp { offset: Option, length: Option, }, - - /// Represents an operation to resolve the absolute address of a RIP-relative address. - /// - /// `offset` is the offset of the displacement value. If `None`, the offset will be `0x3`. - /// `length` is the length of the instruction. If `None`, the length will be `0x7`. Rip { offset: Option, length: Option, }, - - /// Represents a `slice` operation. - /// - /// `start` is the start index of the slice. - /// `end` is the end index of the slice. - Slice { start: usize, end: usize }, - - /// Represents a `subtract` operation. - /// - /// `value` is the value to subtract. - Sub { value: usize }, + Slice { + start: usize, + end: usize, + }, + Sub { + value: usize, + }, } -/// Represents a signature specified in the `config.json` file. #[derive(Debug, Deserialize, Serialize)] pub struct Signature { - /// The name of the signature. pub name: String, - - /// The name of the module. pub module: String, - - /// The pattern of the signature. pub pattern: String, - - /// The list of operations to perform on the target address. pub operations: Vec, } -/// Represents the `config.json` file. #[derive(Debug, Deserialize, Serialize)] pub struct Config { - /// The list of signatures specified in the `config.json` file. pub signatures: Vec, } diff --git a/src/dumper/interfaces.rs b/src/dumper/interfaces.rs index 1abca17..0c64dec 100644 --- a/src/dumper/interfaces.rs +++ b/src/dumper/interfaces.rs @@ -1,40 +1,24 @@ -use super::{generate_files, Entries, Entry}; - -use crate::builder::FileBuilderEnum; -use crate::util::{Address, Process}; +use std::ffi::c_char; +use std::mem::offset_of; use anyhow::Result; use simplelog::{debug, info}; -use std::ffi::c_char; -use std::mem::offset_of; +use super::{generate_files, Entries, Entry}; + +use crate::builder::FileBuilderEnum; +use crate::util::{Address, Process}; -/// Represents a node in a linked list of interfaces. #[derive(Debug)] #[repr(C)] struct InterfaceNode { - /// Used to instantiate an instance of the interface. pub create_fn: *const (), - - /// Pointer to the name of the interface. pub name: *const c_char, - - /// Pointer to the next entry in the linked list. pub next: *mut InterfaceNode, } impl InterfaceNode { - /// Returns the instance of the interface. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `InterfaceNode` struct. - /// * `process` - A reference to the `Process` struct. - /// - /// # Returns - /// - /// * `Result
` - A `Result` containing the instance of the interface if successful, or an error if the memory read fails. fn instance(&self, process: &Process) -> Result
{ process .read_memory::( @@ -43,18 +27,6 @@ impl InterfaceNode { .map(|ptr| ptr.into()) } - /// Returns the name of the interface with the version number appended. - /// - /// E.g. "Source2Client002". - /// - /// # Arguments - /// - /// * `&self` - A reference to the `InterfaceNode` struct. - /// * `process` - A reference to the `Process` struct. - /// - /// # Returns - /// - /// * `Result` - A `Result` containing the name of the interface if successful, or an error if the memory read fails. fn name(&self, process: &Process) -> Result { let name_ptr = process.read_memory::( (self as *const _ as usize + offset_of!(InterfaceNode, name)).into(), @@ -63,16 +35,6 @@ impl InterfaceNode { process.read_string(name_ptr.into()) } - /// Returns a pointer to the next `InterfaceNode` in the linked list. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `InterfaceNode` struct. - /// * `process` - A reference to the `Process` struct. - /// - /// # Returns - /// - /// * `Result<*mut InterfaceNode>` - A `Result` containing a pointer to the next `InterfaceNode` if successful, or an error if the memory read fails. fn next(&self, process: &Process) -> Result<*mut InterfaceNode> { process.read_memory::<*mut InterfaceNode>( (self as *const _ as usize + offset_of!(InterfaceNode, next)).into(), @@ -80,18 +42,6 @@ impl InterfaceNode { } } -/// Dumps all interfaces and writes the results to a file. -/// -/// # Arguments -/// -/// * `process` - A reference to the `Process` struct. -/// * `builders` - A mutable reference to a vector of `FileBuilderEnum`. -/// * `file_path` - A string slice representing the path to the file to write the results to. -/// * `indent` - The number of spaces to use for indentation in the output file. -/// -/// # Returns -/// -/// * `Result<()>` - A `Result` indicating the outcome of the operation. pub fn dump_interfaces( process: &Process, builders: &mut Vec, @@ -100,13 +50,12 @@ pub fn dump_interfaces( ) -> Result<()> { let mut entries = Entries::new(); - // Iterate over all modules in the process, excluding crashhandler64.dll. for module in process .modules()? .iter() .filter(|m| m.name != "crashhandler64.dll") { - if let Some(create_interface_export) = module.get_export_by_name("CreateInterface") { + if let Some(create_interface_export) = module.export_by_name("CreateInterface") { info!("Dumping interfaces in {}...", module.name); let create_interface_address = @@ -114,7 +63,6 @@ pub fn dump_interfaces( let mut node = process.read_memory::<*mut InterfaceNode>(create_interface_address)?; - // Iterate over each node in the linked list. while !node.is_null() { let instance = unsafe { (*node).instance(process) }?; let name = unsafe { (*node).name(process) }?; @@ -138,7 +86,6 @@ pub fn dump_interfaces( indent: Some(indent), }); - // Get the next node in the linked list. node = unsafe { (*node).next(process) }?; } } diff --git a/src/dumper/mod.rs b/src/dumper/mod.rs index 90f8099..dcd1484 100644 --- a/src/dumper/mod.rs +++ b/src/dumper/mod.rs @@ -1,9 +1,3 @@ -use crate::builder::{FileBuilder, FileBuilderEnum}; - -use anyhow::Result; - -use chrono::Utc; - pub use interfaces::dump_interfaces; pub use offsets::dump_offsets; pub use schemas::dump_schemas; @@ -12,51 +6,32 @@ use std::collections::BTreeMap; use std::fs::File; use std::io::Write; +use anyhow::Result; + +use chrono::Utc; + +use crate::builder::{FileBuilder, FileBuilderEnum}; + pub mod interfaces; pub mod offsets; pub mod schemas; -/// Represents an entry in the generated file. #[derive(Debug, PartialEq)] pub struct Entry { - /// The name of the entry. pub name: String, - - /// The value of the entry. pub value: usize, - - /// An optional comment associated with the entry. pub comment: Option, - - /// An optional indentation level for the entry. pub indent: Option, } -/// A container for entries, which consists of data and an optional comment. #[derive(Default)] pub struct EntriesContainer { - /// The data associated with the container. pub data: Vec, - - /// An optional comment associated with the container. pub comment: Option, } -/// A type alias for a `BTreeMap` that maps `String` keys to `EntriesContainer` values. pub type Entries = BTreeMap; -/// Generates a file using the given `builder`, `entries`, `file_path`, and `file_name`. -/// -/// # Arguments -/// -/// * `builder` - A mutable reference to the `FileBuilderEnum`. -/// * `entries` - A reference to the `Entries` struct. -/// * `file_path` - A string slice representing the path to the file. -/// * `file_name` - A string slice representing the name of the file. -/// -/// # Returns -/// -/// * `Result<()>` - A `Result` indicating the outcome of the operation. pub fn generate_file( builder: &mut FileBuilderEnum, entries: &Entries, @@ -96,18 +71,6 @@ pub fn generate_file( Ok(()) } -/// Generate files using the given `builders`, `entries`, `file_path`, and `file_name`. -/// -/// # Arguments -/// -/// * `builders` - A mutable slice of `FileBuilderEnum` objects. -/// * `entries` - A reference to the `Entries` struct. -/// * `file_path` - A string slice representing the path to the file. -/// * `file_name` - A string slice representing the name of the file. -/// -/// # Returns -/// -/// * `Result<()>` - A `Result` indicating the outcome of the operation. pub fn generate_files( builders: &mut [FileBuilderEnum], entries: &Entries, @@ -119,16 +82,6 @@ pub fn generate_files( .try_for_each(|builder| generate_file(builder, entries, file_path, file_name)) } -/// Writes the banner to the given file based on the file extension. -/// -/// # Arguments -/// -/// * `file` - A mutable reference to the file to write the banner to. -/// * `file_extension` - A string slice representing the file extension of the file. -/// -/// # Returns -/// -/// * `Result<()>` - A `Result` indicating the outcome of the operation. fn write_banner_to_file(file: &mut File, file_extension: &str) -> Result<()> { const REPO_URL: &str = "https://github.com/a2x/cs2-dumper"; @@ -137,12 +90,12 @@ fn write_banner_to_file(file: &mut File, file_extension: &str) -> Result<()> { let banner = match file_extension { "json" => None, "py" => Some(format!( - "'''\nCreated using {}\n{}\n'''\n\n", + "'''\nGenerated using {}\n{}\n'''\n\n", REPO_URL, time_now )), "yaml" => None, _ => Some(format!( - "/*\n * Created using {}\n * {}\n */\n\n", + "/*\n * Generated using {}\n * {}\n */\n\n", REPO_URL, time_now )), }; diff --git a/src/dumper/offsets.rs b/src/dumper/offsets.rs index d5810d1..1907cc1 100644 --- a/src/dumper/offsets.rs +++ b/src/dumper/offsets.rs @@ -1,3 +1,9 @@ +use std::fs::File; + +use anyhow::Result; + +use simplelog::{debug, error, info}; + use super::{generate_files, Entries, Entry}; use crate::builder::FileBuilderEnum; @@ -5,24 +11,6 @@ use crate::config::Config; use crate::config::Operation::*; use crate::util::Process; -use anyhow::Result; - -use simplelog::{debug, error, info}; - -use std::fs::File; - -/// Dumps all offsets specified in the `config.json` file and writes the results to a file. -/// -/// # Arguments -/// -/// * `process` - A reference to the `Process` struct. -/// * `builders` - A mutable reference to a vector of `FileBuilderEnum`. -/// * `file_path` - A string slice representing the path to the file to write the results to. -/// * `indent` - The number of spaces to use for indentation in the output file. -/// -/// # Returns -/// -/// * `Result<()>` - A `Result` indicating the outcome of the operation. pub fn dump_offsets( process: &Process, builders: &mut Vec, diff --git a/src/dumper/schemas.rs b/src/dumper/schemas.rs index 7f94ee2..54e690e 100644 --- a/src/dumper/schemas.rs +++ b/src/dumper/schemas.rs @@ -1,25 +1,13 @@ +use anyhow::Result; + +use simplelog::{debug, info}; + use super::{generate_files, Entries, Entry}; use crate::builder::FileBuilderEnum; use crate::sdk::SchemaSystem; use crate::util::Process; -use anyhow::Result; - -use simplelog::{debug, info}; - -/// Dumps all schema system classes and writes the results to a file. -/// -/// # Arguments -/// -/// * `process` - A reference to the `Process` struct. -/// * `builders` - A mutable reference to a vector of `FileBuilderEnum`. -/// * `file_path` - A string slice representing the path to the file to write the results to. -/// * `indent` - The number of spaces to use for indentation in the output file. -/// -/// # Returns -/// -/// * `Result<()>` - A `Result` indicating the outcome of the operation. pub fn dump_schemas( process: &Process, builders: &mut Vec, diff --git a/src/main.rs b/src/main.rs index 0c484ae..3a57b5a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,21 +1,19 @@ #![allow(dead_code)] -use anyhow::{bail, Result}; - -use builder::*; - -use clap::Parser; - -use dumper::{dump_interfaces, dump_offsets, dump_schemas}; - -use log::LevelFilter; - -use simplelog::{info, ColorChoice, ConfigBuilder, TermLogger, TerminalMode}; - use std::fs; use std::path::Path; use std::time::Instant; +use anyhow::{bail, Result}; + +use clap::Parser; + +use log::LevelFilter; + +use simplelog::{info, ColorChoice, ConfigBuilder, TermLogger, TerminalMode}; + +use builder::*; +use dumper::{dump_interfaces, dump_offsets, dump_schemas}; use util::Process; mod builder; @@ -24,21 +22,20 @@ mod dumper; mod sdk; mod util; -/// Command line arguments for the program. #[derive(Debug, Parser)] #[command(name = "cs2-dumper")] #[command(author = "a2x")] #[command(version = "1.1.5")] struct Args { - /// Dump interfaces. + /// Whether to dump interfaces. #[arg(short, long)] interfaces: bool, - /// Dump offsets. + /// Whether to dump offsets. #[arg(short, long)] offsets: bool, - /// Dump schema system classes. + /// Whether to dump schema classes. #[arg(short, long)] schemas: bool, @@ -47,7 +44,7 @@ struct Args { #[arg( short, long, - value_parser = parse_extension, + value_parser = map_file_extension_to_builder, value_delimiter = ',', default_values = [".cs", ".hpp", ".json", ".py", ".rs", ".yaml"], )] @@ -89,7 +86,6 @@ fn main() -> Result<()> { TermLogger::init(log_level, config, TerminalMode::Mixed, ColorChoice::Auto)?; - // Check if the config file exists. if !Path::new("config.json").exists() { bail!("Missing config.json file"); } @@ -97,12 +93,8 @@ fn main() -> Result<()> { // Create the output directory if it doesn't exist. fs::create_dir_all(&output)?; - // Open a handle to the game process. let mut process = Process::new("cs2.exe")?; - process.initialize()?; - - // Start the timer. let now = Instant::now(); let all = !(interfaces || offsets || schemas); @@ -119,7 +111,6 @@ fn main() -> Result<()> { dump_offsets(&mut process, &mut builders, &output, indent)?; } - // Stop the timer. info!( "Done! Time elapsed: {:?}", now.elapsed() @@ -128,18 +119,8 @@ fn main() -> Result<()> { Ok(()) } -/// Parses the given file extension and returns the corresponding `FileBuilderEnum`. -/// -/// # Arguments -/// -/// * `extension` - A string slice that represents the file extension. -/// -/// # Returns -/// -/// * `Ok(FileBuilderEnum)` - If the extension is valid, returns the corresponding `FileBuilderEnum`. -/// * `Err(&'static str)` - If the extension is invalid, returns an error message. -fn parse_extension(extension: &str) -> Result { - match extension { +fn map_file_extension_to_builder(ext: &str) -> Result { + match ext { ".cs" => Ok(FileBuilderEnum::CSharpFileBuilder(CSharpFileBuilder)), ".hpp" => Ok(FileBuilderEnum::CppFileBuilder(CppFileBuilder)), ".json" => Ok(FileBuilderEnum::JsonFileBuilder(JsonFileBuilder::default())), diff --git a/src/sdk/schema_class_field_data.rs b/src/sdk/schema_class_field_data.rs index efed0ac..d3acac1 100644 --- a/src/sdk/schema_class_field_data.rs +++ b/src/sdk/schema_class_field_data.rs @@ -1,54 +1,25 @@ +use anyhow::Result; + use super::SchemaType; use crate::util::{Address, Process}; -use anyhow::Result; - -/// Represents data for a field in a schema class. pub struct SchemaClassFieldData<'a> { process: &'a Process, address: Address, } impl<'a> SchemaClassFieldData<'a> { - /// Creates a new `SchemaClassFieldData` instance. - /// - /// # Arguments - /// - /// * `process` - A reference to the `Process` struct. - /// * `address` - The address of the `SchemaClassFieldData` instance. - /// - /// # Returns - /// - /// * `SchemaClassFieldData` - The new `SchemaClassFieldData` instance. pub fn new(process: &'a Process, address: Address) -> Self { Self { process, address } } - /// Returns the name of the field. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `SchemaClassFieldData` struct. - /// - /// # Returns - /// - /// * `Result` - The name of the field. pub fn name(&self) -> Result { let name_ptr = self.process.read_memory::(self.address)?; self.process.read_string_length(name_ptr.into(), 64) } - /// Returns the `SchemaType` of the field. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `SchemaClassFieldData` struct. - /// - /// # Returns - /// - /// * `Result` - The `SchemaType` of the field. pub fn r#type(&self) -> Result { Ok(SchemaType::new( self.process, @@ -58,15 +29,6 @@ impl<'a> SchemaClassFieldData<'a> { )) } - /// Returns the offset of the field. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `SchemaClassFieldData` struct. - /// - /// # Returns - /// - /// * `Result` - The offset of the field. pub fn offset(&self) -> Result { self.process.read_memory::(self.address + 0x10) } diff --git a/src/sdk/schema_class_info.rs b/src/sdk/schema_class_info.rs index 4d63e4e..7678b14 100644 --- a/src/sdk/schema_class_info.rs +++ b/src/sdk/schema_class_info.rs @@ -1,10 +1,9 @@ +use anyhow::Result; + use super::SchemaClassFieldData; use crate::util::{Address, Process}; -use anyhow::Result; - -/// Represents information about a schema class. pub struct SchemaClassInfo<'a> { process: &'a Process, address: Address, @@ -12,17 +11,6 @@ pub struct SchemaClassInfo<'a> { } impl<'a> SchemaClassInfo<'a> { - /// Creates a new `SchemaClassInfo` instance. - /// - /// # Arguments - /// - /// * `process` - A reference to the `Process` struct. - /// * `address` - The address of the `SchemaClassInfo` instance. - /// * `class_name` - The name of the class. - /// - /// # Returns - /// - /// * `SchemaClassInfo` - The new `SchemaClassInfo` instance. pub fn new(process: &'a Process, address: Address, class_name: &str) -> Self { Self { process, @@ -31,30 +19,11 @@ impl<'a> SchemaClassInfo<'a> { } } - /// Returns a reference to the name of the class. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `SchemaClassInfo` struct. - /// - /// # Returns - /// - /// * `&str` - A string slice containing the name of the class. #[inline] pub fn name(&self) -> &str { &self.class_name } - /// Returns a vector of `SchemaClassFieldData` representing the fields of the schema class. - /// If the address of the schema class is null, an empty vector is returned. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `SchemaClassInfo` struct. - /// - /// # Returns - /// - /// * `Result>` - A vector of `SchemaClassFieldData` representing the fields of the schema class. pub fn fields(&self) -> Result> { let address = self.process.read_memory::(self.address + 0x28)?; @@ -72,29 +41,10 @@ impl<'a> SchemaClassInfo<'a> { Ok(fields) } - /// Returns the number of fields in the class. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `SchemaClassInfo` struct. - /// - /// # Returns - /// - /// * `Result` - The number of fields in the class. pub fn fields_count(&self) -> Result { self.process.read_memory::(self.address + 0x1C) } - /// Returns the parent `SchemaClassInfo` of the current `SchemaClassInfo` instance. - /// If the parent is not found, returns `Ok(None)`. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `SchemaClassInfo` struct. - /// - /// # Returns - /// - /// * `Result>` - The parent `SchemaClassInfo` of the current `SchemaClassInfo` instance. pub fn parent(&self) -> Result> { let address = Address::from(self.process.read_memory::(self.address + 0x38)?); diff --git a/src/sdk/schema_system.rs b/src/sdk/schema_system.rs index fa34d0e..f57481a 100644 --- a/src/sdk/schema_system.rs +++ b/src/sdk/schema_system.rs @@ -1,27 +1,17 @@ +use std::mem; + +use anyhow::{bail, Result}; + use super::SchemaSystemTypeScope; use crate::util::{Address, Process}; -use anyhow::{bail, Result}; - -use std::mem; - -/// Represents the schema system. pub struct SchemaSystem<'a> { process: &'a Process, address: Address, } impl<'a> SchemaSystem<'a> { - /// Creates a new `SchemaSystem` instance. - /// - /// # Arguments - /// - /// * `process` - A reference to the `Process` struct. - /// - /// # Returns - /// - /// * `Result` - The new `SchemaSystem` instance. pub fn new(process: &'a Process) -> Result { let mut address = process.find_pattern( "schemasystem.dll", @@ -33,15 +23,6 @@ impl<'a> SchemaSystem<'a> { Ok(Self { process, address }) } - /// Returns a vector of `SchemaSystemTypeScope` objects. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `SchemaSystem` struct. - /// - /// # Returns - /// - /// * `Result>` - A vector of `SchemaSystemTypeScope` objects. pub fn type_scopes(&self) -> Result> { let size = self.process.read_memory::(self.address + 0x190)?; diff --git a/src/sdk/schema_system_type_scope.rs b/src/sdk/schema_system_type_scope.rs index 250c3e3..73e71e9 100644 --- a/src/sdk/schema_system_type_scope.rs +++ b/src/sdk/schema_system_type_scope.rs @@ -1,40 +1,19 @@ +use anyhow::Result; + use super::{SchemaClassInfo, SchemaTypeDeclaredClass, UtlTsHash}; use crate::util::{Address, Process}; -use anyhow::Result; - -/// Represents a system type scope in the schema. pub struct SchemaSystemTypeScope<'a> { process: &'a Process, address: Address, } impl<'a> SchemaSystemTypeScope<'a> { - /// Creates a new `SchemaSystemTypeScope` instance. - /// - /// # Arguments - /// - /// * `process` - A reference to the `Process` struct. - /// * `address` - The address of the `SchemaSystemTypeScope` instance. - /// * `class_name` - The name of the class. - /// - /// # Returns - /// - /// * `SchemaSystemTypeScope` - The new `SchemaSystemTypeScope` instance. pub fn new(process: &'a Process, address: Address) -> Self { Self { process, address } } - /// Returns a vector of `SchemaClassInfo` containing information about all the classes declared in the current scope. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `SchemaSystemTypeScope` struct. - /// - /// # Returns - /// - /// * `Result>` - A vector of `SchemaClassInfo` containing information about all the classes declared in the current scope. pub fn classes(&self) -> Result> { let declared_classes = self .process @@ -58,15 +37,6 @@ impl<'a> SchemaSystemTypeScope<'a> { Ok(classes) } - /// Returns the name of the module associated with the current `SchemaSystemTypeScope` instance. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `SchemaSystemTypeScope` struct. - /// - /// # Returns - /// - /// * `Result` - The name of the module associated with the current `SchemaSystemTypeScope` instance. pub fn module_name(&self) -> Result { self.process.read_string_length(self.address + 0x8, 256) } diff --git a/src/sdk/schema_type.rs b/src/sdk/schema_type.rs index 040981a..aa5f1fd 100644 --- a/src/sdk/schema_type.rs +++ b/src/sdk/schema_type.rs @@ -1,4 +1,4 @@ -use crate::util::{Address, Process}; +use std::collections::HashMap; use anyhow::Result; @@ -6,9 +6,8 @@ use lazy_static::lazy_static; use regex::Regex; -use std::collections::HashMap; +use crate::util::{Address, Process}; -/// Map of type names to their `C` equivalents. const TYPE_MAP: &[(&'static str, &'static str)] = &[ ("uint8", "uint8_t"), ("uint16", "uint16_t"), @@ -23,8 +22,6 @@ const TYPE_MAP: &[(&'static str, &'static str)] = &[ ]; lazy_static! { - /// A static HashMap that maps a string to a Regex pattern. - /// The Regex pattern is created by wrapping the string with word boundaries `(\b)`. static ref REGEX_MAP: HashMap<&'static str, Regex> = { let mut map = HashMap::with_capacity(TYPE_MAP.len()); @@ -36,36 +33,16 @@ lazy_static! { }; } -/// Represents a type in the schema. pub struct SchemaType<'a> { process: &'a Process, address: Address, } impl<'a> SchemaType<'a> { - /// Creates a new `SchemaType` instance. - /// - /// # Arguments - /// - /// * `process` - A reference to the `Process` struct. - /// * `address` - The address of the `SchemaType` instance. - /// - /// # Returns - /// - /// * `SchemaType` - The new `SchemaType` instance. pub fn new(process: &'a Process, address: Address) -> Self { Self { process, address } } - /// Returns the name of the schema type. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `SchemaType` instance. - /// - /// # Returns - /// - /// * `Result` - The name of the schema type, wrapped in a `Result` object. pub fn name(&self) -> Result { let name_ptr = self.process.read_memory::(self.address + 0x8)?; @@ -78,15 +55,6 @@ impl<'a> SchemaType<'a> { Ok(Self::convert_type_name(&name)) } - /// Converts a schema type name to its `C` equivalent. - /// - /// # Arguments - /// - /// * `type_name` - A string slice that holds the name of the schema type. - /// - /// # Returns - /// - /// * `String` - The `C` equivalent of the schema type name. fn convert_type_name(type_name: &str) -> String { let mut result = type_name.to_string(); diff --git a/src/sdk/schema_type_declared_class.rs b/src/sdk/schema_type_declared_class.rs index a50d0d2..9b74172 100644 --- a/src/sdk/schema_type_declared_class.rs +++ b/src/sdk/schema_type_declared_class.rs @@ -1,37 +1,17 @@ -use crate::util::{Address, Process}; - use anyhow::Result; -/// Represents a declared class type in the schema. +use crate::util::{Address, Process}; + pub struct SchemaTypeDeclaredClass<'a> { process: &'a Process, address: Address, } impl<'a> SchemaTypeDeclaredClass<'a> { - /// Creates a new `SchemaTypeDeclaredClass` instance. - /// - /// # Arguments - /// - /// * `process` - A reference to the `Process` struct. - /// * `address` - The address of the `SchemaTypeDeclaredClass` instance. - /// - /// # Returns - /// - /// * `SchemaTypeDeclaredClass` - The new `SchemaTypeDeclaredClass` instance. pub fn new(process: &'a Process, address: Address) -> Self { Self { process, address } } - /// Returns the name of the declared class. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `SchemaTypeDeclaredClass` struct. - /// - /// # Returns - /// - /// * `Result` - The name of the declared class. pub fn name(&self) -> Result { let name_ptr = self.process.read_memory::(self.address + 0x8)?; diff --git a/src/sdk/utl_ts_hash.rs b/src/sdk/utl_ts_hash.rs index 14b1ccd..43f0b25 100644 --- a/src/sdk/utl_ts_hash.rs +++ b/src/sdk/utl_ts_hash.rs @@ -1,10 +1,9 @@ -use crate::util::Process; +use std::mem::offset_of; use anyhow::Result; -use std::mem::offset_of; +use crate::util::Process; -/// Represents the internal data of a hash table. #[derive(Debug)] #[repr(C)] struct HashFixedDataInternal { @@ -13,17 +12,7 @@ struct HashFixedDataInternal { data: T, // 0x0010 } -/// Implementation of HashFixedDataInternal struct with methods for reading the next element in the hash table. impl HashFixedDataInternal { - /// Reads the next element in the hash table. - /// - /// # Arguments - /// - /// * `process` - A reference to the `Process` struct. - /// - /// # Returns - /// - /// Returns a Result containing a pointer to the next element in the hash table if successful, or an error if unsuccessful. fn next(&self, process: &Process) -> Result<*mut HashFixedDataInternal> { process.read_memory::<*mut HashFixedDataInternal>( (self as *const _ as usize + offset_of!(HashFixedDataInternal, next)).into(), @@ -31,7 +20,6 @@ impl HashFixedDataInternal { } } -/// Represents the internal data of a hash bucket. #[derive(Debug)] #[repr(C)] struct HashBucketDataInternal { @@ -41,15 +29,6 @@ struct HashBucketDataInternal { } impl HashBucketDataInternal { - /// Reads the next element in the hash table. - /// - /// # Arguments - /// - /// * `process` - A reference to the `Process` struct. - /// - /// # Returns - /// - /// Returns a Result containing a pointer to the next element in the hash table if successful, or an error if unsuccessful. fn next(&self, process: &Process) -> Result<*mut HashFixedDataInternal> { process.read_memory::<*mut HashFixedDataInternal>( (self as *const _ as usize + offset_of!(HashBucketDataInternal, next)).into(), @@ -57,7 +36,6 @@ impl HashBucketDataInternal { } } -/// Represents allocated data in a hash table. #[derive(Debug)] #[repr(C)] pub struct HashAllocatedData { @@ -66,15 +44,6 @@ pub struct HashAllocatedData { } impl HashAllocatedData { - /// Reads the list of elements in the hash table. - /// - /// # Arguments - /// - /// * `process` - A reference to the `Process` struct. - /// - /// # Returns - /// - /// Returns a Result containing a list of elements in the hash table if successful, or an error if unsuccessful. fn list(&self, process: &Process) -> Result<[HashFixedDataInternal; 128]> { process.read_memory::<[HashFixedDataInternal; 128]>( (self as *const _ as usize + offset_of!(HashAllocatedData, list)).into(), @@ -82,7 +51,6 @@ impl HashAllocatedData { } } -/// A struct representing unallocated data in a hash table. #[derive(Debug)] #[repr(C)] struct HashUnallocatedData { @@ -94,45 +62,18 @@ struct HashUnallocatedData { } impl HashUnallocatedData { - /// Reads the next `HashUnallocatedData` element in memory. - /// - /// # Arguments - /// - /// * `process` - A reference to the `Process` struct. - /// - /// # Returns - /// - /// * `Result<*mut HashUnallocatedData>` - A Result containing a pointer to the next `HashUnallocatedData` element in memory. fn next(&self, process: &Process) -> Result<*mut HashUnallocatedData> { process.read_memory::<*mut HashUnallocatedData>( (self as *const _ as usize + offset_of!(HashUnallocatedData, next)).into(), ) } - /// Reads the UI key of the `HashUnallocatedData` element in memory. - /// - /// # Arguments - /// - /// * `process` - A reference to the `Process` struct. - /// - /// # Returns - /// - /// * `Result` - A Result containing the UI key of the `HashUnallocatedData` element in memory. fn ui_key(&self, process: &Process) -> Result { process.read_memory::( (self as *const _ as usize + offset_of!(HashUnallocatedData, ui_key)).into(), ) } - /// Reads the block list of the `HashUnallocatedData` element in memory. - /// - /// # Arguments - /// - /// * `process` - A reference to the `Process` struct. - /// - /// # Returns - /// - /// * `Result<[HashBucketDataInternal; 256]>` - A Result containing the block list of the `HashUnallocatedData` element in memory. fn block_list(&self, process: &Process) -> Result<[HashBucketDataInternal; 256]> { process.read_memory::<[HashBucketDataInternal; 256]>( (self as *const _ as usize + offset_of!(HashUnallocatedData, block_list)).into(), @@ -140,7 +81,6 @@ impl HashUnallocatedData { } } -/// Represents a hash bucket. #[derive(Debug)] #[repr(C)] struct HashBucket { @@ -149,7 +89,6 @@ struct HashBucket { unallocated_data: *const HashUnallocatedData, // 0x0018 } -/// Represents a memory pool used by the `UtlTsHash` class. #[derive(Debug)] #[repr(C)] struct UtlMemoryPool { @@ -162,36 +101,17 @@ struct UtlMemoryPool { } impl UtlMemoryPool { - /// Returns the number of blocks per blob. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `UtlMemoryPool` struct. - /// - /// # Returns - /// - /// * `i32` - The number of blocks per blob. #[inline] fn block_size(&self) -> i32 { self.blocks_per_blob } - /// Returns the number of blocks allocated. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `UtlMemoryPool` struct. - /// - /// # Returns - /// - /// * `i32` - The number of blocks allocated. #[inline] fn count(&self) -> i32 { self.block_allocated_size } } -/// Represents a thread-safe hash table. #[derive(Debug)] #[repr(C)] pub struct UtlTsHash { @@ -203,43 +123,16 @@ impl UtlTsHash where T: Copy, { - /// Returns the number of blocks per blob. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `UtlTsHash` struct. - /// - /// # Returns - /// - /// * `i32` - The number of blocks per blob. #[inline] pub fn block_size(&self) -> i32 { self.entry_memory.block_size() } - /// Returns the number of blocks allocated. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `UtlTsHash` struct. - /// - /// # Returns - /// - /// * `i32` - The number of blocks allocated. #[inline] pub fn count(&self) -> i32 { self.entry_memory.count() } - /// Returns a list of elements in the hash table. - /// - /// # Arguments - /// - /// * `process` - A reference to the `Process` struct. - /// - /// # Returns - /// - /// * `Result>` - A Result containing a list of elements in the hash table if successful, or an error if unsuccessful. pub fn elements(&self, process: &Process) -> Result> { let mut address = self.buckets.unallocated_data; diff --git a/src/util/address.rs b/src/util/address.rs index 3ddd41c..4ea288a 100644 --- a/src/util/address.rs +++ b/src/util/address.rs @@ -1,210 +1,136 @@ use std::fmt::{LowerHex, UpperHex}; use std::ops::{Add, AddAssign, Sub, SubAssign}; -/// Represents a memory address. #[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd)] #[repr(transparent)] pub struct Address(pub usize); impl Address { - /// Adds the given value to the current address and returns a new `Address`. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Address` struct. - /// * `value` - The value to add to the current address. - /// - /// # Returns - /// - /// * `Address` - A new `Address` struct with the value of the current address plus the given value. #[inline] pub fn add(&self, value: usize) -> Self { Self(self.0 + value) } - /// Returns true if the value of the address is zero. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Address` struct. - /// - /// # Returns - /// - /// * `bool` - True if the value of the address is zero, false otherwise. #[inline] pub fn is_zero(&self) -> bool { self.0 == 0 } - /// Subtracts a value from the current address and returns a new `Address`. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Address` struct. - /// * `value` - The value to subtract from the current address. - /// - /// # Returns - /// - /// * `Address` - A new `Address` struct with the value of the current address minus the given value. #[inline] pub fn sub(&self, value: usize) -> Self { Self(self.0 - value) } - /// Returns a raw pointer to the underlying data as a `*const T`. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Address` struct. - /// - /// # Returns - /// - /// * `*const T` - A raw pointer to the underlying data as a `*const T`. #[inline] pub fn as_ptr(&self) -> *const T { self.0 as *const T } - /// Returns a mutable pointer to the underlying data. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Address` struct. - /// - /// # Returns - /// - /// * `*mut T` - A mutable pointer to the underlying data. #[inline] pub fn as_mut_ptr(&self) -> *mut T { self.0 as *mut T } } -/// Converts a `usize` value to an `Address` struct. impl From for Address { fn from(value: usize) -> Self { Self(value) } } -/// Converts a raw pointer to a `usize` value and creates an `Address` instance from it. impl From<*const u8> for Address { fn from(value: *const u8) -> Self { Self(value as usize) } } -/// Converts a raw pointer to a `usize` value and wraps it in an `Address` struct. impl From<*mut u8> for Address { fn from(value: *mut u8) -> Self { Self(value as usize) } } -/// Converts an `Address` struct to a `usize` value. impl From
for usize { fn from(value: Address) -> Self { value.0 } } -/// Converts an `Address` struct to a raw pointer to an unsigned 8-bit integer. impl From
for *const u8 { fn from(value: Address) -> Self { value.0 as *const u8 } } -/// Converts an `Address` struct to a raw pointer to a mutable unsigned 8-bit integer. impl From
for *mut u8 { fn from(value: Address) -> Self { value.0 as *mut u8 } } -/// Implements the addition of a `usize` value to an `Address` value. impl Add for Address { type Output = Self; - /// Adds a `usize` value to an `Address` value and returns the result. fn add(self, rhs: usize) -> Self::Output { Self(self.0 + rhs) } } -/// Implements the addition of two `Address` instances. impl Add
for Address { type Output = Self; - /// Adds two `Address` instances and returns a new `Address`. fn add(self, rhs: Address) -> Self::Output { Self(self.0 + rhs.0) } } -/// Implements the `AddAssign` trait for `Address` struct. impl AddAssign for Address { - /// Adds the given `rhs` value to the `Address` struct. fn add_assign(&mut self, rhs: usize) { self.0 += rhs; } } -/// Implements the `AddAssign` trait for `Address`. impl AddAssign
for Address { - /// Adds the given `rhs` value to the `Address` struct. fn add_assign(&mut self, rhs: Address) { self.0 += rhs.0; } } -/// Implements the subtraction of a `usize` from an `Address`. impl Sub for Address { type Output = Self; - /// Subtracts the given `rhs` from `&self`. fn sub(self, rhs: usize) -> Self::Output { Self(self.0 - rhs) } } -/// Implements the subtraction operation for `Address`. impl Sub
for Address { type Output = Self; - /// Subtracts the given `rhs` from `&self`. fn sub(self, rhs: Address) -> Self::Output { Self(self.0 - rhs.0) } } -/// Implements the subtraction assignment operation for `Address` and `usize`. impl SubAssign for Address { - /// Subtracts the given `rhs` from the `Address`. fn sub_assign(&mut self, rhs: usize) { self.0 -= rhs; } } -/// Implements the subtraction assignment operator for `Address`. impl SubAssign
for Address { - /// Subtracts the value of `rhs` from `&self`. fn sub_assign(&mut self, rhs: Address) { self.0 -= rhs.0; } } -/// Implements the `UpperHex` trait for the `Address` struct. impl UpperHex for Address { - /// Formats the value of `&self` using the `write!` macro and the `UpperHex` format specifier. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:#X}", self.0) } } -/// Implements the `LowerHex` trait for the `Address` struct. impl LowerHex for Address { - /// Formats the value of `&self` using the `write!` macro and the `LowerHex` format specifier. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:#x}", self.0) } diff --git a/src/util/module.rs b/src/util/module.rs index c51c36a..e176cf0 100644 --- a/src/util/module.rs +++ b/src/util/module.rs @@ -1,5 +1,3 @@ -use super::Address; - use anyhow::Result; use goblin::pe::export::Export; @@ -8,29 +6,15 @@ use goblin::pe::options::ParseOptions; use goblin::pe::section_table::SectionTable; use goblin::pe::PE; -/// Represents a module loaded in a Windows process. +use super::Address; + pub struct Module<'a> { - /// The name of the module. pub name: &'a str, - - /// A reference to a slice of bytes containing the module data. pub data: &'a [u8], - - /// The PE file format representation of the module. pub pe: PE<'a>, } impl<'a> Module<'a> { - /// Parses the given module name and data and returns a `Result` containing a `Module` struct. - /// - /// # Arguments - /// - /// * `name` - A string slice that holds the name of the module. - /// * `data` - A byte slice that holds the data of the module. - /// - /// # Returns - /// - /// * `Result` - A `Result` containing a `Module` instance if successful, or an error if the module could not be parsed. pub fn parse(name: &'a str, data: &'a [u8]) -> Result { let pe = PE::parse_with_opts( data, @@ -43,45 +27,23 @@ impl<'a> Module<'a> { Ok(Self { name, data, pe }) } - /// Returns the base address of the module. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Module` struct. - /// - /// # Returns - /// - /// * `Address` - The base address of the module. #[inline] pub fn base(&self) -> Address { self.pe.image_base.into() } - /// Returns a slice of `Export` structs representing the exports of the module. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Module` struct. - /// - /// # Returns - /// - /// * `&[Export]` - A slice of `Export` structs representing the exports of the module. #[inline] - pub fn exports(&self) -> &'a [Export] { - self.pe.exports.as_slice() + pub fn exports(&self) -> &[Export] { + &self.pe.exports } - /// Returns the address of the export with the given name, if it exists. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Module` struct. - /// - /// # Returns - /// - /// * `Option
` - The address of the export with the given name, if it exists. #[inline] - pub fn get_export_by_name(&self, name: &str) -> Option
{ + pub fn imports(&self) -> &[Import] { + &self.pe.imports + } + + #[inline] + pub fn export_by_name(&self, name: &str) -> Option
{ self.pe .exports .iter() @@ -89,17 +51,8 @@ impl<'a> Module<'a> { .map(|e| (self.pe.image_base + e.rva).into()) } - /// Returns the address of the imported function with the given name, if it exists. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Module` struct. - /// - /// # Returns - /// - /// * `Option
` - The address of the imported function with the given name, if it exists. #[inline] - pub fn get_import_by_name(&self, name: &str) -> Option
{ + pub fn import_by_name(&self, name: &str) -> Option
{ self.pe .imports .iter() @@ -107,49 +60,17 @@ impl<'a> Module<'a> { .map(|i| (self.pe.image_base + i.rva).into()) } - /// Returns a slice of the imported functions of the module. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Module` struct. - /// - /// # Returns - /// - /// * `&[Import]` - A slice of `Import` structs representing the imported functions of the module. - #[inline] - pub fn imports(&self) -> &'a [Import] { - self.pe.imports.as_slice() - } - - /// Returns a slice of the section table entries in the module's PE header. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Module` struct. - /// - /// # Returns - /// - /// * `&[SectionTable]` - A slice of `SectionTable` structs representing the section table entries in the module's PE header. #[inline] pub fn sections(&self) -> &[SectionTable] { - self.pe.sections.as_slice() + &self.pe.sections } - /// Returns the size of the module. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Module` struct. - /// - /// # Returns - /// - /// * `u32` - The size of the module. #[inline] pub fn size(&self) -> u32 { self.pe .header .optional_header - .unwrap() + .expect("optional header not found") .windows_fields .size_of_image } diff --git a/src/util/process.rs b/src/util/process.rs index edfc29a..8305497 100644 --- a/src/util/process.rs +++ b/src/util/process.rs @@ -1,76 +1,41 @@ -use super::{Address, Module}; - -use anyhow::{bail, Result}; - use std::collections::HashMap; use std::ffi::{c_void, CStr}; use std::mem; use std::ptr; +use anyhow::{bail, Result}; + use windows::Win32::Foundation::{CloseHandle, HANDLE}; use windows::Win32::System::Diagnostics::Debug::ReadProcessMemory; use windows::Win32::System::Diagnostics::ToolHelp::*; use windows::Win32::System::Threading::{OpenProcess, PROCESS_ALL_ACCESS}; -/// Represents a Windows process. +use super::{Address, Module}; + #[derive(Debug)] pub struct Process { - /// ID of the process. id: u32, - - /// Handle to the process. handle: HANDLE, - - /// A HashMap containing the name of each module and its corresponding raw data. modules: HashMap>, } impl Process { - /// Creates a new `Process` instance with the given name. - /// - /// # Arguments - /// - /// * `name` - A string slice that holds the name of the process. - /// - /// # Returns - /// - /// * `Result` - A `Result` containing the `Process` instance if successful, or an error if the process could not be found. pub fn new(name: &str) -> Result { let id = Self::get_process_id_by_name(name)?; let handle = unsafe { OpenProcess(PROCESS_ALL_ACCESS, false, id) }?; - Ok(Self { + let mut process = Self { id, handle, modules: HashMap::new(), - }) + }; + + process.parse_loaded_modules()?; + + Ok(process) } - /// Initializes the `Process` instance by parsing all loaded modules in the process. - /// - /// # Arguments - /// - /// * `&self` - A mutable reference to the `Process` struct. - /// - /// # Returns - /// - /// * `Result<()>` - A `Result` indicating the outcome of the operation. - pub fn initialize(&mut self) -> Result<()> { - self.parse_loaded_modules() - } - - /// Searches for a pattern in the memory of a specified module and returns the address of the first occurrence. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Process` struct. - /// * `module_name` - A string slice that holds the name of the module to search in. - /// * `pattern` - A string slice that holds the pattern to search for. - /// - /// # Returns - /// - /// * `Option
` - The address of the first occurrence of the pattern if found, or `None` if the pattern was not found. pub fn find_pattern(&self, module_name: &str, pattern: &str) -> Option
{ let module = self.get_module_by_name(module_name)?; @@ -89,31 +54,12 @@ impl Process { None } - /// Returns an optional `Module` instance by its name. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Process` struct. - /// * `name` - A string slice representing the name of the module to retrieve. - /// - /// # Returns - /// - /// * `Option` - An optional `Module` instance if the module was found, or `None` if the module was not found. pub fn get_module_by_name<'a>(&'a self, name: &'a str) -> Option> { self.modules .get(name) .map(|data| Module::parse(name, data).unwrap()) } - /// Returns a vector of `Module` instances parsed from the process's loaded modules. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Process` struct. - /// - /// # Returns - /// - /// * `Result>` - A `Result` containing a vector of `Module` instances if successful, or an error if the modules could not be parsed. pub fn modules(&self) -> Result> { let mut modules = Vec::new(); @@ -124,23 +70,6 @@ impl Process { Ok(modules) } - /// Reads the memory at the specified address and returns the value as type T. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Process` struct. - /// * `address` - The address to read from. - /// - /// # Examples - /// - /// ``` - /// let process = Process::new(pid)?; - /// let value: i32 = process.read_memory(address)?; - /// ``` - /// - /// # Returns - /// - /// * `Result` - A `Result` containing the value if successful, or an error if the memory read fails. pub fn read_memory(&self, address: Address) -> Result { let mut buffer: T = unsafe { mem::zeroed() }; @@ -153,18 +82,6 @@ impl Process { Ok(buffer) } - /// Reads the memory of a process and stores it in a buffer. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Process` struct. - /// * `address` - The address to start reading from. - /// * `buffer` - A pointer to the buffer where the read data will be stored. - /// * `size` - The number of bytes to read. - /// - /// # Returns - /// - /// * `Result<()>` - A `Result` indicating the outcome of the operation. pub fn read_memory_raw( &self, address: Address, @@ -183,16 +100,6 @@ impl Process { .map_err(|e| e.into()) } - /// Reads a null-terminated string from the process memory at the given address. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Process` struct. - /// * `address` - The address in the process memory where the string is located. - /// - /// # Returns - /// - /// * `Result` - A `Result` containing the string read from the process memory if successful, or an error if the memory read fails or if the string contains invalid UTF-8. pub fn read_string(&self, address: Address) -> Result { let mut buffer = Vec::new(); @@ -206,17 +113,6 @@ impl Process { Ok(String::from_utf8(buffer)?) } - /// Reads a string of the specified length from the process memory at the given address. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Process` struct. - /// * `address` - The address to read the string from. - /// * `length` - The length of the string to read. - /// - /// # Returns - /// - /// * `Result` - A `Result` containing the string read from the process memory if successful, or an error if the memory read fails or if the string contains invalid UTF-8. pub fn read_string_length(&self, address: Address, length: usize) -> Result { let mut buffer = vec![0; length]; @@ -229,18 +125,6 @@ impl Process { Ok(String::from_utf8(buffer)?) } - /// Resolves the absolute address of a relative call. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Process` struct. - /// * `address` - The address of the jump instruction. - /// * `offset` - The offset of the displacement value. - /// * `length` - The length of the instruction. - /// - /// # Returns - /// - /// * `Result
` - A `Result` containing the absolute address if successful, or an error if the memory read fails. pub fn resolve_jmp( &self, address: Address, @@ -255,18 +139,6 @@ impl Process { .add(displacement as usize)) } - /// Resolves the absolute address of a RIP-relative address. - /// - /// # Arguments - /// - /// * `&self` - A reference to the `Process` struct. - /// * `address` - The address of the relative instruction pointer (RIP). - /// * `offset` - The offset of the displacement value. If `None`, the offset will be `0x3`. - /// * `length` - The length of the instruction. If `None`, the length will be `0x7`. - /// - /// # Returns - /// - /// * `Result
` - A `Result` containing the absolute address if successful, or an error if the memory read fails. pub fn resolve_rip( &self, address: Address, @@ -281,15 +153,6 @@ impl Process { .add(displacement as usize)) } - /// Returns the process ID of the first process with the given name. - /// - /// # Arguments - /// - /// * `process_name` - A string slice that holds the name of the process to search for. - /// - /// # Returns - /// - /// * `Result` - A `Result` containing the process ID if successful, or an error if the process could not be found. fn get_process_id_by_name(process_name: &str) -> Result { let snapshot = unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) }?; @@ -313,15 +176,6 @@ impl Process { bail!("Process not found: {}", process_name) } - /// Parses the loaded modules of a process and stores them in a HashMap with the module name as the key and the module data as the value. - /// - /// # Arguments - /// - /// * `&self` - A mutable reference to the `Process` struct. - /// - /// # Returns - /// - /// * `Result<()>` - A `Result` indicating the outcome of the operation. fn parse_loaded_modules(&mut self) -> Result<()> { let snapshot = unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, self.id) }?; @@ -351,15 +205,6 @@ impl Process { Ok(()) } - /// Converts a pattern string to a vector of bytes. - /// - /// # Arguments - /// - /// * `pattern` - A string slice that represents the pattern to be converted. - /// - /// # Returns - /// - /// * `Vec` - A vector of bytes representing the pattern. fn pattern_to_bytes(pattern: &str) -> Vec { pattern .split_whitespace() @@ -374,9 +219,6 @@ impl Process { } } -/// Implements the `Drop` trait for the `Process` struct. -/// -/// When a `Process` instance goes out of scope, this implementation will automatically close the process handle if it is not invalid. impl Drop for Process { fn drop(&mut self) { if !self.handle.is_invalid() {