initial
This commit is contained in:
commit
8e183c25f1
|
@ -0,0 +1 @@
|
|||
/target
|
|
@ -0,0 +1,119 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||
|
||||
[[package]]
|
||||
name = "alloc-no-stdlib"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
|
||||
|
||||
[[package]]
|
||||
name = "alloc-stdlib"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brotli"
|
||||
version = "8.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9991eea70ea4f293524138648e41ee89b0b2b12ddef3b255effa43c8056e0e0d"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
"alloc-stdlib",
|
||||
"brotli-decompressor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brotli-decompressor"
|
||||
version = "5.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
"alloc-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.37.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03fd943161069e1768b4b3d050890ba48730e590f57e56d4aa04e7e090e61b4a"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"memchr",
|
||||
"ruzstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruzstd"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3640bec8aad418d7d03c72ea2de10d5c646a598f9883c7babc160d91e3c1b26c"
|
||||
dependencies = [
|
||||
"twox-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauriunpack"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"brotli",
|
||||
"object",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "twox-hash"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b907da542cbced5261bd3256de1b3a1bf340a3d37f93425a07362a1d687de56"
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "tauriunpack"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
brotli = "8"
|
||||
object = "0.37"
|
|
@ -0,0 +1,99 @@
|
|||
use std::{
|
||||
env,
|
||||
error::Error,
|
||||
fmt, fs,
|
||||
io::{Cursor, Read},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use object::{Object, ObjectSection, read::pe::PeFile64};
|
||||
|
||||
type Result<T> = std::result::Result<T, Box<dyn Error>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum MyError {
|
||||
NoParentDir,
|
||||
NoSection,
|
||||
NoData,
|
||||
}
|
||||
impl fmt::Display for MyError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::NoParentDir => write!(f, "no parent dir for path"),
|
||||
Self::NoSection => write!(f, "no section found"),
|
||||
Self::NoData => write!(f, "no data"),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Error for MyError {}
|
||||
|
||||
fn next_u64_le(r: &mut impl Read) -> Result<u64> {
|
||||
let mut b = [0u8; 8];
|
||||
r.read_exact(&mut b)?;
|
||||
Ok(u64::from_le_bytes(b))
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// read args
|
||||
let mut args = env::args().skip(1);
|
||||
let table_base: u64 = args
|
||||
.next()
|
||||
.and_then(|s| u64::from_str_radix(&s, 16).ok())
|
||||
.expect("no table base provided");
|
||||
let table_len: u64 = args
|
||||
.next()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.expect("no table len provided");
|
||||
let path = args.next().expect("no *.exe provided");
|
||||
|
||||
// read file
|
||||
let data = fs::read(path)?;
|
||||
|
||||
// parse file
|
||||
let file = PeFile64::parse(&*data)?;
|
||||
|
||||
// find section
|
||||
let section = file
|
||||
.sections()
|
||||
.find(|s| (s.address()..s.address() + s.size()).contains(&table_base))
|
||||
.ok_or(MyError::NoSection)?;
|
||||
|
||||
// dump table
|
||||
for i in 0..table_len {
|
||||
// get entry
|
||||
let ptr_entry = table_base + 32 * i;
|
||||
let entry = section.data_range(ptr_entry, 32)?.ok_or(MyError::NoData)?;
|
||||
|
||||
// parse entry
|
||||
let mut c = Cursor::new(entry);
|
||||
let ptr_name = next_u64_le(&mut c)?;
|
||||
let len_name = next_u64_le(&mut c)?;
|
||||
let ptr_data = next_u64_le(&mut c)?;
|
||||
let len_data = next_u64_le(&mut c)?;
|
||||
|
||||
// read name/data
|
||||
let name = section
|
||||
.data_range(ptr_name, len_name)?
|
||||
.ok_or(MyError::NoData)?;
|
||||
let data = section
|
||||
.data_range(ptr_data, len_data)?
|
||||
.ok_or(MyError::NoData)?;
|
||||
|
||||
// print name
|
||||
let mut name = String::from_utf8(name.to_vec())?;
|
||||
println!("saving {name}");
|
||||
|
||||
// make path
|
||||
let mut p = PathBuf::from("./save");
|
||||
name.insert(0, '.');
|
||||
p.push(name);
|
||||
|
||||
// open file
|
||||
let parent = p.parent().ok_or(MyError::NoParentDir)?;
|
||||
fs::create_dir_all(parent)?;
|
||||
let mut file = fs::File::create_new(p)?;
|
||||
brotli::BrotliDecompress(&mut &data[..], &mut file)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue