Change json structure and add comments for modules

This commit is contained in:
mysty 2023-10-18 11:29:37 +01:00
parent 0a86db6b40
commit 7bf035aaf6
12 changed files with 85 additions and 48 deletions

View File

@ -17,8 +17,12 @@ impl FileBuilder for CppFileBuilder {
Ok(()) 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<()> {
if let Some(comment) = comment {
write!(output, "namespace {} {{ // {}\n", name, comment)?;
} else {
write!(output, "namespace {} {{\n", name)?; write!(output, "namespace {} {{\n", name)?;
}
Ok(()) Ok(())
} }

View File

@ -14,8 +14,12 @@ impl FileBuilder for CSharpFileBuilder {
Ok(()) 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<()> {
if let Some(comment) = comment {
write!(output, "public static class {} {{ // {}\n", name, comment)?;
} else {
write!(output, "public static class {} {{\n", name)?; write!(output, "public static class {} {{\n", name)?;
}
Ok(()) Ok(())
} }

View File

@ -5,7 +5,7 @@ pub trait FileBuilder {
fn write_top_level(&mut self, output: &mut dyn Write) -> Result<()>; 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( fn write_variable(
&mut self, &mut self,

View File

@ -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; use super::FileBuilder;
#[derive(Debug, PartialEq)]
pub struct JsonFileBuilder { #[derive(Debug, PartialEq, Default, Serialize)]
json: Value, struct JsonOffsetValue {
current_namespace: String, value: usize,
comment: Option<String>,
} }
impl Default for JsonFileBuilder { #[derive(Debug, PartialEq, Default, Serialize)]
fn default() -> Self { struct JsonMod {
Self { data: BTreeMap<String, JsonOffsetValue>,
json: Value::Object(Map::new()), comment: Option<String>,
current_namespace: String::new(), }
}
} #[derive(Debug, PartialEq, Default)]
pub struct JsonFileBuilder {
data: BTreeMap<String, JsonMod>,
current_namespace: String,
} }
impl FileBuilder for JsonFileBuilder { impl FileBuilder for JsonFileBuilder {
@ -28,8 +32,9 @@ impl FileBuilder for JsonFileBuilder {
Ok(()) 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.current_namespace = name.to_string();
self.data.entry(name.to_string()).or_default().comment = comment.map(str::to_string);
Ok(()) Ok(())
} }
@ -39,26 +44,22 @@ impl FileBuilder for JsonFileBuilder {
_output: &mut dyn Write, _output: &mut dyn Write,
name: &str, name: &str,
value: usize, value: usize,
_comment: Option<&str>, comment: Option<&str>,
) -> Result<()> { ) -> Result<()> {
if let Some(map) = self.json.as_object_mut() { self.data.entry(self.current_namespace.clone()).or_default().data
let entry = map .insert(name.to_string(), JsonOffsetValue {
.entry(&self.current_namespace) value: value,
.or_insert_with(|| json!({})); comment: comment.map(str::to_string)
});
if let Some(object) = entry.as_object_mut() {
object.insert(name.to_string(), json!(value));
}
}
Ok(()) Ok(())
} }
fn write_closure(&mut self, output: &mut dyn Write, eof: bool) -> Result<()> { fn write_closure(&mut self, output: &mut dyn Write, eof: bool) -> Result<()> {
if eof { 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(()) Ok(())

View File

@ -32,8 +32,8 @@ impl FileBuilder for FileBuilderEnum {
self.as_mut().write_top_level(output) self.as_mut().write_top_level(output)
} }
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.as_mut().write_namespace(output, name) self.as_mut().write_namespace(output, name, comment)
} }
fn write_variable( fn write_variable(

View File

@ -14,8 +14,12 @@ impl FileBuilder for PythonFileBuilder {
Ok(()) 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<()> {
if let Some(comment) = comment {
write!(output, "class {}: # {}\n", name, comment)?;
} else {
write!(output, "class {}:\n", name)?; write!(output, "class {}:\n", name)?;
}
Ok(()) Ok(())
} }

View File

@ -19,8 +19,12 @@ impl FileBuilder for RustFileBuilder {
Ok(()) 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<()> {
if let Some(comment) = comment {
write!(output, "pub mod {} {{ // {}\n", name, comment)?;
} else {
write!(output, "pub mod {} {{\n", name)?; write!(output, "pub mod {} {{\n", name)?;
}
Ok(()) Ok(())
} }

View File

@ -47,6 +47,7 @@ pub fn dump_interfaces(builders: &mut Vec<FileBuilderEnum>, process: &Process) -
.to_case(Case::Pascal), .to_case(Case::Pascal),
) )
.or_default() .or_default()
.data
.push(Entry { .push(Entry {
name: name.clone(), name: name.clone(),
value: ptr - module.base(), value: ptr - module.base(),

View File

@ -21,7 +21,13 @@ pub struct Entry {
pub comment: Option<String>, pub comment: Option<String>,
} }
pub type Entries = BTreeMap<String, Vec<Entry>>; #[derive(Default)]
pub struct EntriesContainer {
pub data: Vec<Entry>,
pub comment: Option<String>
}
pub type Entries = BTreeMap<String, EntriesContainer>;
pub fn generate_file( pub fn generate_file(
builder: &mut FileBuilderEnum, builder: &mut FileBuilderEnum,
@ -43,9 +49,9 @@ pub fn generate_file(
let len = entries.len(); let len = entries.len();
for (i, pair) in entries.iter().enumerate() { 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( builder.write_variable(
&mut file, &mut file,
&entry.name, &entry.name,

View File

@ -84,6 +84,7 @@ pub fn dump_offsets(builders: &mut Vec<FileBuilderEnum>, process: &Process) -> R
log::info!("Dumping offsets..."); log::info!("Dumping offsets...");
for signature in config.signatures { for signature in config.signatures {
log::info!("Searching for {}...", signature.name);
let module = process.get_module_by_name(&signature.module)?; let module = process.get_module_by_name(&signature.module)?;
let mut address = match process.find_pattern(&signature.module, &signature.pattern) { let mut address = match process.find_pattern(&signature.module, &signature.pattern) {
@ -156,6 +157,7 @@ pub fn dump_offsets(builders: &mut Vec<FileBuilderEnum>, process: &Process) -> R
.to_case(Case::Pascal), .to_case(Case::Pascal),
) )
.or_default() .or_default()
.data
.push(Entry { .push(Entry {
name, name,
value, value,

View File

@ -19,6 +19,9 @@ pub fn dump_schemas(builders: &mut Vec<FileBuilderEnum>, process: &Process) -> R
for class in type_scope.classes()? { for class in type_scope.classes()? {
log::debug!(" {}", class.name()); 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()? { for field in class.fields()? {
let field_name = field.name()?; let field_name = field.name()?;
let field_offset = field.offset()?; let field_offset = field.offset()?;
@ -31,10 +34,7 @@ pub fn dump_schemas(builders: &mut Vec<FileBuilderEnum>, process: &Process) -> R
field_type_name field_type_name
); );
entries container.data.push(Entry {
.entry(class.name().replace("::", "_"))
.or_default()
.push(Entry {
name: field_name, name: field_name,
value: field_offset as usize, value: field_offset as usize,
comment: Some(field_type_name), comment: Some(field_type_name),

View File

@ -45,4 +45,15 @@ impl<'a> SchemaClassInfo<'a> {
pub fn fields_count(&self) -> Result<u16> { pub fn fields_count(&self) -> Result<u16> {
self.process.read_memory::<u16>(self.address + 0x1C) self.process.read_memory::<u16>(self.address + 0x1C)
} }
pub fn parent(&self) -> Result<Option<SchemaClassInfo>> {
let addr = self.process.read_memory::<u64>(self.address + 0x38)?;
if addr == 0 {
return Ok(None);
}
let parent = self.process.read_memory::<u64>(addr as usize + 0x8)?;
let name = self.process.read_string(self.process.read_memory::<usize>(parent as usize + 0x8)?)?;
Ok(Some(SchemaClassInfo::new(self.process, parent as usize, &name)))
}
} }