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(())
}
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(())
}

View File

@ -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(())
}

View File

@ -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,

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;
#[derive(Debug, PartialEq)]
pub struct JsonFileBuilder {
json: Value,
current_namespace: String,
#[derive(Debug, PartialEq, Default, Serialize)]
struct JsonOffsetValue {
value: usize,
comment: Option<String>,
}
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<String, JsonOffsetValue>,
comment: Option<String>,
}
#[derive(Debug, PartialEq, Default)]
pub struct JsonFileBuilder {
data: BTreeMap<String, JsonMod>,
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(())

View File

@ -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(

View File

@ -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(())
}

View File

@ -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(())
}

View File

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

View File

@ -21,7 +21,13 @@ pub struct Entry {
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(
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,

View File

@ -84,6 +84,7 @@ pub fn dump_offsets(builders: &mut Vec<FileBuilderEnum>, 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<FileBuilderEnum>, process: &Process) -> R
.to_case(Case::Pascal),
)
.or_default()
.data
.push(Entry {
name,
value,

View File

@ -19,6 +19,9 @@ pub fn dump_schemas(builders: &mut Vec<FileBuilderEnum>, 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<FileBuilderEnum>, 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),
});
}
}

View File

@ -45,4 +45,15 @@ impl<'a> SchemaClassInfo<'a> {
pub fn fields_count(&self) -> Result<u16> {
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)))
}
}