From 7bf035aaf6a0e2cc4bd938ae0b0f199732f4376c Mon Sep 17 00:00:00 2001 From: mysty Date: Wed, 18 Oct 2023 11:29:37 +0100 Subject: [PATCH] Change json structure and add comments for modules --- src/builder/cpp_file_builder.rs | 8 +++-- src/builder/csharp_file_builder.rs | 8 +++-- src/builder/file_builder.rs | 2 +- src/builder/json_file_builder.rs | 53 +++++++++++++++--------------- src/builder/mod.rs | 4 +-- src/builder/python_file_builder.rs | 8 +++-- src/builder/rust_file_builder.rs | 8 +++-- src/dumpers/interfaces.rs | 1 + src/dumpers/mod.rs | 12 +++++-- src/dumpers/offsets.rs | 2 ++ src/dumpers/schemas.rs | 16 ++++----- src/sdk/schema_class_info.rs | 11 +++++++ 12 files changed, 85 insertions(+), 48 deletions(-) diff --git a/src/builder/cpp_file_builder.rs b/src/builder/cpp_file_builder.rs index ad1b9b3b..220691d0 100644 --- a/src/builder/cpp_file_builder.rs +++ b/src/builder/cpp_file_builder.rs @@ -17,8 +17,12 @@ impl FileBuilder for CppFileBuilder { Ok(()) } - fn write_namespace(&mut self, output: &mut dyn Write, name: &str) -> Result<()> { - write!(output, "namespace {} {{\n", name)?; + fn write_namespace(&mut self, output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()> { + if let Some(comment) = comment { + write!(output, "namespace {} {{ // {}\n", name, comment)?; + } else { + write!(output, "namespace {} {{\n", name)?; + } Ok(()) } diff --git a/src/builder/csharp_file_builder.rs b/src/builder/csharp_file_builder.rs index f1b1c86e..f091c2da 100644 --- a/src/builder/csharp_file_builder.rs +++ b/src/builder/csharp_file_builder.rs @@ -14,8 +14,12 @@ impl FileBuilder for CSharpFileBuilder { Ok(()) } - fn write_namespace(&mut self, output: &mut dyn Write, name: &str) -> Result<()> { - write!(output, "public static class {} {{\n", name)?; + fn write_namespace(&mut self, output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()> { + if let Some(comment) = comment { + write!(output, "public static class {} {{ // {}\n", name, comment)?; + } else { + write!(output, "public static class {} {{\n", name)?; + } Ok(()) } diff --git a/src/builder/file_builder.rs b/src/builder/file_builder.rs index 9b9b00b1..3908fb02 100644 --- a/src/builder/file_builder.rs +++ b/src/builder/file_builder.rs @@ -5,7 +5,7 @@ pub trait FileBuilder { fn write_top_level(&mut self, output: &mut dyn Write) -> Result<()>; - fn write_namespace(&mut self, output: &mut dyn Write, name: &str) -> Result<()>; + fn write_namespace(&mut self, output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()>; fn write_variable( &mut self, diff --git a/src/builder/json_file_builder.rs b/src/builder/json_file_builder.rs index 4694c990..1cb9cf42 100644 --- a/src/builder/json_file_builder.rs +++ b/src/builder/json_file_builder.rs @@ -1,22 +1,26 @@ -use std::io::{Result, Write}; +use std::{io::{Result, Write}, collections::BTreeMap}; -use serde_json::{json, Map, Value}; +use serde::Serialize; use super::FileBuilder; -#[derive(Debug, PartialEq)] -pub struct JsonFileBuilder { - json: Value, - current_namespace: String, + +#[derive(Debug, PartialEq, Default, Serialize)] +struct JsonOffsetValue { + value: usize, + comment: Option, } -impl Default for JsonFileBuilder { - fn default() -> Self { - Self { - json: Value::Object(Map::new()), - current_namespace: String::new(), - } - } +#[derive(Debug, PartialEq, Default, Serialize)] +struct JsonMod { + data: BTreeMap, + comment: Option, +} + +#[derive(Debug, PartialEq, Default)] +pub struct JsonFileBuilder { + data: BTreeMap, + current_namespace: String, } impl FileBuilder for JsonFileBuilder { @@ -28,8 +32,9 @@ impl FileBuilder for JsonFileBuilder { Ok(()) } - fn write_namespace(&mut self, _output: &mut dyn Write, name: &str) -> Result<()> { + fn write_namespace(&mut self, _output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()> { self.current_namespace = name.to_string(); + self.data.entry(name.to_string()).or_default().comment = comment.map(str::to_string); Ok(()) } @@ -39,26 +44,22 @@ impl FileBuilder for JsonFileBuilder { _output: &mut dyn Write, name: &str, value: usize, - _comment: Option<&str>, + comment: Option<&str>, ) -> Result<()> { - if let Some(map) = self.json.as_object_mut() { - let entry = map - .entry(&self.current_namespace) - .or_insert_with(|| json!({})); - - if let Some(object) = entry.as_object_mut() { - object.insert(name.to_string(), json!(value)); - } - } + self.data.entry(self.current_namespace.clone()).or_default().data + .insert(name.to_string(), JsonOffsetValue { + value: value, + comment: comment.map(str::to_string) + }); Ok(()) } fn write_closure(&mut self, output: &mut dyn Write, eof: bool) -> Result<()> { if eof { - write!(output, "{}", serde_json::to_string_pretty(&self.json)?)?; + write!(output, "{}", serde_json::to_string_pretty(&self.data)?)?; - self.json = json!({}); + self.data = BTreeMap::new(); } Ok(()) diff --git a/src/builder/mod.rs b/src/builder/mod.rs index e06ada90..fc47d182 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -32,8 +32,8 @@ impl FileBuilder for FileBuilderEnum { self.as_mut().write_top_level(output) } - fn write_namespace(&mut self, output: &mut dyn Write, name: &str) -> Result<()> { - self.as_mut().write_namespace(output, name) + fn write_namespace(&mut self, output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()> { + self.as_mut().write_namespace(output, name, comment) } fn write_variable( diff --git a/src/builder/python_file_builder.rs b/src/builder/python_file_builder.rs index de65ec95..092d4223 100644 --- a/src/builder/python_file_builder.rs +++ b/src/builder/python_file_builder.rs @@ -14,8 +14,12 @@ impl FileBuilder for PythonFileBuilder { Ok(()) } - fn write_namespace(&mut self, output: &mut dyn Write, name: &str) -> Result<()> { - write!(output, "class {}:\n", name)?; + fn write_namespace(&mut self, output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()> { + if let Some(comment) = comment { + write!(output, "class {}: # {}\n", name, comment)?; + } else { + write!(output, "class {}:\n", name)?; + } Ok(()) } diff --git a/src/builder/rust_file_builder.rs b/src/builder/rust_file_builder.rs index 2065b9e8..626166fc 100644 --- a/src/builder/rust_file_builder.rs +++ b/src/builder/rust_file_builder.rs @@ -19,8 +19,12 @@ impl FileBuilder for RustFileBuilder { Ok(()) } - fn write_namespace(&mut self, output: &mut dyn Write, name: &str) -> Result<()> { - write!(output, "pub mod {} {{\n", name)?; + fn write_namespace(&mut self, output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()> { + if let Some(comment) = comment { + write!(output, "pub mod {} {{ // {}\n", name, comment)?; + } else { + write!(output, "pub mod {} {{\n", name)?; + } Ok(()) } diff --git a/src/dumpers/interfaces.rs b/src/dumpers/interfaces.rs index 2f308b47..a7f5614d 100644 --- a/src/dumpers/interfaces.rs +++ b/src/dumpers/interfaces.rs @@ -47,6 +47,7 @@ pub fn dump_interfaces(builders: &mut Vec, process: &Process) - .to_case(Case::Pascal), ) .or_default() + .data .push(Entry { name: name.clone(), value: ptr - module.base(), diff --git a/src/dumpers/mod.rs b/src/dumpers/mod.rs index d5b4318c..a4617ece 100644 --- a/src/dumpers/mod.rs +++ b/src/dumpers/mod.rs @@ -21,7 +21,13 @@ pub struct Entry { pub comment: Option, } -pub type Entries = BTreeMap>; +#[derive(Default)] +pub struct EntriesContainer { + pub data: Vec, + pub comment: Option +} + +pub type Entries = BTreeMap; pub fn generate_file( builder: &mut FileBuilderEnum, @@ -43,9 +49,9 @@ pub fn generate_file( let len = entries.len(); for (i, pair) in entries.iter().enumerate() { - builder.write_namespace(&mut file, pair.0)?; + builder.write_namespace(&mut file, pair.0, pair.1.comment.as_deref())?; - pair.1.iter().try_for_each(|entry| { + pair.1.data.iter().try_for_each(|entry| { builder.write_variable( &mut file, &entry.name, diff --git a/src/dumpers/offsets.rs b/src/dumpers/offsets.rs index 4228d8ce..601f184b 100644 --- a/src/dumpers/offsets.rs +++ b/src/dumpers/offsets.rs @@ -84,6 +84,7 @@ pub fn dump_offsets(builders: &mut Vec, process: &Process) -> R log::info!("Dumping offsets..."); for signature in config.signatures { + log::info!("Searching for {}...", signature.name); let module = process.get_module_by_name(&signature.module)?; let mut address = match process.find_pattern(&signature.module, &signature.pattern) { @@ -156,6 +157,7 @@ pub fn dump_offsets(builders: &mut Vec, process: &Process) -> R .to_case(Case::Pascal), ) .or_default() + .data .push(Entry { name, value, diff --git a/src/dumpers/schemas.rs b/src/dumpers/schemas.rs index 38761eba..e2468c85 100644 --- a/src/dumpers/schemas.rs +++ b/src/dumpers/schemas.rs @@ -19,6 +19,9 @@ pub fn dump_schemas(builders: &mut Vec, process: &Process) -> R for class in type_scope.classes()? { log::debug!(" {}", class.name()); + let container = entries.entry(class.name().replace("::", "_")).or_default(); + container.comment = class.parent()?.map(|p| p.name().to_string()); + for field in class.fields()? { let field_name = field.name()?; let field_offset = field.offset()?; @@ -31,14 +34,11 @@ pub fn dump_schemas(builders: &mut Vec, process: &Process) -> R field_type_name ); - entries - .entry(class.name().replace("::", "_")) - .or_default() - .push(Entry { - name: field_name, - value: field_offset as usize, - comment: Some(field_type_name), - }); + container.data.push(Entry { + name: field_name, + value: field_offset as usize, + comment: Some(field_type_name), + }); } } diff --git a/src/sdk/schema_class_info.rs b/src/sdk/schema_class_info.rs index c5f80a65..34993ac5 100644 --- a/src/sdk/schema_class_info.rs +++ b/src/sdk/schema_class_info.rs @@ -45,4 +45,15 @@ impl<'a> SchemaClassInfo<'a> { pub fn fields_count(&self) -> Result { self.process.read_memory::(self.address + 0x1C) } + + pub fn parent(&self) -> Result> { + let addr = self.process.read_memory::(self.address + 0x38)?; + if addr == 0 { + return Ok(None); + } + + let parent = self.process.read_memory::(addr as usize + 0x8)?; + let name = self.process.read_string(self.process.read_memory::(parent as usize + 0x8)?)?; + Ok(Some(SchemaClassInfo::new(self.process, parent as usize, &name))) + } }