code wiki / (root) / nx_pe_compile_win_fread.nx

nx_pe_compile_win_fread.nx source

↩ module page · 194 lines · 12145 B

1// nx_pe_compile_win_fread.nx -- W-NET-5a: native file reading (CreateFileA + ReadFile), the capability 2// needed to serve the REAL Elder ui/dist from disk on :5173. De-risk standalone before integrating into 3// the HTTP server. Reads C:/Users/elder/elder-ai-platform/ui/dist/index.html and returns its byte count. 4// kernel32 only { ExitProcess, GetProcessHeap, HeapAlloc, CreateFileA, ReadFile } -- 1 DLL, 5 funcs. 5// CreateFileA takes the ASCII path directly (Windows accepts forward slashes), no UTF-16 needed. 6// lineage_id: substrate_pe_compile_win_fread_v1 7import "nx_syscalls.nx" 8import "nxasm_x86.nx" 9import "nx_pe_writer.nx" 10 11const FR_CODE_CAP: i64 = 1048576 12const FR_FILE_SIZE: i64 = 0x800 13const FR_STUB_LEN: i64 = 18 14const FR_TEXT_CAP: i64 = 0x400 15const FR_RVA_TEXT: i64 = 0x1000 16const FR_RVA_IDATA: i64 = 0x2000 17const FR_FOFF_TEXT: i64 = 0x200 18const FR_FOFF_IDATA:i64 = 0x600 19const FR_IAT_EXIT: i64 = 0x2058 20const FR_IAT_GPH: i64 = 0x2060 21const FR_IAT_HA: i64 = 0x2068 22const FR_IAT_CFA: i64 = 0x2070 23const FR_IAT_RF: i64 = 0x2078 24const FR_L_HALLOC: i64 = 29 25const FR_L_FOPEN: i64 = 57 26const FR_L_FREAD: i64 = 42 27 28func fr_lbloff(src: *u8, lab_off: *i64, lab_len: *i64, lab_addr: *i64, n_lab: i64, nm: *u8) -> i64 { 29 var k: i64 = 0 30 while k < n_lab { if axc_tok_is(src, lab_off[k], lab_len[k], nm) == 1 { return lab_addr[k] } k = k + 1 } 31 return 0 - 1 32} 33 34func fr_assemble(src: *u8, n: i64, out: *u8, out_cap: i64, off: *i64) -> i64 { 35 let lab_off: *i64 = sys_mmap(ASM_MAX_LABELS * 8) as *i64 36 let lab_len: *i64 = sys_mmap(ASM_MAX_LABELS * 8) as *i64 37 let lab_addr: *i64 = sys_mmap(ASM_MAX_LABELS * 8) as *i64 38 let lab_sec: *i64 = sys_mmap(ASM_MAX_LABELS * 8) as *i64 39 let op0: *i64 = sys_mmap(72) as *i64 // 9 slots for SIB (matches nxasm_x86) 40 let op1: *i64 = sys_mmap(72) as *i64 41 let op2: *i64 = sys_mmap(72) as *i64 // API DRIFT FIX: axc_pass gained op2 42 let scratch: *u8 = sys_mmap(64) 43 let posbox: *i64 = sys_mmap(16) as *i64 44 let n_lab_box: *i64 = sys_mmap(16) as *i64 45 n_lab_box[0] = 0 46 let lh: *i64 = sys_mmap(ASM_LH_SIZE * 8) as *i64 47 let text_size: i64 = axc_pass(src, n, out, 0, 0, lab_off, lab_len, lab_addr, lab_sec, n_lab_box, lh, op0, op1, op2, scratch, posbox) 48 if text_size < 0 { return text_size } 49 let n_lab: i64 = n_lab_box[0] 50 var k: i64 = 0 51 while k < n_lab { if lab_sec[k] == 1 { lab_addr[k] = lab_addr[k] + text_size } k = k + 1 } 52 axc_lh_build(src, lab_off, lab_len, n_lab, lh) 53 let total: i64 = axc_pass(src, n, out, text_size, 1, lab_off, lab_len, lab_addr, lab_sec, n_lab_box, lh, op0, op1, op2, scratch, posbox) 54 if total < 0 { return total } 55 if total > out_cap { return 0 - 200 } 56 off[0] = fr_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "main") 57 off[1] = fr_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "sys_mmap") 58 off[2] = fr_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "nx_fopen") 59 off[3] = fr_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "nx_fread") 60 return total 61} 62 63func fr_redirect(buf: *u8, shim_off: i64, thunk_off: i64) -> i64 { 64 if shim_off < 0 { return 0 } 65 let shim_rva: i64 = FR_RVA_TEXT + FR_STUB_LEN + shim_off 66 let thunk_rva: i64 = FR_RVA_TEXT + thunk_off 67 let s: i64 = FR_FOFF_TEXT + FR_STUB_LEN + shim_off 68 _w8(buf, s+0, 0xE9); _w32(buf, s+1, thunk_rva - (shim_rva + 5)) 69 return 0 70} 71 72func fr_emit_pe(buf: *u8, code: *u8, code_len: i64, off: *i64) -> i64 { 73 if (buf as i64) == 0 { return 0 - NX_PE_BAD_INPUT } 74 if off[0] < 0 { return 0 - NX_PE_BAD_INPUT } 75 let thalloc: i64 = FR_STUB_LEN + code_len 76 let tfopen: i64 = thalloc + FR_L_HALLOC 77 let tfread: i64 = tfopen + FR_L_FOPEN 78 let tend: i64 = tfread + FR_L_FREAD 79 if tend > FR_TEXT_CAP { return 0 - NX_PE_BAD_INPUT } 80 81 _w16(buf, 0, 0x5A4D); _w32(buf, 0x3C, FOFF_PE_SIG); _w32(buf, FOFF_PE_SIG, 0x00004550) 82 _w16(buf, FOFF_COFF + 0, PE_MACHINE_AMD64); _w16(buf, FOFF_COFF + 2, 2) 83 _w16(buf, FOFF_COFF + 16, 0xF0); _w16(buf, FOFF_COFF + 18, PE_CHAR_EXEC | PE_CHAR_LARGE_ADDR) 84 _w16(buf, FOFF_OPT + 0, PE_OH_MAGIC_PEPLUS); _w8(buf, FOFF_OPT + 2, 1) 85 _w32(buf, FOFF_OPT + 4, 0x400); _w32(buf, FOFF_OPT + 8, 0x200) 86 _w32(buf, FOFF_OPT + 16, FR_RVA_TEXT); _w32(buf, FOFF_OPT + 20, FR_RVA_TEXT) 87 _w64(buf, FOFF_OPT + 24, IMG_BASE_LO, IMG_BASE_HI) 88 _w32(buf, FOFF_OPT + 32, 0x1000); _w32(buf, FOFF_OPT + 36, 0x200) 89 _w16(buf, FOFF_OPT + 40, 6); _w16(buf, FOFF_OPT + 48, 6) 90 _w32(buf, FOFF_OPT + 56, 0x3000); _w32(buf, FOFF_OPT + 60, 0x200) 91 _w16(buf, FOFF_OPT + 68, PE_SUBSYSTEM_CONSOLE) 92 _w64(buf, FOFF_OPT + 72, 0x100000, 0); _w64(buf, FOFF_OPT + 80, 0x1000, 0) 93 _w64(buf, FOFF_OPT + 88, 0x100000, 0); _w64(buf, FOFF_OPT + 96, 0x1000, 0) 94 _w32(buf, FOFF_OPT + 108, 16) 95 _w32(buf, FOFF_OPT + 112 + 8, FR_RVA_IDATA); _w32(buf, FOFF_OPT + 112 + 12, 0x28) 96 _emit_section_header(buf, FOFF_SECT_TBL, 46, 116, 101, 120, 116, 0, 0, 0, tend, FR_RVA_TEXT, 0x400, FR_FOFF_TEXT, PE_SECT_CODE_X_R) 97 _emit_section_header(buf, FOFF_SECT_TBL + 40, 46, 105, 100, 97, 116, 97, 0, 0, 0xDB, FR_RVA_IDATA, 0x200, FR_FOFF_IDATA, PE_SECT_DATA_R) 98 99 // entry stub 100 let t: i64 = FR_FOFF_TEXT 101 _w8(buf, t+0, 0x48); _w8(buf, t+1, 0x83); _w8(buf, t+2, 0xEC); _w8(buf, t+3, 0x28) 102 _w8(buf, t+4, 0xE8); _w32(buf, t+5, 0x9 + off[0]) 103 _w8(buf, t+9, 0x89); _w8(buf, t+10, 0xC1) 104 _w8(buf, t+11, 0xFF); _w8(buf, t+12, 0x15); _w32(buf, t+13, FR_IAT_EXIT - (FR_RVA_TEXT + 17)) 105 _w8(buf, t+17, 0xCC) 106 var i: i64 = 0 107 while i < code_len { buf[t + FR_STUB_LEN + i] = code[i]; i = i + 1 } 108 109 // HALLOC thunk (sys_mmap -> GetProcessHeap+HeapAlloc) 110 var rva: i64 = FR_RVA_TEXT + thalloc 111 var a: i64 = FR_FOFF_TEXT + thalloc 112 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x28) 113 _w8(buf,a+4,0xFF);_w8(buf,a+5,0x15);_w32(buf,a+6,FR_IAT_GPH-(rva+10)) 114 _w8(buf,a+10,0x48);_w8(buf,a+11,0x89);_w8(buf,a+12,0xC1) 115 _w8(buf,a+13,0x31);_w8(buf,a+14,0xD2) 116 _w8(buf,a+15,0x49);_w8(buf,a+16,0x89);_w8(buf,a+17,0xF8) 117 _w8(buf,a+18,0xFF);_w8(buf,a+19,0x15);_w32(buf,a+20,FR_IAT_HA-(rva+24)) 118 _w8(buf,a+24,0x48);_w8(buf,a+25,0x83);_w8(buf,a+26,0xC4);_w8(buf,a+27,0x28) 119 _w8(buf,a+28,0xC3) 120 // FOPEN thunk (nx_fopen(path) -> CreateFileA(path,GENERIC_READ,SHARE_READ,0,OPEN_EXISTING,NORMAL,0)) 121 rva = FR_RVA_TEXT + tfopen; a = FR_FOFF_TEXT + tfopen 122 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x48) // sub rsp,0x48 123 _w8(buf,a+4,0x48);_w8(buf,a+5,0x89);_w8(buf,a+6,0xF9) // mov rcx,rdi (path) 124 _w8(buf,a+7,0xBA);_w8(buf,a+8,0x00);_w8(buf,a+9,0x00);_w8(buf,a+10,0x00);_w8(buf,a+11,0x80) // mov edx,0x80000000 125 _w8(buf,a+12,0x41);_w8(buf,a+13,0xB8);_w32(buf,a+14,1) // mov r8d,1 (FILE_SHARE_READ) 126 _w8(buf,a+18,0x45);_w8(buf,a+19,0x31);_w8(buf,a+20,0xC9) // xor r9d,r9d 127 _w8(buf,a+21,0xC7);_w8(buf,a+22,0x44);_w8(buf,a+23,0x24);_w8(buf,a+24,0x20);_w32(buf,a+25,3) // mov dword[rsp+0x20],3 OPEN_EXISTING 128 _w8(buf,a+29,0xC7);_w8(buf,a+30,0x44);_w8(buf,a+31,0x24);_w8(buf,a+32,0x28);_w32(buf,a+33,0x80) // mov dword[rsp+0x28],0x80 NORMAL 129 _w8(buf,a+37,0x48);_w8(buf,a+38,0xC7);_w8(buf,a+39,0x44);_w8(buf,a+40,0x24);_w8(buf,a+41,0x30);_w32(buf,a+42,0) // mov qword[rsp+0x30],0 130 _w8(buf,a+46,0xFF);_w8(buf,a+47,0x15);_w32(buf,a+48,FR_IAT_CFA-(rva+52)) // call [CreateFileA] 131 _w8(buf,a+52,0x48);_w8(buf,a+53,0x83);_w8(buf,a+54,0xC4);_w8(buf,a+55,0x48) // add rsp,0x48 132 _w8(buf,a+56,0xC3) 133 // FREAD thunk (nx_fread(h,buf,n) -> ReadFile(h,buf,n,&got,0); returns got) 134 rva = FR_RVA_TEXT + tfread; a = FR_FOFF_TEXT + tfread 135 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x38) // sub rsp,0x38 136 _w8(buf,a+4,0x48);_w8(buf,a+5,0x89);_w8(buf,a+6,0xF9) // mov rcx,rdi (h) 137 _w8(buf,a+7,0x49);_w8(buf,a+8,0x89);_w8(buf,a+9,0xD0) // mov r8,rdx (n) 138 _w8(buf,a+10,0x48);_w8(buf,a+11,0x89);_w8(buf,a+12,0xF2) // mov rdx,rsi (buf) 139 _w8(buf,a+13,0x4C);_w8(buf,a+14,0x8D);_w8(buf,a+15,0x4C);_w8(buf,a+16,0x24);_w8(buf,a+17,0x30) // lea r9,[rsp+0x30] (&got) 140 _w8(buf,a+18,0x48);_w8(buf,a+19,0xC7);_w8(buf,a+20,0x44);_w8(buf,a+21,0x24);_w8(buf,a+22,0x20);_w32(buf,a+23,0) // mov qword[rsp+0x20],0 141 _w8(buf,a+27,0xFF);_w8(buf,a+28,0x15);_w32(buf,a+29,FR_IAT_RF-(rva+33)) // call [ReadFile] 142 _w8(buf,a+33,0x8B);_w8(buf,a+34,0x44);_w8(buf,a+35,0x24);_w8(buf,a+36,0x30) // mov eax,[rsp+0x30] (got) 143 _w8(buf,a+37,0x48);_w8(buf,a+38,0x83);_w8(buf,a+39,0xC4);_w8(buf,a+40,0x38) // add rsp,0x38 144 _w8(buf,a+41,0xC3) 145 146 fr_redirect(buf, off[1], thalloc) 147 fr_redirect(buf, off[2], tfopen) 148 fr_redirect(buf, off[3], tfread) 149 150 // ===== .idata: kernel32 { ExitProcess, GetProcessHeap, HeapAlloc, CreateFileA, ReadFile } ===== 151 let d: i64 = FR_FOFF_IDATA 152 _w32(buf,d+0x00,0x2028); _w32(buf,d+0x0C,0x20CE); _w32(buf,d+0x10,0x2058) 153 // INT @0x28 154 _w64(buf,d+0x28,0x2088,0); _w64(buf,d+0x30,0x2096,0); _w64(buf,d+0x38,0x20A8,0); _w64(buf,d+0x40,0x20B4,0); _w64(buf,d+0x48,0x20C2,0); _w64(buf,d+0x50,0,0) 155 // IAT @0x58 156 _w64(buf,d+0x58,0x2088,0); _w64(buf,d+0x60,0x2096,0); _w64(buf,d+0x68,0x20A8,0); _w64(buf,d+0x70,0x20B4,0); _w64(buf,d+0x78,0x20C2,0); _w64(buf,d+0x80,0,0) 157 // ExitProcess @0x88 158 _w16(buf,d+0x88,0);_w8(buf,d+0x8A,69);_w8(buf,d+0x8B,120);_w8(buf,d+0x8C,105);_w8(buf,d+0x8D,116);_w8(buf,d+0x8E,80);_w8(buf,d+0x8F,114);_w8(buf,d+0x90,111);_w8(buf,d+0x91,99);_w8(buf,d+0x92,101);_w8(buf,d+0x93,115);_w8(buf,d+0x94,115);_w8(buf,d+0x95,0) 159 // GetProcessHeap @0x96 160 _w16(buf,d+0x96,0);_w8(buf,d+0x98,71);_w8(buf,d+0x99,101);_w8(buf,d+0x9A,116);_w8(buf,d+0x9B,80);_w8(buf,d+0x9C,114);_w8(buf,d+0x9D,111);_w8(buf,d+0x9E,99);_w8(buf,d+0x9F,101);_w8(buf,d+0xA0,115);_w8(buf,d+0xA1,115);_w8(buf,d+0xA2,72);_w8(buf,d+0xA3,101);_w8(buf,d+0xA4,97);_w8(buf,d+0xA5,112);_w8(buf,d+0xA6,0);_w8(buf,d+0xA7,0) 161 // HeapAlloc @0xA8 162 _w16(buf,d+0xA8,0);_w8(buf,d+0xAA,72);_w8(buf,d+0xAB,101);_w8(buf,d+0xAC,97);_w8(buf,d+0xAD,112);_w8(buf,d+0xAE,65);_w8(buf,d+0xAF,108);_w8(buf,d+0xB0,108);_w8(buf,d+0xB1,111);_w8(buf,d+0xB2,99);_w8(buf,d+0xB3,0) 163 // CreateFileA @0xB4 164 _w16(buf,d+0xB4,0);_w8(buf,d+0xB6,67);_w8(buf,d+0xB7,114);_w8(buf,d+0xB8,101);_w8(buf,d+0xB9,97);_w8(buf,d+0xBA,116);_w8(buf,d+0xBB,101);_w8(buf,d+0xBC,70);_w8(buf,d+0xBD,105);_w8(buf,d+0xBE,108);_w8(buf,d+0xBF,101);_w8(buf,d+0xC0,65);_w8(buf,d+0xC1,0) 165 // ReadFile @0xC2 166 _w16(buf,d+0xC2,0);_w8(buf,d+0xC4,82);_w8(buf,d+0xC5,101);_w8(buf,d+0xC6,97);_w8(buf,d+0xC7,100);_w8(buf,d+0xC8,70);_w8(buf,d+0xC9,105);_w8(buf,d+0xCA,108);_w8(buf,d+0xCB,101);_w8(buf,d+0xCC,0);_w8(buf,d+0xCD,0) 167 // "kernel32.dll" @0xCE 168 _w8(buf,d+0xCE,107);_w8(buf,d+0xCF,101);_w8(buf,d+0xD0,114);_w8(buf,d+0xD1,110);_w8(buf,d+0xD2,101);_w8(buf,d+0xD3,108);_w8(buf,d+0xD4,51);_w8(buf,d+0xD5,50);_w8(buf,d+0xD6,46);_w8(buf,d+0xD7,100);_w8(buf,d+0xD8,108);_w8(buf,d+0xD9,108);_w8(buf,d+0xDA,0) 169 170 return NX_PE_OK 171} 172 173func main() -> i64 { 174 let lenbox: *i64 = sys_mmap(16) as *i64 175 let src: *u8 = sys_read_file("/tmp/nxwin.s" as *u8, lenbox) 176 if (src as i64) == 0 { return 1 } 177 let n: i64 = lenbox[0] 178 if n <= 0 { return 2 } 179 let code: *u8 = sys_mmap(FR_CODE_CAP) 180 let off: *i64 = sys_mmap(16 * 8) as *i64 181 var z: i64 = 0 182 while z < 4 { off[z] = 0 - 1; z = z + 1 } 183 let code_len: i64 = fr_assemble(src, n, code, FR_CODE_CAP, off) 184 if code_len < 0 { return 3 } 185 if off[0] < 0 { return 4 } 186 let buf: *u8 = sys_mmap(FR_FILE_SIZE) 187 let rc: i64 = fr_emit_pe(buf, code, code_len, off) 188 if rc != NX_PE_OK { return 5 } 189 let outp: *u8 = "/mnt/c/Users/elder/nishi-core/nxc2/_offc/nx_win_fread.exe" as *u8 190 if nx_pe_write_to_file(outp, buf, FR_FILE_SIZE) != NX_PE_OK { return 70 } 191 let msg: *u8 = "[substrate] nxc2-compiled native file-read PE written: nx_win_fread.exe\n" as *u8 192 sys_write(1, msg, 71) 193 return 0 194}