initial commit
This commit is contained in:
parent
a6a6bed5de
commit
d0bd1dd405
|
@ -14,3 +14,5 @@ Cargo.lock
|
||||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||||
*.pdb
|
*.pdb
|
||||||
|
|
||||||
|
# IntelliJ IDEA
|
||||||
|
.idea
|
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "laa_toggle"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="RUST_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,76 @@
|
||||||
|
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_DOS_HEADER_E_LFANEW: u64 = 0x3C;
|
||||||
|
const IMAGE_FILE_LARGE_ADDRESS_AWARE: u8 = 0x20;
|
||||||
|
const IMAGE_FILE_MACHINE_AMD64: u16 = 0x8664;
|
||||||
|
const IMAGE_FILE_MACHINE_I386: u16 = 0x14C;
|
||||||
|
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, IMAGE_DOS_HEADER_E_LFANEW) {
|
||||||
|
abort("Failed to read e_lfanew of MS DOS stub", Some(&error));
|
||||||
|
}
|
||||||
|
let address_coff_machine = (u32::from_le_bytes(buffer4) + 0x4) as u64; // real data starts after "PE\0\0" string
|
||||||
|
if let Err(error) = file.seek_read(&mut buffer2, address_coff_machine) {
|
||||||
|
abort("Failed to read Machine of PE header", Some(&error));
|
||||||
|
}
|
||||||
|
let machine = u16::from_le_bytes(buffer2);
|
||||||
|
match machine {
|
||||||
|
IMAGE_FILE_MACHINE_I386 => {},
|
||||||
|
IMAGE_FILE_MACHINE_AMD64 => abort("This binary is 64 bit - LAA is not needed", None),
|
||||||
|
_ => abort(&*format!("Unsupported machine type: {}", machine), None)
|
||||||
|
}
|
||||||
|
let address_coff_characteristics = address_coff_machine + 0x12;
|
||||||
|
if let Err(error) = file.seek_read(&mut buffer2, address_coff_characteristics) {
|
||||||
|
abort("Failed to read Characteristics from PE 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();
|
||||||
|
}
|
Loading…
Reference in New Issue