code wiki / (root) / nx_pe_compile_win_uiserve.nx

nx_pe_compile_win_uiserve.nx source

↩ module page · 361 lines · 20813 B

1// nx_pe_compile_win_uiserve.nx -- W-NET-5b: native static-file HTTP server (sockets + file I/O in ONE 2// PE) to serve the REAL Elder ui/dist on :5173. 13 imports across 2 DLLs: 3// kernel32 { ExitProcess, GetProcessHeap, HeapAlloc, CreateFileA, ReadFile } 4// ws2_32 { WSAStartup, socket, bind, listen, accept, recv, send, closesocket } 5// Keystone-linker redirects shims to thunks (tolerant: only those the source defines, so a combined 6// probe and the full server build from the same organ). lineage_id: substrate_pe_compile_win_uiserve_v1 7import "nx_syscalls.nx" 8import "nxasm_x86.nx" 9import "nx_pe_writer.nx" 10 11const US_CODE_CAP: i64 = 1048576 12const US_FILE_SIZE: i64 = 0x2400 // headers(0x200)+.text(0x2000)+.idata(0x200) 13const US_STUB_LEN: i64 = 18 14const US_TEXT_CAP: i64 = 0x2000 15const US_RVA_TEXT: i64 = 0x1000 16const US_RVA_IDATA: i64 = 0x3000 // .text raw 0x2000 -> virtual 0x1000..0x3000 -> idata at 0x3000 17const US_FOFF_TEXT: i64 = 0x200 18const US_FOFF_IDATA:i64 = 0x2200 19// IAT RVAs (combined 13-func layout below) 20const US_IAT_EXIT: i64 = 0x30BC 21const US_IAT_GPH: i64 = 0x30C4 22const US_IAT_HA: i64 = 0x30CC 23const US_IAT_CFA: i64 = 0x30D4 24const US_IAT_RF: i64 = 0x30DC 25const US_IAT_WSA: i64 = 0x30EC 26const US_IAT_SOCK: i64 = 0x30F4 27const US_IAT_BIND: i64 = 0x30FC 28const US_IAT_LISTEN:i64 = 0x3104 29const US_IAT_ACCEPT:i64 = 0x310C 30const US_IAT_RECV: i64 = 0x3114 31const US_IAT_SEND: i64 = 0x311C 32const US_IAT_CLOSE: i64 = 0x3124 33const US_IAT_CONNECT:i64 = 0x312C 34// thunk lengths 35const US_L_HALLOC: i64 = 29 36const US_L_FOPEN: i64 = 57 37const US_L_FREAD: i64 = 42 38const US_L_WSA: i64 = 31 39const US_L_SOCK: i64 = 28 40const US_L_BIND: i64 = 65 41const US_L_LISTEN: i64 = 23 42const US_L_ACCEPT: i64 = 23 43const US_L_RECV: i64 = 27 44const US_L_SEND: i64 = 27 45const US_L_CLOSE: i64 = 18 46const US_L_CONNECT: i64 = 65 47 48func us_lbloff(src: *u8, lab_off: *i64, lab_len: *i64, lab_addr: *i64, n_lab: i64, nm: *u8) -> i64 { 49 var k: i64 = 0 50 while k < n_lab { if axc_tok_is(src, lab_off[k], lab_len[k], nm) == 1 { return lab_addr[k] } k = k + 1 } 51 return 0 - 1 52} 53 54func us_assemble(src: *u8, n: i64, out: *u8, out_cap: i64, off: *i64) -> i64 { 55 let lab_off: *i64 = sys_mmap(ASM_MAX_LABELS * 8) as *i64 56 let lab_len: *i64 = sys_mmap(ASM_MAX_LABELS * 8) as *i64 57 let lab_addr: *i64 = sys_mmap(ASM_MAX_LABELS * 8) as *i64 58 let lab_sec: *i64 = sys_mmap(ASM_MAX_LABELS * 8) as *i64 59 let op0: *i64 = sys_mmap(72) as *i64 // 9 slots for SIB (matches nxasm_x86) 60 let op1: *i64 = sys_mmap(72) as *i64 61 let op2: *i64 = sys_mmap(72) as *i64 // API DRIFT FIX: axc_pass gained op2 62 let scratch: *u8 = sys_mmap(64) 63 let posbox: *i64 = sys_mmap(16) as *i64 64 let n_lab_box: *i64 = sys_mmap(16) as *i64 65 n_lab_box[0] = 0 66 let lh: *i64 = sys_mmap(ASM_LH_SIZE * 8) as *i64 67 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) 68 if text_size < 0 { return text_size } 69 let n_lab: i64 = n_lab_box[0] 70 var k: i64 = 0 71 while k < n_lab { if lab_sec[k] == 1 { lab_addr[k] = lab_addr[k] + text_size } k = k + 1 } 72 axc_lh_build(src, lab_off, lab_len, n_lab, lh) 73 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) 74 if total < 0 { return total } 75 if total > out_cap { return 0 - 200 } 76 off[0] = us_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "main") 77 off[1] = us_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "sys_mmap") 78 off[2] = us_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "nx_fopen") 79 off[3] = us_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "nx_fread") 80 off[4] = us_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "nx_wsa") 81 off[5] = us_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "nx_sock") 82 off[6] = us_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "nx_bind") 83 off[7] = us_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "nx_listen") 84 off[8] = us_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "nx_accept") 85 off[9] = us_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "nx_recv") 86 off[10] = us_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "nx_send") 87 off[11] = us_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "nx_close") 88 off[12] = us_lbloff(src, lab_off, lab_len, lab_addr, n_lab, "nx_connect") 89 return total 90} 91 92func us_redirect(buf: *u8, shim_off: i64, thunk_off: i64) -> i64 { 93 if shim_off < 0 { return 0 } 94 let shim_rva: i64 = US_RVA_TEXT + US_STUB_LEN + shim_off 95 let thunk_rva: i64 = US_RVA_TEXT + thunk_off 96 let s: i64 = US_FOFF_TEXT + US_STUB_LEN + shim_off 97 _w8(buf, s+0, 0xE9); _w32(buf, s+1, thunk_rva - (shim_rva + 5)) 98 return 0 99} 100 101func us_putname(buf: *u8, base: i64, off: i64, s: *u8) -> i64 { 102 _w16(buf, base + off, 0) 103 var i: i64 = 0 104 while s[i] != (0 as u8) { _w8(buf, base + off + 2 + i, s[i] as i64); i = i + 1 } 105 _w8(buf, base + off + 2 + i, 0) 106 return off + 2 + i + 1 107} 108func us_putdll(buf: *u8, base: i64, off: i64, s: *u8) -> i64 { 109 var i: i64 = 0 110 while s[i] != (0 as u8) { _w8(buf, base + off + i, s[i] as i64); i = i + 1 } 111 _w8(buf, base + off + i, 0) 112 return off + i + 1 113} 114 115func us_emit_pe(buf: *u8, code: *u8, code_len: i64, off: *i64) -> i64 { 116 if (buf as i64) == 0 { return 0 - NX_PE_BAD_INPUT } 117 if off[0] < 0 { return 0 - NX_PE_BAD_INPUT } 118 let thalloc: i64 = US_STUB_LEN + code_len 119 let tfopen: i64 = thalloc + US_L_HALLOC 120 let tfread: i64 = tfopen + US_L_FOPEN 121 let twsa: i64 = tfread + US_L_FREAD 122 let tsock: i64 = twsa + US_L_WSA 123 let tbind: i64 = tsock + US_L_SOCK 124 let tlisten: i64 = tbind + US_L_BIND 125 let taccept: i64 = tlisten + US_L_LISTEN 126 let trecv: i64 = taccept + US_L_ACCEPT 127 let tsend: i64 = trecv + US_L_RECV 128 let tclose: i64 = tsend + US_L_SEND 129 let tconnect: i64 = tclose + US_L_CLOSE 130 let tend: i64 = tconnect + US_L_CONNECT 131 if tend > US_TEXT_CAP { return 0 - NX_PE_BAD_INPUT } 132 133 _w16(buf, 0, 0x5A4D); _w32(buf, 0x3C, FOFF_PE_SIG); _w32(buf, FOFF_PE_SIG, 0x00004550) 134 _w16(buf, FOFF_COFF + 0, PE_MACHINE_AMD64); _w16(buf, FOFF_COFF + 2, 2) 135 _w16(buf, FOFF_COFF + 16, 0xF0); _w16(buf, FOFF_COFF + 18, PE_CHAR_EXEC | PE_CHAR_LARGE_ADDR) 136 _w16(buf, FOFF_OPT + 0, PE_OH_MAGIC_PEPLUS); _w8(buf, FOFF_OPT + 2, 1) 137 _w32(buf, FOFF_OPT + 4, 0x2000); _w32(buf, FOFF_OPT + 8, 0x200) 138 _w32(buf, FOFF_OPT + 16, US_RVA_TEXT); _w32(buf, FOFF_OPT + 20, US_RVA_TEXT) 139 _w64(buf, FOFF_OPT + 24, IMG_BASE_LO, IMG_BASE_HI) 140 _w32(buf, FOFF_OPT + 32, 0x1000); _w32(buf, FOFF_OPT + 36, 0x200) 141 _w16(buf, FOFF_OPT + 40, 6); _w16(buf, FOFF_OPT + 48, 6) 142 _w32(buf, FOFF_OPT + 56, 0x4000); _w32(buf, FOFF_OPT + 60, 0x200) 143 _w16(buf, FOFF_OPT + 68, PE_SUBSYSTEM_CONSOLE) 144 _w64(buf, FOFF_OPT + 72, 0x100000, 0); _w64(buf, FOFF_OPT + 80, 0x1000, 0) 145 _w64(buf, FOFF_OPT + 88, 0x100000, 0); _w64(buf, FOFF_OPT + 96, 0x1000, 0) 146 _w32(buf, FOFF_OPT + 108, 16) 147 _w32(buf, FOFF_OPT + 112 + 8, US_RVA_IDATA); _w32(buf, FOFF_OPT + 112 + 12, 0x3C) 148 // FIX (2026-06-18): VirtualSize must match the section's mapped extent vs RawSize(0x2000). Using `tend` 149 // (actual code size) made VirtualSize round to 1 page (0x1000) < RawSize(0x2000) for SMALL servers -> 150 // Windows ERROR_BAD_EXE_FORMAT(193). Set VirtualSize=US_TEXT_CAP(=RawSize) -> valid for ANY code size. 151 _emit_section_header(buf, FOFF_SECT_TBL, 46, 116, 101, 120, 116, 0, 0, 0, US_TEXT_CAP, US_RVA_TEXT, 0x2000, US_FOFF_TEXT, PE_SECT_CODE_X_R) 152 _emit_section_header(buf, FOFF_SECT_TBL + 40, 46, 105, 100, 97, 116, 97, 0, 0, 0x1DC, US_RVA_IDATA, 0x200, US_FOFF_IDATA, PE_SECT_DATA_R) 153 154 // entry stub 155 let t: i64 = US_FOFF_TEXT 156 _w8(buf, t+0, 0x48); _w8(buf, t+1, 0x83); _w8(buf, t+2, 0xEC); _w8(buf, t+3, 0x28) 157 _w8(buf, t+4, 0xE8); _w32(buf, t+5, 0x9 + off[0]) 158 _w8(buf, t+9, 0x89); _w8(buf, t+10, 0xC1) 159 _w8(buf, t+11, 0xFF); _w8(buf, t+12, 0x15); _w32(buf, t+13, US_IAT_EXIT - (US_RVA_TEXT + 17)) 160 _w8(buf, t+17, 0xCC) 161 var i: i64 = 0 162 while i < code_len { buf[t + US_STUB_LEN + i] = code[i]; i = i + 1 } 163 164 var rva: i64 = 0 165 var a: i64 = 0 166 // HALLOC (sys_mmap -> GetProcessHeap+HeapAlloc) 167 rva = US_RVA_TEXT + thalloc; a = US_FOFF_TEXT + thalloc 168 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x28) 169 _w8(buf,a+4,0xFF);_w8(buf,a+5,0x15);_w32(buf,a+6,US_IAT_GPH-(rva+10)) 170 _w8(buf,a+10,0x48);_w8(buf,a+11,0x89);_w8(buf,a+12,0xC1) 171 _w8(buf,a+13,0x31);_w8(buf,a+14,0xD2) 172 _w8(buf,a+15,0x49);_w8(buf,a+16,0x89);_w8(buf,a+17,0xF8) 173 _w8(buf,a+18,0xFF);_w8(buf,a+19,0x15);_w32(buf,a+20,US_IAT_HA-(rva+24)) 174 _w8(buf,a+24,0x48);_w8(buf,a+25,0x83);_w8(buf,a+26,0xC4);_w8(buf,a+27,0x28) 175 _w8(buf,a+28,0xC3) 176 // FOPEN (nx_fopen(path) -> CreateFileA) 177 rva = US_RVA_TEXT + tfopen; a = US_FOFF_TEXT + tfopen 178 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x48) 179 _w8(buf,a+4,0x48);_w8(buf,a+5,0x89);_w8(buf,a+6,0xF9) 180 _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) 181 _w8(buf,a+12,0x41);_w8(buf,a+13,0xB8);_w32(buf,a+14,1) 182 _w8(buf,a+18,0x45);_w8(buf,a+19,0x31);_w8(buf,a+20,0xC9) 183 _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) 184 _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) 185 _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) 186 _w8(buf,a+46,0xFF);_w8(buf,a+47,0x15);_w32(buf,a+48,US_IAT_CFA-(rva+52)) 187 _w8(buf,a+52,0x48);_w8(buf,a+53,0x83);_w8(buf,a+54,0xC4);_w8(buf,a+55,0x48) 188 _w8(buf,a+56,0xC3) 189 // FREAD (nx_fread(h,buf,n) -> ReadFile; returns got) 190 rva = US_RVA_TEXT + tfread; a = US_FOFF_TEXT + tfread 191 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x38) 192 _w8(buf,a+4,0x48);_w8(buf,a+5,0x89);_w8(buf,a+6,0xF9) 193 _w8(buf,a+7,0x49);_w8(buf,a+8,0x89);_w8(buf,a+9,0xD0) 194 _w8(buf,a+10,0x48);_w8(buf,a+11,0x89);_w8(buf,a+12,0xF2) 195 _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) 196 _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) 197 _w8(buf,a+27,0xFF);_w8(buf,a+28,0x15);_w32(buf,a+29,US_IAT_RF-(rva+33)) 198 _w8(buf,a+33,0x8B);_w8(buf,a+34,0x44);_w8(buf,a+35,0x24);_w8(buf,a+36,0x30) 199 _w8(buf,a+37,0x48);_w8(buf,a+38,0x83);_w8(buf,a+39,0xC4);_w8(buf,a+40,0x38) 200 _w8(buf,a+41,0xC3) 201 // WSA 202 rva = US_RVA_TEXT + twsa; a = US_FOFF_TEXT + twsa 203 _w8(buf,a+0,0x48);_w8(buf,a+1,0x81);_w8(buf,a+2,0xEC);_w32(buf,a+3,0x228) 204 _w8(buf,a+7,0xB9);_w32(buf,a+8,0x0202) 205 _w8(buf,a+12,0x48);_w8(buf,a+13,0x8D);_w8(buf,a+14,0x54);_w8(buf,a+15,0x24);_w8(buf,a+16,0x28) 206 _w8(buf,a+17,0xFF);_w8(buf,a+18,0x15);_w32(buf,a+19,US_IAT_WSA-(rva+23)) 207 _w8(buf,a+23,0x48);_w8(buf,a+24,0x81);_w8(buf,a+25,0xC4);_w32(buf,a+26,0x228) 208 _w8(buf,a+30,0xC3) 209 // SOCK 210 rva = US_RVA_TEXT + tsock; a = US_FOFF_TEXT + tsock 211 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x28) 212 _w8(buf,a+4,0xB9);_w32(buf,a+5,2) 213 _w8(buf,a+9,0xBA);_w32(buf,a+10,1) 214 _w8(buf,a+14,0x45);_w8(buf,a+15,0x31);_w8(buf,a+16,0xC0) 215 _w8(buf,a+17,0xFF);_w8(buf,a+18,0x15);_w32(buf,a+19,US_IAT_SOCK-(rva+23)) 216 _w8(buf,a+23,0x48);_w8(buf,a+24,0x83);_w8(buf,a+25,0xC4);_w8(buf,a+26,0x28) 217 _w8(buf,a+27,0xC3) 218 // BIND 219 rva = US_RVA_TEXT + tbind; a = US_FOFF_TEXT + tbind 220 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x38) 221 _w8(buf,a+4,0x66);_w8(buf,a+5,0xC7);_w8(buf,a+6,0x44);_w8(buf,a+7,0x24);_w8(buf,a+8,0x20);_w16(buf,a+9,2) 222 _w8(buf,a+11,0x66);_w8(buf,a+12,0x89);_w8(buf,a+13,0xF0) 223 _w8(buf,a+14,0x66);_w8(buf,a+15,0xC1);_w8(buf,a+16,0xC0);_w8(buf,a+17,0x08) 224 _w8(buf,a+18,0x66);_w8(buf,a+19,0x89);_w8(buf,a+20,0x44);_w8(buf,a+21,0x24);_w8(buf,a+22,0x22) 225 _w8(buf,a+23,0xC7);_w8(buf,a+24,0x44);_w8(buf,a+25,0x24);_w8(buf,a+26,0x24);_w32(buf,a+27,0) 226 _w8(buf,a+31,0x48);_w8(buf,a+32,0xC7);_w8(buf,a+33,0x44);_w8(buf,a+34,0x24);_w8(buf,a+35,0x28);_w32(buf,a+36,0) 227 _w8(buf,a+40,0x48);_w8(buf,a+41,0x89);_w8(buf,a+42,0xF9) 228 _w8(buf,a+43,0x48);_w8(buf,a+44,0x8D);_w8(buf,a+45,0x54);_w8(buf,a+46,0x24);_w8(buf,a+47,0x20) 229 _w8(buf,a+48,0x41);_w8(buf,a+49,0xB8);_w32(buf,a+50,16) 230 _w8(buf,a+54,0xFF);_w8(buf,a+55,0x15);_w32(buf,a+56,US_IAT_BIND-(rva+60)) 231 _w8(buf,a+60,0x48);_w8(buf,a+61,0x83);_w8(buf,a+62,0xC4);_w8(buf,a+63,0x38) 232 _w8(buf,a+64,0xC3) 233 // LISTEN 234 rva = US_RVA_TEXT + tlisten; a = US_FOFF_TEXT + tlisten 235 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x28) 236 _w8(buf,a+4,0x48);_w8(buf,a+5,0x89);_w8(buf,a+6,0xF9) 237 _w8(buf,a+7,0xBA);_w32(buf,a+8,16) 238 _w8(buf,a+12,0xFF);_w8(buf,a+13,0x15);_w32(buf,a+14,US_IAT_LISTEN-(rva+18)) 239 _w8(buf,a+18,0x48);_w8(buf,a+19,0x83);_w8(buf,a+20,0xC4);_w8(buf,a+21,0x28) 240 _w8(buf,a+22,0xC3) 241 // ACCEPT 242 rva = US_RVA_TEXT + taccept; a = US_FOFF_TEXT + taccept 243 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x28) 244 _w8(buf,a+4,0x48);_w8(buf,a+5,0x89);_w8(buf,a+6,0xF9) 245 _w8(buf,a+7,0x31);_w8(buf,a+8,0xD2) 246 _w8(buf,a+9,0x45);_w8(buf,a+10,0x31);_w8(buf,a+11,0xC0) 247 _w8(buf,a+12,0xFF);_w8(buf,a+13,0x15);_w32(buf,a+14,US_IAT_ACCEPT-(rva+18)) 248 _w8(buf,a+18,0x48);_w8(buf,a+19,0x83);_w8(buf,a+20,0xC4);_w8(buf,a+21,0x28) 249 _w8(buf,a+22,0xC3) 250 // RECV (nx_recv(c,buf,n) -> recv(c,buf,n,0); returns bytes received into the CALLER buffer) 251 rva = US_RVA_TEXT + trecv; a = US_FOFF_TEXT + trecv 252 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x28) // sub rsp,0x28 253 _w8(buf,a+4,0x48);_w8(buf,a+5,0x89);_w8(buf,a+6,0xF9) // mov rcx,rdi (c) 254 _w8(buf,a+7,0x49);_w8(buf,a+8,0x89);_w8(buf,a+9,0xD0) // mov r8,rdx (n) 255 _w8(buf,a+10,0x48);_w8(buf,a+11,0x89);_w8(buf,a+12,0xF2) // mov rdx,rsi (buf) 256 _w8(buf,a+13,0x45);_w8(buf,a+14,0x31);_w8(buf,a+15,0xC9) // xor r9d,r9d 257 _w8(buf,a+16,0xFF);_w8(buf,a+17,0x15);_w32(buf,a+18,US_IAT_RECV-(rva+22)) // call [recv] 258 _w8(buf,a+22,0x48);_w8(buf,a+23,0x83);_w8(buf,a+24,0xC4);_w8(buf,a+25,0x28) // add rsp,0x28 259 _w8(buf,a+26,0xC3) // ret 260 // SEND 261 rva = US_RVA_TEXT + tsend; a = US_FOFF_TEXT + tsend 262 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x28) 263 _w8(buf,a+4,0x48);_w8(buf,a+5,0x89);_w8(buf,a+6,0xF9) 264 _w8(buf,a+7,0x49);_w8(buf,a+8,0x89);_w8(buf,a+9,0xD0) 265 _w8(buf,a+10,0x48);_w8(buf,a+11,0x89);_w8(buf,a+12,0xF2) 266 _w8(buf,a+13,0x45);_w8(buf,a+14,0x31);_w8(buf,a+15,0xC9) 267 _w8(buf,a+16,0xFF);_w8(buf,a+17,0x15);_w32(buf,a+18,US_IAT_SEND-(rva+22)) 268 _w8(buf,a+22,0x48);_w8(buf,a+23,0x83);_w8(buf,a+24,0xC4);_w8(buf,a+25,0x28) 269 _w8(buf,a+26,0xC3) 270 // CLOSE 271 rva = US_RVA_TEXT + tclose; a = US_FOFF_TEXT + tclose 272 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x28) 273 _w8(buf,a+4,0x48);_w8(buf,a+5,0x89);_w8(buf,a+6,0xF9) 274 _w8(buf,a+7,0xFF);_w8(buf,a+8,0x15);_w32(buf,a+9,US_IAT_CLOSE-(rva+13)) 275 _w8(buf,a+13,0x48);_w8(buf,a+14,0x83);_w8(buf,a+15,0xC4);_w8(buf,a+16,0x28) 276 _w8(buf,a+17,0xC3) 277 // CONNECT (nx_connect(s,port) -> connect(s,127.0.0.1:port)); mirrors BIND but addr=0x0100007F, call [connect] 278 rva = US_RVA_TEXT + tconnect; a = US_FOFF_TEXT + tconnect 279 _w8(buf,a+0,0x48);_w8(buf,a+1,0x83);_w8(buf,a+2,0xEC);_w8(buf,a+3,0x38) 280 _w8(buf,a+4,0x66);_w8(buf,a+5,0xC7);_w8(buf,a+6,0x44);_w8(buf,a+7,0x24);_w8(buf,a+8,0x20);_w16(buf,a+9,2) 281 _w8(buf,a+11,0x66);_w8(buf,a+12,0x89);_w8(buf,a+13,0xF0) 282 _w8(buf,a+14,0x66);_w8(buf,a+15,0xC1);_w8(buf,a+16,0xC0);_w8(buf,a+17,0x08) 283 _w8(buf,a+18,0x66);_w8(buf,a+19,0x89);_w8(buf,a+20,0x44);_w8(buf,a+21,0x24);_w8(buf,a+22,0x22) 284 _w8(buf,a+23,0xC7);_w8(buf,a+24,0x44);_w8(buf,a+25,0x24);_w8(buf,a+26,0x24);_w32(buf,a+27,0x0100007F) 285 _w8(buf,a+31,0x48);_w8(buf,a+32,0xC7);_w8(buf,a+33,0x44);_w8(buf,a+34,0x24);_w8(buf,a+35,0x28);_w32(buf,a+36,0) 286 _w8(buf,a+40,0x48);_w8(buf,a+41,0x89);_w8(buf,a+42,0xF9) 287 _w8(buf,a+43,0x48);_w8(buf,a+44,0x8D);_w8(buf,a+45,0x54);_w8(buf,a+46,0x24);_w8(buf,a+47,0x20) 288 _w8(buf,a+48,0x41);_w8(buf,a+49,0xB8);_w32(buf,a+50,16) 289 _w8(buf,a+54,0xFF);_w8(buf,a+55,0x15);_w32(buf,a+56,US_IAT_CONNECT-(rva+60)) 290 _w8(buf,a+60,0x48);_w8(buf,a+61,0x83);_w8(buf,a+62,0xC4);_w8(buf,a+63,0x38) 291 _w8(buf,a+64,0xC3) 292 293 us_redirect(buf, off[1], thalloc) 294 us_redirect(buf, off[2], tfopen) 295 us_redirect(buf, off[3], tfread) 296 us_redirect(buf, off[4], twsa) 297 us_redirect(buf, off[5], tsock) 298 us_redirect(buf, off[6], tbind) 299 us_redirect(buf, off[7], tlisten) 300 us_redirect(buf, off[8], taccept) 301 us_redirect(buf, off[9], trecv) 302 us_redirect(buf, off[10], tsend) 303 us_redirect(buf, off[11], tclose) 304 us_redirect(buf, off[12], tconnect) 305 306 // ===== .idata: kernel32{5} + ws2_32{9} (connect added). Names via helpers -> self-consistent RVAs. ===== 307 let d: i64 = US_FOFF_IDATA 308 var no: i64 = 0x13C 309 let r_exit: i64 = 0x3000 + no; no = us_putname(buf, d, no, "ExitProcess" as *u8) 310 let r_gph: i64 = 0x3000 + no; no = us_putname(buf, d, no, "GetProcessHeap" as *u8) 311 let r_ha: i64 = 0x3000 + no; no = us_putname(buf, d, no, "HeapAlloc" as *u8) 312 let r_cfa: i64 = 0x3000 + no; no = us_putname(buf, d, no, "CreateFileA" as *u8) 313 let r_rf: i64 = 0x3000 + no; no = us_putname(buf, d, no, "ReadFile" as *u8) 314 let r_wsa: i64 = 0x3000 + no; no = us_putname(buf, d, no, "WSAStartup" as *u8) 315 let r_sock: i64 = 0x3000 + no; no = us_putname(buf, d, no, "socket" as *u8) 316 let r_bind: i64 = 0x3000 + no; no = us_putname(buf, d, no, "bind" as *u8) 317 let r_listen: i64 = 0x3000 + no; no = us_putname(buf, d, no, "listen" as *u8) 318 let r_accept: i64 = 0x3000 + no; no = us_putname(buf, d, no, "accept" as *u8) 319 let r_recv: i64 = 0x3000 + no; no = us_putname(buf, d, no, "recv" as *u8) 320 let r_send: i64 = 0x3000 + no; no = us_putname(buf, d, no, "send" as *u8) 321 let r_close: i64 = 0x3000 + no; no = us_putname(buf, d, no, "closesocket" as *u8) 322 let r_connect: i64 = 0x3000 + no; no = us_putname(buf, d, no, "connect" as *u8) 323 let r_k32: i64 = 0x3000 + no; no = us_putdll(buf, d, no, "kernel32.dll" as *u8) 324 let r_ws2: i64 = 0x3000 + no; no = us_putdll(buf, d, no, "ws2_32.dll" as *u8) 325 // descriptors: kernel32 (OFT=INT_k 0x303C, FT=IAT_k 0x30BC) ; ws2_32 (OFT=INT_w 0x306C, FT=IAT_w 0x30EC) 326 _w32(buf,d+0x00,0x303C); _w32(buf,d+0x0C,r_k32); _w32(buf,d+0x10,0x30BC) 327 _w32(buf,d+0x14,0x306C); _w32(buf,d+0x20,r_ws2); _w32(buf,d+0x24,0x30EC) 328 // INT_k @0x3C (5+null) 329 _w64(buf,d+0x3C,r_exit,0); _w64(buf,d+0x44,r_gph,0); _w64(buf,d+0x4C,r_ha,0); _w64(buf,d+0x54,r_cfa,0); _w64(buf,d+0x5C,r_rf,0); _w64(buf,d+0x64,0,0) 330 // INT_w @0x6C (9+null) 331 _w64(buf,d+0x6C,r_wsa,0); _w64(buf,d+0x74,r_sock,0); _w64(buf,d+0x7C,r_bind,0); _w64(buf,d+0x84,r_listen,0); _w64(buf,d+0x8C,r_accept,0); _w64(buf,d+0x94,r_recv,0); _w64(buf,d+0x9C,r_send,0); _w64(buf,d+0xA4,r_close,0); _w64(buf,d+0xAC,r_connect,0); _w64(buf,d+0xB4,0,0) 332 // IAT_k @0xBC (5+null) 333 _w64(buf,d+0xBC,r_exit,0); _w64(buf,d+0xC4,r_gph,0); _w64(buf,d+0xCC,r_ha,0); _w64(buf,d+0xD4,r_cfa,0); _w64(buf,d+0xDC,r_rf,0); _w64(buf,d+0xE4,0,0) 334 // IAT_w @0xEC (9+null) 335 _w64(buf,d+0xEC,r_wsa,0); _w64(buf,d+0xF4,r_sock,0); _w64(buf,d+0xFC,r_bind,0); _w64(buf,d+0x104,r_listen,0); _w64(buf,d+0x10C,r_accept,0); _w64(buf,d+0x114,r_recv,0); _w64(buf,d+0x11C,r_send,0); _w64(buf,d+0x124,r_close,0); _w64(buf,d+0x12C,r_connect,0); _w64(buf,d+0x134,0,0) 336 337 return NX_PE_OK 338} 339 340func main() -> i64 { 341 let lenbox: *i64 = sys_mmap(16) as *i64 342 let src: *u8 = sys_read_file("/tmp/nxwin.s" as *u8, lenbox) 343 if (src as i64) == 0 { return 1 } 344 let n: i64 = lenbox[0] 345 if n <= 0 { return 2 } 346 let code: *u8 = sys_mmap(US_CODE_CAP) 347 let off: *i64 = sys_mmap(16 * 8) as *i64 348 var z: i64 = 0 349 while z < 13 { off[z] = 0 - 1; z = z + 1 } 350 let code_len: i64 = us_assemble(src, n, code, US_CODE_CAP, off) 351 if code_len < 0 { return 3 } 352 if off[0] < 0 { return 4 } 353 let buf: *u8 = sys_mmap(US_FILE_SIZE) 354 let rc: i64 = us_emit_pe(buf, code, code_len, off) 355 if rc != NX_PE_OK { return 5 } 356 let outp: *u8 = "/mnt/c/Users/elder/nishi-core/nxc2/_offc/nx_win_uiserve.exe" as *u8 357 if nx_pe_write_to_file(outp, buf, US_FILE_SIZE) != NX_PE_OK { return 70 } 358 let msg: *u8 = "[substrate] nxc2-compiled native UI-server PE written: nx_win_uiserve.exe\n" as *u8 359 sys_write(1, msg, 73) 360 return 0 361}