code wiki / _hdl_build / nx_nxe_exec_probe.nx
nx_nxe_exec_probe.nx source
↩ module page · 32 lines · 2093 B
1// nx_nxe_exec_probe.nx -- PROBE (cardinal rule 2: verify the runtime primitive before building on it).
2// Question: can we (a) mmap RWX memory, (b) write raw x86_64 machine code into it, (c) cast the raw address to a
3// typed function pointer and CALL it -- i.e. genuinely EXECUTE loaded code on this machine? If yes, the native NXE
4// loader can verify-then-execute. Payload = int64 f(int64 x){ return x*x + 1; } in SysV ABI (arg rdi, ret rax):
5// 48 89 f8 mov rax, rdi
6// 48 0f af c7 imul rax, rdi
7// 48 ff c0 inc rax
8// c3 ret
9// f(7) must be 50. expect_exit: 0
10import "nx_syscalls.nx"
11const K_MAGIC_4096: i64 = 4096
12
13func g_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
14func g_pn(v: i64) -> i64 { let b: *u8=sys_mmap(28); var x: i64=v; if x<0{b[0]=45;sys_write(1,b,1);x=0-x} if x==0{b[0]=48;sys_write(1,b,1);return 0} var d: i64=0; var y: i64=x; while y>0{d=d+1;y=y/10} var i: i64=d-1; y=x; while i>=0{b[i]=(48+(y%10)) as u8;y=y/10;i=i-1} sys_write(1,b,d); return 0 }
15
16// PROT_READ|PROT_WRITE|PROT_EXEC = 7, MAP_PRIVATE|MAP_ANONYMOUS = 0x22
17func mmap_rwx(size: i64) -> *u8 { let r: i64 = __syscall(SYS_MMAP, 0, size, 7, 0x22, -1, 0); return r as *u8 }
18
19func main() -> i64 {
20 g_puts("nx_nxe_exec_probe (can we mmap RWX + execute raw machine code via a cast fn-ptr?)\n" as *u8)
21 let code: *u8 = mmap_rwx(K_MAGIC_4096)
22 if (code as i64) < 0 { g_puts(" mmap RWX FAILED\n" as *u8); sys_exit(1); return 1 }
23 code[0]=0x48 as u8; code[1]=0x89 as u8; code[2]=0xf8 as u8
24 code[3]=0x48 as u8; code[4]=0x0f as u8; code[5]=0xaf as u8; code[6]=0xc7 as u8
25 code[7]=0x48 as u8; code[8]=0xff as u8; code[9]=0xc0 as u8
26 code[10]=0xc3 as u8
27 let fp: func(i64) -> i64 = (code as i64) as func(i64) -> i64
28 let r: i64 = fp(7)
29 g_puts(" executed loaded code: f(7)="); g_pn(r); g_puts(" (expect 50)\n" as *u8)
30 if r==50 { g_puts("verdict=GREEN (RWX mmap + raw-code execution via cast fn-ptr WORKS)\n" as *u8); sys_exit(0); return 0 }
31 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1
32}