diff --git a/.editorconfig b/.editorconfig old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.rustfmt.toml b/.rustfmt.toml old mode 100644 new mode 100755 diff --git a/Cargo.lock b/Cargo.lock index 74b4ffb..452041e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,98 +2,94 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "elfloader" version = "0.1.0" dependencies = [ - "goblin", - "libc", -] - -[[package]] -name = "goblin" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb07a4ffed2093b118a525b1d8f5204ae274faed5604537caf7135d0f18d9887" -dependencies = [ - "log", - "plain", - "scroll", + "memfd-exec", + "winapi", ] [[package]] name = "libc" -version = "0.2.151" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] -name = "log" -version = "0.4.20" +name = "memfd-exec" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" - -[[package]] -name = "proc-macro2" -version = "1.0.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" +checksum = "e627eb44f3789e87dccac3f4c7279a608cbf14ff71f2c54f122f44a07e2ca338" dependencies = [ - "unicode-ident", + "libc", + "nix", ] [[package]] -name = "quote" -version = "1.0.35" +name = "memoffset" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ - "proc-macro2", + "autocfg", ] [[package]] -name = "scroll" -version = "0.12.0" +name = "nix" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ - "scroll_derive", + "bitflags", + "cfg-if", + "libc", + "memoffset", + "pin-utils", ] [[package]] -name = "scroll_derive" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "syn" -version = "2.0.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "testexec" +name = "pin-utils" version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "unicode-ident" -version = "1.0.12" +name = "winapi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml old mode 100644 new mode 100755 index 45ad6ff..2841506 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,12 +2,15 @@ name = "elfloader" version = "0.1.0" edition = "2021" +description = "elfloader" +authors = ["davidontop "] +readme = "README.md" +documentation = "https://docs.rs/elfloader" +license = "MIT" +repository = "https://git.davidon.top/public/elfloader.git" -[workspace] -members = [ - "testexec" -] +[target.'cfg(target_os = "linux")'.dependencies] +memfd-exec = "0.2.1" -[dependencies] -goblin = "0.8.0" -libc = "0.2.151" +[target.'cfg(target_os = "windows")'.dependencies] +winapi = "0.3.9" diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 index 3c3602f..9b84d0d --- a/LICENSE +++ b/LICENSE @@ -1,26 +1,22 @@ - GLWTS(Good Luck With That Shit) Public License - Copyright (c) Every-fucking-one +MIT License -Everyone is permitted to copy, distribute, modify, merge, sell, publish, -sublicense or whatever the fuck they want with this software but at their -OWN RISK. +Copyright (c) 2023 DavidOnTop - Preamble +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The author has absolutely no fucking clue what the code in this project -does. It might just fucking work or not, there is no third option. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. - GOOD LUCK WITH THAT SHIT PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION, AND MODIFICATION - - 0. You just DO WHATEVER THE FUCK YOU WANT TO as long as you NEVER LEAVE -A FUCKING TRACE TO TRACK THE AUTHOR of the original product to blame for -or held responsible. - -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -Good luck and Godspeed. diff --git a/README.md b/README.md new file mode 100755 index 0000000..2cb4d18 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# elfloader diff --git a/src/lib.rs b/src/lib.rs new file mode 100755 index 0000000..386cb96 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,6 @@ +#[cfg(target_os = "linux")] +pub mod linux; +#[cfg(target_os = "windows")] +pub mod win; + +pub fn run(name: String, executable: Vec) { todo!() } diff --git a/src/linux.rs b/src/linux.rs new file mode 100644 index 0000000..90bc8a5 --- /dev/null +++ b/src/linux.rs @@ -0,0 +1,18 @@ +use std::io::Write; + +use memfd_exec::{MemFdExecutable, Stdio}; + +pub fn run(name: String, elf: Vec, stdin: Vec) -> std::io::Result<()> { + let cmd = MemFdExecutable::new(name, elf.as_slice()) + .stdout(Stdio::piped()) + .spawn()?; + + let mut si = cmd.stdin.ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + "Can not get ChildStdin handle", + ))?; + si.write_all(stdin.as_slice())?; + si.flush()?; + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index c651ed3..0000000 --- a/src/main.rs +++ /dev/null @@ -1,34 +0,0 @@ -use std::os::fd::FromRawFd; - -fn main() { - let file = if std::fs::metadata("target/release/testexec").is_ok() { - std::fs::File::open("target/release/testexec").unwrap() - } else if std::fs::metadata("target/debug/testexec").is_ok() { - std::fs::File::open("target/debug/testexec").unwrap() - } else { - panic!("testexec not found"); - }; - let filename = "testexec"; - let name = std::ffi::CString::new(filename).unwrap(); - let name = name.as_ptr(); - let mem_file_fd = unsafe { libc::memfd_create(name, 0) }; - let mem_file = unsafe { std::fs::File::from_raw_fd(mem_file_fd) }; - let mut reader = std::io::BufReader::new(file); - let mut writer = std::io::BufWriter::new(&mem_file); - std::io::copy(&mut reader, &mut writer).unwrap(); - - let filepath = std::ffi::CString::new(format!("/proc/self/fd/{}", mem_file_fd)).unwrap(); - let filepath = filepath.as_ptr(); - let argv_owned = vec![std::ffi::CString::new(filename).unwrap()]; - let argv: Vec<*const libc::c_char> = argv_owned.iter().map(|x| x.as_ptr()).chain(std::iter::once(std::ptr::null())).collect(); - let envp_owned = std::env::vars_os() - .map(|(k, v)| { - let mut kv = k.into_string().unwrap(); - kv.push('='); - kv.push_str(&v.into_string().unwrap()); - std::ffi::CString::new(kv).unwrap() - }).collect::>(); - let envp: Vec<*const libc::c_char> = envp_owned.iter().map(|x| x.as_ptr()).chain(std::iter::once(std::ptr::null())).collect(); - unsafe { libc::execve(filepath, argv.as_ptr(), envp.as_ptr()) }; - unsafe ; -} diff --git a/src/win.rs b/src/win.rs new file mode 100644 index 0000000..c487b66 --- /dev/null +++ b/src/win.rs @@ -0,0 +1,96 @@ +use std::{ptr, thread}; + +use winapi::um::{ + memoryapi::{VirtualAllocEx, VirtualProtectEx}, + processthreadsapi::{CreateProcessA, OpenProcess}, + winbase::CREATE_NO_WINDOW, + winnt::{PROCESS_ALL_ACCESS, SECURITY_ATTRIBUTES}, +}; + +pub fn run(name: String, pe: Vec, stdin: Vec) -> std::io::Result<()> { + let target_process_handle = unsafe { OpenProcess(PROCESS_ALL_ACCESS, false, ptr::null_mut()) }; + let base_address = unsafe { + VirtualAllocEx( + target_process_handle, + ptr::null_mut(), + 4096, + MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE, + ) + }; + + unsafe { + WriteProcessMemory( + target_process_handle, + base_address, + pe.as_ptr() as *const _, + pe.len(), + ptr::null_mut(), + ); + } + + unsafe { + VirtualProtectEx( + target_process_handle, + base_address, + ptr::null_mut(), + 4096, + PAGE_EXECUTE_READWRITE, + ); + } + + let mut sa = SECURITY_ATTRIBUTES::default(); + sa.nLength = std::mem::size_of::() as u32; + sa.lpSecurityDescriptor = ptr::null_mut(); + sa.bInheritHandle = 1; + + let mut stdout_pipe_read_handle: HANDLE = ptr::null_mut(); + + let process_creation_and_interaction = || unsafe { + if CreatePipe(&mut stdout_pipe_read_handle, &mut ptr::null_mut(), &sa, 0) == 0 { + panic!("Failed to create stdout pipe"); + } + + let success = CreateProcessA( + ptr::null(), + ptr::null(), + &sa, + ptr::null_mut(), + true, + CREATE_NO_WINDOW, + ptr::null_mut(), + ptr::null_mut(), + base_address as *mut _, + ptr::null_mut(), + &mut ptr::null_mut(), + &mut stdout_pipe_read_handle, + ptr::null_mut(), + ); + + if success == 0 { + println!("Failed to create process."); + } else { + println!("Process created successfully."); + + let stdin_handle = GetStdHandle(STD_INPUT_HANDLE); + if stdin_handle.is_null() { + panic!("Failed to get stdin handle"); + } + unsafe { + if !WriteFile( + stdin_handle, + stdin.as_ptr() as *const _, + stdin.len(), + ptr::null_mut(), + ptr::null_mut(), + ) { + panic!("Failed to write to stdin"); + } + } + } + }; + + thread::spawn(process_creation_and_interaction); + + Ok(()) +} diff --git a/testexec/Cargo.toml b/testexec/Cargo.toml deleted file mode 100644 index f1df1a8..0000000 --- a/testexec/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "testexec" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/testexec/src/main.rs b/testexec/src/main.rs deleted file mode 100644 index 9fa5de3..0000000 --- a/testexec/src/main.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - println!("Hello, i was loaded from memory!"); - std::fs::File::create("deleteme").unwrap(); -}