Basically, this answer does not add any thing more essential than one of @PeterT. It's modified a little bit to write arbitrary bytes (as we want) on the page boundary:
use std::{
mem::{transmute, MaybeUninit},
ptr,
};
use winapi::{
shared::{minwindef::TRUE, ntdef::NULL},
um::{
memoryapi::{VirtualAlloc, VirtualFree, VirtualProtect},
sysinfoapi::GetSystemInfo,
winnt::{
MEM_COMMIT, MEM_DECOMMIT, MEM_RESERVE, PAGE_EXECUTE_READWRITE,
},
},
};
fn main() {
let page_size = {
let mut sys_info = MaybeUninit::uninit();
let sys_info = unsafe {
GetSystemInfo(sys_info.as_mut_ptr());
sys_info.assume_init()
};
sys_info.dwPageSize
} as usize;
let region_base = unsafe {
VirtualAlloc(
NULL,
page_size * 2,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE,
)
} as usize;
println!("Allocated region base: 0x{:x}", region_base);
let ud1_addr = region_base + page_size - 0x2;
print!("Writing 0f b9 27 (ud1 esp, [rdi]) to: 0x{:x}... ", ud1_addr);
let ud1_ptr = ud1_addr as *mut u8;
unsafe {
ptr::write(ud1_ptr, 0x0f);
ptr::write(ud1_ptr.add(1), 0xb9);
ptr::write(ud1_ptr.add(2), 0x27);
};
println!("ok");
let last_page_addr: usize = region_base + page_size;
print!("Decommitting the last page at 0x{:x}... ", last_page_addr);
let free_ok = unsafe { VirtualFree(last_page_addr as _, page_size, MEM_DECOMMIT) };
if free_ok == TRUE {
println!("ok. Executing: ud1 esp, [rdi]");
let ud1: extern "C" fn() = unsafe { transmute(ud1_ptr as *const ()) };
ud1();
} else {
println!("failed");
}
}