Windows decryption no GUI
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
1935
Cargo.lock
generated
Normal file
1935
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "gd_save_browser"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
rfd = "0.15.0"
|
||||
base64 = "0.22.1"
|
||||
flate2 = "1.0.34"
|
||||
dirs = "5.0.1"
|
1
src/constants.rs
Normal file
1
src/constants.rs
Normal file
@ -0,0 +1 @@
|
||||
pub const XOR_KEY: u8 = 0xB;
|
22
src/main.rs
Normal file
22
src/main.rs
Normal file
@ -0,0 +1,22 @@
|
||||
mod constants;
|
||||
mod util;
|
||||
|
||||
use constants::XOR_KEY;
|
||||
use util::decrypt::*;
|
||||
use util::file::*;
|
||||
use util::xml::*;
|
||||
|
||||
fn main() {
|
||||
let data: Vec<u8> =
|
||||
gz_decompress(&base64_decode(&xor_decrypt(&get_dat_data(), XOR_KEY)).unwrap());
|
||||
|
||||
match validate_xml(&data) {
|
||||
Ok(_) => {
|
||||
println!("Decryption successful");
|
||||
write_decrypted_data(&data, prompt_output_path());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Error: {e}");
|
||||
}
|
||||
}
|
||||
}
|
31
src/util/decrypt.rs
Normal file
31
src/util/decrypt.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use base64::{engine::general_purpose::URL_SAFE, DecodeError, Engine};
|
||||
use flate2::read::GzDecoder;
|
||||
use std::io::Read;
|
||||
|
||||
// Step 1
|
||||
pub fn xor_decrypt(data: &[u8], key: u8) -> Vec<u8> {
|
||||
data.iter().map(|byte| byte ^ key).collect()
|
||||
}
|
||||
|
||||
// Step 2
|
||||
pub fn base64_decode(data: &[u8]) -> Result<Vec<u8>, DecodeError> {
|
||||
let url_safe_data: Vec<u8> = data
|
||||
.iter()
|
||||
.filter(|&&byte| byte != 0)
|
||||
.map(|&byte| match byte {
|
||||
b'+' => b'-',
|
||||
b'/' => b'_',
|
||||
_ => byte,
|
||||
})
|
||||
.collect();
|
||||
|
||||
URL_SAFE.decode(url_safe_data)
|
||||
}
|
||||
|
||||
// Step 3
|
||||
pub fn gz_decompress(data: &[u8]) -> Vec<u8> {
|
||||
let mut decoder: GzDecoder<&[u8]> = GzDecoder::new(data);
|
||||
let mut decompressed: Vec<u8> = Vec::new();
|
||||
decoder.read_to_end(&mut decompressed).unwrap();
|
||||
decompressed
|
||||
}
|
33
src/util/file.rs
Normal file
33
src/util/file.rs
Normal file
@ -0,0 +1,33 @@
|
||||
use dirs::{data_local_dir, desktop_dir};
|
||||
use rfd::FileDialog;
|
||||
use std::{fs::File, io::Read, io::Write, path::PathBuf};
|
||||
|
||||
pub fn get_dat_data() -> Vec<u8> {
|
||||
let path: PathBuf = FileDialog::new()
|
||||
.set_title("Select Geometry Dash Save")
|
||||
.set_file_name("CCGameManager.dat")
|
||||
.add_filter("Geometry Dash Save", &["dat"])
|
||||
.set_directory(data_local_dir().unwrap())
|
||||
.pick_file()
|
||||
.unwrap();
|
||||
|
||||
let mut file: File = File::open(path).unwrap();
|
||||
let mut data: Vec<u8> = Vec::new();
|
||||
file.read_to_end(&mut data).unwrap();
|
||||
data
|
||||
}
|
||||
|
||||
pub fn prompt_output_path() -> PathBuf {
|
||||
FileDialog::new()
|
||||
.set_title("Select Output Location")
|
||||
.set_file_name("CCGameManager.xml")
|
||||
.add_filter("Geometry Dash Decrypted Save", &["xml"])
|
||||
.set_directory(desktop_dir().unwrap())
|
||||
.save_file()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn write_decrypted_data(data: &[u8], output_path: PathBuf) {
|
||||
let mut output_file: File = File::create(output_path).unwrap();
|
||||
output_file.write_all(data).unwrap()
|
||||
}
|
3
src/util/mod.rs
Normal file
3
src/util/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
pub mod decrypt;
|
||||
pub mod file;
|
||||
pub mod xml;
|
12
src/util/xml.rs
Normal file
12
src/util/xml.rs
Normal file
@ -0,0 +1,12 @@
|
||||
pub fn validate_xml(xml: &[u8]) -> Result<(), String> {
|
||||
let xml_str: String = String::from_utf8_lossy(xml).to_string();
|
||||
|
||||
if xml_str.starts_with("<?xml version=\"1.0\"?>") {
|
||||
return Ok(());
|
||||
} else {
|
||||
return Err("Invalid/missing XML header".to_string());
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
Ok(())
|
||||
}
|
Reference in New Issue
Block a user