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}