code wiki / (root) / nishi_spawn_probe.nx

nishi_spawn_probe.nx source

↩ module page · 83 lines · 3628 B

1// nishi_spawn_probe.nx -- verify the GUI keystone's process-spawn imports (IAT slots 20-23): 2// CreateFileA, CreateProcessA, WaitForSingleObject, CloseHandle + generic ReadFile (19). 3// Spawns nishi_fetch.exe with stdout -> a temp file, waits, reads the file back, dumps it. 4// If this prints example.com's rendered text, in-process navigation is unblocked. 5 6import "nx_syscalls.nx" 7 8func win32(id: i64, args: *i64) -> i64 { return id } 9 10const W_ReadFile: i64 = 19 11const W_CreateFileA: i64 = 20 12const W_CreateProcessA: i64 = 21 13const W_WaitForSingleObject: i64 = 22 14const W_CloseHandle: i64 = 23 15 16func w32(p: *u8, o: i64, v: i64) -> i64 { 17 p[o]=(v&0xff) as u8; p[o+1]=((v>>8)&0xff) as u8; p[o+2]=((v>>16)&0xff) as u8; p[o+3]=((v>>24)&0xff) as u8; return 0 18} 19func wp(p: *u8, o: i64, v: i64) -> i64 { w32(p,o,v); w32(p,o+4, v / 4294967296); return 0 } 20func rd32(p: *u8, o: i64) -> i64 { return (p[o]&0xff)|((p[o+1]&0xff)<<8)|((p[o+2]&0xff)<<16)|((p[o+3]&0xff)<<24) } 21func rp(p: *u8, o: i64) -> i64 { return rd32(p,o) | (rd32(p,o+4) * 4294967296) } 22func scopy(dst: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[o+i]=s[i]; i=i+1 } return o+i } 23 24func main() -> i64 { 25 let a: *i64 = sys_mmap(256) as *i64 26 27 let cmd: *u8 = sys_mmap(1024) 28 var cl: i64 = scopy(cmd, 0, "_offc/nishi_fetch.exe https://example.com/" as *u8) 29 cmd[cl] = 0 as u8 30 let app: *u8 = "_offc/nishi_fetch.exe" as *u8 31 let fname: *u8 = "_nav_page.txt" as *u8 32 33 // SECURITY_ATTRIBUTES: nLength=24, lpSD=0, bInheritHandle=1 34 let sa: *u8 = sys_mmap(32) 35 w32(sa, 0, 24); wp(sa, 8, 0); w32(sa, 16, 1) 36 37 // CreateFileA(temp, GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_ALWAYS, NORMAL, 0) 38 a[0]=fname as i64; a[1]=0x40000000; a[2]=1; a[3]=sa as i64; a[4]=2; a[5]=0x80; a[6]=0 39 let hout: i64 = win32(W_CreateFileA, a) 40 if hout == 0 { sys_exit(101); return 1 } 41 if hout == (0 - 1) { sys_exit(102); return 1 } 42 43 // STARTUPINFOA (104B): cb@0, dwFlags@60=USESTDHANDLES, hStdInput@80, hStdOutput@88, hStdError@96 44 let si: *u8 = sys_mmap(128) 45 w32(si, 0, 104); w32(si, 60, 0x100); wp(si, 80, 0); wp(si, 88, hout); wp(si, 96, hout) 46 let pi: *u8 = sys_mmap(32) // PROCESS_INFORMATION: hProcess@0, hThread@8 47 48 // CreateProcessA(app, cmd, 0, 0, bInherit=1, CREATE_NO_WINDOW, 0, 0, si, pi) 49 a[0]=app as i64; a[1]=cmd as i64; a[2]=0; a[3]=0; a[4]=1; a[5]=0x08000000; a[6]=0; a[7]=0; a[8]=si as i64; a[9]=pi as i64 50 win32(W_CreateProcessA, a) 51 let hproc: i64 = rp(pi, 0) 52 if hproc == 0 { sys_exit(103); return 1 } 53 54 a[0]=hproc; a[1]=0xFFFFFFFF; win32(W_WaitForSingleObject, a) 55 a[0]=hproc; win32(W_CloseHandle, a) 56 a[0]=rp(pi,8);win32(W_CloseHandle, a) 57 a[0]=hout; win32(W_CloseHandle, a) 58 59 // CreateFileA(temp, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, NORMAL, 0) 60 a[0]=fname as i64; a[1]=0x80000000; a[2]=1; a[3]=0; a[4]=3; a[5]=0x80; a[6]=0 61 let hin: i64 = win32(W_CreateFileA, a) 62 if hin == (0 - 1) { sys_exit(104); return 1 } 63 64 let buf: *u8 = sys_mmap(1048576) 65 let got: *u8 = sys_mmap(16) 66 var total: i64 = 0 67 var go: i64 = 1 68 while go == 1 { 69 w32(got, 0, 0) 70 a[0]=hin; a[1]=(buf as i64)+total; a[2]=1048576-total; a[3]=got as i64; a[4]=0 71 win32(W_ReadFile, a) 72 let n: i64 = rd32(got, 0) 73 if n <= 0 { go = 0 } else { total = total + n } 74 if total >= 1048576 { go = 0 } 75 } 76 a[0]=hin; win32(W_CloseHandle, a) 77 78 sys_write(1, buf, 90) 79 sys_write(1, "\n" as *u8, 1) 80 if total <= 0 { sys_exit(105); return 1 } 81 sys_exit(0) 82 return 0 83}