mirror of
https://github.com/entropykit/entropia
synced 2026-06-24 06:05:04 +00:00
46 lines
1.7 KiB
Rust
46 lines
1.7 KiB
Rust
// SPDX-License-Identifier: Apache-2.0
|
|
// run_bin.rs — load an EntropyKit .bin and execute it. Linux x86-64 only.
|
|
// Build: rustc -O run_bin.rs -o run_bin
|
|
// Use: ./run_bin example/gc_demo.bin
|
|
//
|
|
// On Windows the equivalent is the bundled `example/sclauncher64.exe`,
|
|
// which does VirtualAlloc(PAGE_EXECUTE_READWRITE) + memcpy + call.
|
|
|
|
use std::env;
|
|
use std::ffi::c_void;
|
|
use std::fs;
|
|
|
|
extern "C" {
|
|
fn mmap(addr: *mut c_void, len: usize, prot: i32, flags: i32, fd: i32, off: i64) -> *mut c_void;
|
|
fn munmap(addr: *mut c_void, len: usize) -> i32;
|
|
}
|
|
const PROT_READ: i32 = 1;
|
|
const PROT_WRITE: i32 = 2;
|
|
const PROT_EXEC: i32 = 4;
|
|
const MAP_PRIVATE: i32 = 0x02;
|
|
const MAP_ANON: i32 = 0x20;
|
|
|
|
fn main() {
|
|
let path = env::args().nth(1).expect("usage: run_bin <file.bin>");
|
|
let bytes = fs::read(&path).expect("read");
|
|
let len = (bytes.len() + 4095) & !4095;
|
|
|
|
unsafe {
|
|
let p = mmap(std::ptr::null_mut(), len,
|
|
PROT_READ | PROT_WRITE | PROT_EXEC,
|
|
MAP_PRIVATE | MAP_ANON, -1, 0);
|
|
assert!(p as isize != -1, "mmap failed");
|
|
std::ptr::copy_nonoverlapping(bytes.as_ptr(), p as *mut u8, bytes.len());
|
|
|
|
// EntropyKit emits Win64 calling convention (args in rcx/rdx/r8/r9).
|
|
// On Linux rcx isn't a "host services" pointer; main's prologue still
|
|
// saves it, but `shared.*` will see NULL and short-circuit to zero.
|
|
// For zero-arg main(), rcx is irrelevant — rax holds the return value.
|
|
let entry: extern "win64" fn() -> i64 = std::mem::transmute(p);
|
|
let result = entry();
|
|
println!("returned: {} (0x{:x})", result, result);
|
|
|
|
munmap(p, len);
|
|
}
|
|
}
|