Skip to content

Instantly share code, notes, and snippets.

@roktas
Forked from iximeow/stub.rs
Created January 30, 2022 17:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roktas/899e5a47944d3fb891f97d4e901b7dbd to your computer and use it in GitHub Desktop.
Save roktas/899e5a47944d3fb891f97d4e901b7dbd to your computer and use it in GitHub Desktop.
glue between nasm and exec
use std::io::Write;
use std::process::Command;
extern "C" {
fn mprotect(addr: *const u8, len: usize, prot: u32) -> u32;
}
fn main() {
let mut args = std::env::args();
let _ = args.next();
let fname = if let Some(n) = args.next() {
n
} else {
return;
};
let res = Command::new("/usr/bin/nasm")
.args(["-o", "/dev/stdout", "-f", "bin", &fname])
.output()
.expect("process runs");
if res.status.success() {
unsafe {
let code = res.stdout.as_ptr();
let len = res.stdout.len();
// round down because we might be offset in the first page
let prefix = (code as isize) & 0x0fff;
let pages_start = code.offset(-prefix);
let code_end = len + prefix as usize;
// rwx
if mprotect(pages_start, code_end, 7) != 0 {
return;
}
let f: fn() -> ! = std::mem::transmute::<*const u8, fn() -> !>(code);
f();
}
} else {
let mut out = std::io::stdout();
out.write_all(&res.stdout).unwrap();
out.flush().unwrap();
let mut err = std::io::stderr();
err.write_all(&res.stderr).unwrap();
err.flush().unwrap();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment