mirror of
https://github.com/Theaninova/WanganSunrise.git
synced 2026-01-06 07:22:51 +00:00
feat: improve cli tool
This commit is contained in:
19
enmacompat/README.md
Normal file
19
enmacompat/README.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Enma Compat
|
||||||
|
|
||||||
|
Library with CLI tool to work with Enma Engine's emedded data
|
||||||
|
|
||||||
|
## CLI
|
||||||
|
|
||||||
|
You can use the CLI to inspect data contained in the binary
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Only need to run this once
|
||||||
|
enmacompat --path path/to/exe analyze
|
||||||
|
|
||||||
|
# This is for inspecting
|
||||||
|
enmacompat --path path/to/exe extract
|
||||||
|
```
|
||||||
|
|
||||||
|
## Blender Script
|
||||||
|
|
||||||
|
TODO;
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
pub mod area;
|
pub mod area;
|
||||||
|
pub mod meta;
|
||||||
pub mod section;
|
pub mod section;
|
||||||
mod util;
|
mod util;
|
||||||
pub mod windows_pe;
|
pub mod windows_pe;
|
||||||
|
|||||||
@@ -1,44 +1,56 @@
|
|||||||
use clap::{command, Parser};
|
use clap::{command, Parser, Subcommand};
|
||||||
use enmacompat::{
|
use enmacompat::{area::read_area, meta::EnmaMeta, windows_pe::WindowsPEFile};
|
||||||
area::{find_area_array_location, read_area, EnmaAreaRaw},
|
|
||||||
windows_pe::WindowsPEFile,
|
|
||||||
};
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser)]
|
||||||
#[command(version, about)]
|
#[command(version, about)]
|
||||||
struct Args {
|
struct Args {
|
||||||
|
#[clap(subcommand)]
|
||||||
|
command: Commands,
|
||||||
|
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
path: std::path::PathBuf,
|
path: std::path::PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand)]
|
||||||
|
enum Commands {
|
||||||
|
#[clap(about = "Analyze the file and generate a metadata file")]
|
||||||
|
Analyze,
|
||||||
|
#[clap(about = "Extract data from the file")]
|
||||||
|
Extract,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
let file = File::open(&args.path).expect("Failed to open file");
|
let file = File::open(&args.path).expect("Failed to open file");
|
||||||
let mut windows_pe_file = WindowsPEFile::from(file);
|
let mut windows_pe_file = WindowsPEFile::from(file);
|
||||||
|
|
||||||
println!("\x1b[34m\x1b[1mSearching for Area Array Location\x1b[0m");
|
match args.command {
|
||||||
let location = Some(0x1417cc980); //find_area_array_location(&mut windows_pe_file).unwrap();
|
Commands::Analyze => {
|
||||||
if let Some(location) = location {
|
let file = File::create(args.path.with_extension("json")).unwrap();
|
||||||
println!(
|
let mut writer = std::io::BufWriter::new(file);
|
||||||
"\x1b[32m\x1b[1mArea Array Location\x1b[0m: \x1b[4m{:#x}\x1b[0m (Memory), \x1b[4m{:#x}\x1b[0m (File)",
|
serde_json::to_writer_pretty(
|
||||||
location,
|
&mut writer,
|
||||||
windows_pe_file.get_file_address(location).unwrap()
|
&EnmaMeta::from_analysis(&mut windows_pe_file).unwrap(),
|
||||||
);
|
)
|
||||||
|
.unwrap();
|
||||||
let mut i = 1;
|
|
||||||
loop {
|
|
||||||
let address = windows_pe_file.read_addr::<u64>(location + i * 8).unwrap();
|
|
||||||
if address == 0 {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
Commands::Extract => {
|
||||||
|
let meta_file = File::open(args.path.with_extension("json"))
|
||||||
|
.expect("Missing meta file, did you forget to run the analyze command?");
|
||||||
|
let meta: EnmaMeta = serde_json::from_reader(meta_file)
|
||||||
|
.expect("Failed to read meta file, try running the analyze command again?");
|
||||||
|
|
||||||
|
for i in 1..meta.area_array_count {
|
||||||
|
let address = windows_pe_file
|
||||||
|
.read_addr::<u64>(meta.area_array_addr + i as u64 * 8)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let area = read_area(&windows_pe_file, address).unwrap();
|
let area = read_area(&windows_pe_file, address).unwrap();
|
||||||
let file = File::create(format!("out/{}.json", area.name)).unwrap();
|
let file = File::create(format!("out/{}.json", area.name)).unwrap();
|
||||||
let mut writer = std::io::BufWriter::new(file);
|
let mut writer = std::io::BufWriter::new(file);
|
||||||
serde_json::to_writer_pretty(&mut writer, &area).unwrap();
|
serde_json::to_writer_pretty(&mut writer, &area).unwrap();
|
||||||
i += 1;
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
println!("\x1b[31mArea array location could not found\x1b[0m");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
47
enmacompat/src/meta.rs
Normal file
47
enmacompat/src/meta.rs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{area::find_area_array_location, windows_pe::WindowsPEFile};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct EnmaMeta {
|
||||||
|
pub area_array_addr: u64,
|
||||||
|
pub area_array_count: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EnmaMeta {
|
||||||
|
/// Performs an analysis from a WindowsPE executable to find specific data locations
|
||||||
|
pub fn from_analysis(windows_pe_file: &mut WindowsPEFile) -> Result<Self, std::io::Error> {
|
||||||
|
println!("\x1b[34m\x1b[1mSearching for Area Array Location\x1b[0m");
|
||||||
|
let area_array_addr = find_area_array_location(windows_pe_file)?.ok_or_else(|| {
|
||||||
|
std::io::Error::new(
|
||||||
|
std::io::ErrorKind::NotFound,
|
||||||
|
"Could not find Area Array Location",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let mut area_array_count = 1;
|
||||||
|
loop {
|
||||||
|
let area_array =
|
||||||
|
windows_pe_file.read_addr::<u64>(area_array_addr + area_array_count as u64 * 8)?;
|
||||||
|
if area_array == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = windows_pe_file.read_addr::<u64>(area_array)?;
|
||||||
|
if id != area_array_count as u64 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
area_array_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"\x1b[32m\x1b[1mArea Array\x1b[0m: \x1b[4m{:#x} ({} items)\x1b[0m",
|
||||||
|
area_array_addr, area_array_count
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
area_array_addr,
|
||||||
|
area_array_count,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user