not crappy elfloader

This commit is contained in:
davidontop 2024-08-01 14:41:45 +02:00
parent e42a3a8134
commit 5caed9b6dc
Signed by: DavidOnTop
GPG key ID: 5D05538A45D5149F
13 changed files with 209 additions and 137 deletions

0
.editorconfig Normal file → Executable file
View file

0
.gitignore vendored Normal file → Executable file
View file

0
.rustfmt.toml Normal file → Executable file
View file

126
Cargo.lock generated
View file

@ -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"

17
Cargo.toml Normal file → Executable file
View file

@ -2,12 +2,15 @@
name = "elfloader"
version = "0.1.0"
edition = "2021"
description = "elfloader"
authors = ["davidontop <me@davidon.top>"]
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"

38
LICENSE Normal file → Executable file
View file

@ -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.

1
README.md Executable file
View file

@ -0,0 +1 @@
# elfloader

6
src/lib.rs Executable file
View file

@ -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<u8>) { todo!() }

18
src/linux.rs Normal file
View file

@ -0,0 +1,18 @@
use std::io::Write;
use memfd_exec::{MemFdExecutable, Stdio};
pub fn run(name: String, elf: Vec<u8>, stdin: Vec<u8>) -> 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(())
}

View file

@ -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::<Vec<_>>();
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 ;
}

96
src/win.rs Normal file
View file

@ -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<u8>, stdin: Vec<u8>) -> 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::<SECURITY_ATTRIBUTES>() 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(())
}

View file

@ -1,6 +0,0 @@
[package]
name = "testexec"
version = "0.1.0"
edition = "2021"
[dependencies]

View file

@ -1,4 +0,0 @@
fn main() {
println!("Hello, i was loaded from memory!");
std::fs::File::create("deleteme").unwrap();
}