diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..e3cbd3f --- /dev/null +++ b/src/main.rs @@ -0,0 +1,63 @@ +use std::env; +use std::error::Error; +use std::fs::OpenOptions; +use std::io::stdin; +use std::os::windows::fs::FileExt; +use std::process::{Command, exit}; + +fn pause() { + // call pause command to keep the console open, so the user can read infos/errors + Command::new("cmd").args(&["/C", "pause"]).spawn().expect("failed to execute pause command"); +} + +fn abort(message: &str, error: Option<&dyn Error>) -> ! { + if let Some(error) = error { + println!("{:}", error); + } + println!("{}. Abort!", message); + pause(); + exit(1); +} + +fn main() { + const IMAGE_FILE_LARGE_ADDRESS_AWARE: u8 = 0x20; + let mut buffer2 = [0u8; 2]; + let mut buffer4 = [0u8; 4]; + let args= env::args().collect::<Vec<String>>(); + let path = match args.get(1) { + None => abort("Didn't receive path to EXE as argument", None), + Some(path) => path + }; + if !path.to_lowercase().ends_with(".exe") { + abort("Argument is not an EXE", None); + } + println!("Working on: {}", path); + let file = match OpenOptions::new().read(true).write(true).open(path) { + Ok(file) => file, + Err(error) => abort("Failed to open EXE in read/write mode", Some(&error)) + }; + if let Err(error) = file.seek_read(&mut buffer4, 0x3C) { + abort("Failed to read e_lfanew of MS-DOS stub", Some(&error)); + } + let address_coff_characteristics = (u32::from_le_bytes(buffer4) + 0x4 + 0x12) as u64; // real data starts after "PE\0\0" string (first 4 Bytes) + if let Err(error) = file.seek_read(&mut buffer2, address_coff_characteristics) { + abort("Failed to read Characteristics from COFF file header", Some(&error)); + } + let is_laa_enabled = buffer2[0] & IMAGE_FILE_LARGE_ADDRESS_AWARE != 0; + println!("LAA currently enabled: {}\nDo you want to change that [y/n]?", is_laa_enabled); + let mut input = String::new(); + if let Err(error) = stdin().read_line(&mut input) { + abort("Failed to read user input from stdin", Some(&error)); + } + match input.to_lowercase().trim() { + "y" => {}, + "n" => return, + _ => abort("Invalid input", None) + } + buffer2[0] ^= IMAGE_FILE_LARGE_ADDRESS_AWARE; // flip bit + if let Err(error) = file.seek_write(buffer2.as_slice(), address_coff_characteristics) { + abort("Failed to write modification back to file", Some(&error)); + } + println!("Modification written to disk."); + pause(); +} |