1use std::io;
2use std::fmt;
3
4#[derive(Debug, Clone)]
6pub struct MemCopyError;
7
8impl fmt::Display for MemCopyError {
9 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10 write!(f, "could not copy code over to the executable memory area")
11 }
12}
13
14impl std::error::Error for MemCopyError {}
15
16pub fn string_to_bytes(hexstring: &str) -> Result<Vec<u8>, std::num::ParseIntError> {
18 hexstring.split_whitespace()
19 .map(|s| u8::from_str_radix(s, 16))
20 .collect()
21}
22
23pub fn execute(code: &[u8]) -> Result<i32, Box<dyn std::error::Error>> {
25 let size = code.len();
26 let executable_area = unsafe {
27 libc::mmap(
28 std::ptr::null_mut(),
29 size,
30 libc::PROT_WRITE | libc::PROT_EXEC,
31 libc::MAP_ANONYMOUS | libc::MAP_PRIVATE,
32 -1,
33 0,
34 ) as *mut u8
35 };
36
37 if executable_area.is_null() {
38 return Err(Box::new(io::Error::last_os_error()));
39 }
40
41 unsafe {
42 std::ptr::copy_nonoverlapping(code.as_ptr(), executable_area, size);
43 let f: extern "C" fn() -> i32 = std::mem::transmute(executable_area);
44 Ok(f())
45 }
46}