nx_pe_spawn_test.nx source
↩ module page · 40 lines · 1518 B
1// nx_pe_spawn_test.nx -- substrate emits PE that spawns a child process.
2
3import "nx_syscalls.nx"
4import "nx_hal.nx"
5import "nx_pe_writer.nx"
6
7func main() -> i64 {
8 let buf: *u8 = nx_hal_alloc_pages(PE_SPAWN_FILE_SIZE)
9 if (buf as i64) == 0 { return 1 }
10
11 let rc: i64 = nx_pe_emit_spawn42(buf)
12 if rc != NX_PE_OK { return 2 }
13
14 // Spot-checks.
15 if buf[0] != 0x4D { return 10 } // 'M'
16 if buf[0x80] != 0x50 { return 11 } // 'P'
17 if buf[0x86] != 0x03 { return 12 } // 3 sections
18 // .text first byte: sub rsp, 0xE8 (48 81 EC E8)
19 if buf[0x200] != 0x48 { return 13 }
20 if buf[0x201] != 0x81 { return 14 }
21 if buf[0x203] != 0xE8 { return 15 }
22 // .rdata cmdline UTF-16 first wchar 'c' = 0x63 0x00
23 if buf[0x400] != 0x63 { return 16 }
24 if buf[0x401] != 0x00 { return 17 }
25 if buf[0x404] != 0x64 { return 18 } // 'd' at byte offset 4 (wchar 2)
26 // .idata: "CreateProcessW" at RVA 0x3078 = file 0x678
27 if buf[0x67A] != 0x43 { return 19 } // 'C'
28 if buf[0x67B] != 0x72 { return 20 } // 'r'
29 if buf[0x687] != 0x57 { return 21 } // 'W' at end
30 // "kernel32.dll" at file 0x6C6
31 if buf[0x6C6] != 0x6B { return 22 } // 'k'
32
33 let out_path: *u8 = "/mnt/c/Users/elder/nishi-core/nxc2/_offc/nx_pe_spawn.exe" as *u8
34 let wrc: i64 = nx_pe_write_to_file(out_path, buf, PE_SPAWN_FILE_SIZE)
35 if wrc != NX_PE_OK { return 70 }
36
37 let msg: *u8 = "[substrate] CreateProcessW PE32+ written (2048 bytes)\n" as *u8
38 sys_write(1, msg, 54)
39 return 0
40}