nx_pe_container_gen.nx source
↩ module page · 242 lines · 14927 B
1// nx_pe_container_datachar.nx -- generalized Job-Object container (OCI process.args/cwd via cmdline):
2// runs Elder data-character (python uvicorn :8100) as a governed child, no bash, no Docker.
3// Derived from nx_pe_container_sdserver; only the .data cmdline + output path differ. Original header:
4// nx_pe_container_win_io.nx -- W4-b-1: a governed Nishi container with WIRED stdout.
5//
6// W4-a (nx_pe_container_win) ran a Nishi organ as a Job-governed child and reaped exit 88, but the
7// organ's "NX" stdout was lost (CreateProcessW used bInheritHandles=FALSE + CREATE_NO_WINDOW). This
8// rung wires container output: the child inherits the supervisor's stdout, so the organ's output is
9// CAPTURED -- making the container usable for real services that log to stdout (Elder-AI svcs do).
10//
11// CHANGE vs W4-a (two immediates only; everything else byte-identical):
12// - CreateProcessW arg5 bInheritHandles: FALSE(0) -> TRUE(1) ([rsp+0x20])
13// - CreateProcessW arg6 dwCreationFlags: CREATE_NO_WINDOW(0x08000000) -> 0 ([rsp+0x28])
14// With handle inheritance on and no NO_WINDOW, the child (console app) inherits the supervisor's
15// stdout handle, so its writes flow to wherever the supervisor's stdout points (console or file).
16//
17// Pipeline (same governed run+reap as W2c/W4-a): CreateJobObjectW -> SetInformationJobObject(limit=8)
18// -> AssignProcessToJobObject(self,-1) -> CreateProcessW("nx_win_compiled_organ.exe", inherit=TRUE,
19// flags=0) -> WaitForSingleObject(INFINITE) -> GetExitCodeProcess -> ExitProcess(childExit).
20//
21// NO-FALSE-GREEN: the organ prints "NX\n" and exits 88. With output wired, BOTH must hold: stdout
22// captures "NX" (container output flows out) AND supervisor exit == 88 (governed child reaped). The
23// W4-a non-existent-child control (-> exit 0, rep-stosq-25 zeroes exitCode) still applies.
24//
25// lineage_id: substrate_pe_container_win_io_v1 (evolves substrate_pe_container_win_v1).
26
27import "nx_syscalls.nx"
28import "nx_hal.nx"
29import "nx_pe_writer.nx"
30const PE_MAGIC_1024: i64 = 1024
31
32const PE_CWIO_FILE_SIZE: i64 = 0xA00 // enlarged: .data 0x400 holds sd-server's long cmdline; .idata shifted to file 0x800 (RVA fixed)
33
34func nxcwio_put_utf16(buf: *u8, off: i64, s: *u8) -> i64 {
35 var i: i64 = 0
36 while s[i] != 0 {
37 _w16(buf, off + i * 2, s[i] as i64)
38 i = i + 1
39 }
40 _w16(buf, off + i * 2, 0)
41 return i
42}
43
44func nx_pe_emit_container_io(buf: *u8, cmd: *u8) -> i64 {
45 if (buf as i64) == 0 { return 0 - NX_PE_BAD_INPUT }
46
47 _w16(buf, 0, 0x5A4D)
48 _w32(buf, 0x3C, FOFF_PE_SIG)
49 _w32(buf, FOFF_PE_SIG, 0x00004550)
50
51 _w16(buf, FOFF_COFF + 0, PE_MACHINE_AMD64)
52 _w16(buf, FOFF_COFF + 2, 3)
53 _w16(buf, FOFF_COFF + 16, 0xF0)
54 _w16(buf, FOFF_COFF + 18, PE_CHAR_EXEC | PE_CHAR_LARGE_ADDR)
55
56 _w16(buf, FOFF_OPT + 0, PE_OH_MAGIC_PEPLUS)
57 _w8(buf, FOFF_OPT + 2, 1)
58 _w32(buf, FOFF_OPT + 4, 0x200)
59 _w32(buf, FOFF_OPT + 8, 0x400)
60 _w32(buf, FOFF_OPT + 16, PE_HELLO_RVA_TEXT)
61 _w32(buf, FOFF_OPT + 20, PE_HELLO_RVA_TEXT)
62 _w64(buf, FOFF_OPT + 24, IMG_BASE_LO, IMG_BASE_HI)
63 _w32(buf, FOFF_OPT + 32, 0x1000)
64 _w32(buf, FOFF_OPT + 36, 0x200)
65 _w16(buf, FOFF_OPT + 40, 6)
66 _w16(buf, FOFF_OPT + 48, 6)
67 _w32(buf, FOFF_OPT + 56, 0x4000)
68 _w32(buf, FOFF_OPT + 60, 0x200)
69 _w16(buf, FOFF_OPT + 68, PE_SUBSYSTEM_CONSOLE)
70 _w64(buf, FOFF_OPT + 72, 0x100000, 0)
71 _w64(buf, FOFF_OPT + 80, 0x1000, 0)
72 _w64(buf, FOFF_OPT + 88, 0x100000, 0)
73 _w64(buf, FOFF_OPT + 96, 0x1000, 0)
74 _w32(buf, FOFF_OPT + 108, 16)
75 _w32(buf, FOFF_OPT + 112 + 8, PE_HELLO_RVA_IDATA)
76 _w32(buf, FOFF_OPT + 112 + 12, 0x28)
77
78 _emit_section_header(buf, FOFF_SECT_TBL, 46, 116, 101, 120, 116, 0, 0, 0, 0xF8, PE_HELLO_RVA_TEXT, 0x200, PE_HELLO_FOFF_TEXT, PE_SECT_CODE_X_R)
79 _emit_section_header(buf, FOFF_SECT_TBL + 40, 46, 100, 97, 116, 97, 0, 0, 0, 0x400, PE_HELLO_RVA_RDATA, 0x400, PE_HELLO_FOFF_RDATA, PE_SECT_DATA_RW)
80 _emit_section_header(buf, FOFF_SECT_TBL + 80, 46, 105, 100, 97, 116, 97, 0, 0, 0x4B, PE_HELLO_RVA_IDATA, 0x200, 0x800, PE_SECT_DATA_R)
81 _w32(buf, FOFF_SECT_TBL + 80 + 8, 0x14B)
82
83 // ===== .text (W2c/W4-a pipeline; TWO immediates differ -- see bInheritHandles/dwCreationFlags below) =====
84 let t: i64 = PE_HELLO_FOFF_TEXT
85 _w8(buf, t+0, 0x48); _w8(buf, t+1, 0x81); _w8(buf, t+2, 0xEC); _w32(buf, t+3, 0x138)
86 _w8(buf, t+7, 0x31); _w8(buf, t+8, 0xC0)
87 _w8(buf, t+9, 0x48); _w8(buf, t+10, 0x8D); _w8(buf, t+11, 0x7C); _w8(buf, t+12, 0x24); _w8(buf, t+13, 0x58)
88 _w8(buf, t+14, 0xB9); _w32(buf, t+15, 25) // zero 25 qwords (PROCESS_INFORMATION + exitCode -> launch-fail=exit 0)
89 _w8(buf, t+19, 0xF3); _w8(buf, t+20, 0x48); _w8(buf, t+21, 0xAB)
90 _w8(buf, t+22, 0xC7); _w8(buf, t+23, 0x44); _w8(buf, t+24, 0x24); _w8(buf, t+25, 0x58); _w32(buf, t+26, 0x68)
91 _w8(buf, t+30, 0x31); _w8(buf, t+31, 0xC9); _w8(buf, t+32, 0x31); _w8(buf, t+33, 0xD2)
92 _w8(buf, t+34, 0xFF); _w8(buf, t+35, 0x15); _w32(buf, t+36, 0x2040)
93 _w8(buf, t+40, 0x48); _w8(buf, t+41, 0x89); _w8(buf, t+42, 0x44); _w8(buf, t+43, 0x24); _w8(buf, t+44, 0x50)
94 _w8(buf, t+45, 0xC7); _w8(buf, t+46, 0x84); _w8(buf, t+47, 0x24); _w32(buf, t+48, 0xE8); _w32(buf, t+52, 8)
95 _w8(buf, t+56, 0xC7); _w8(buf, t+57, 0x84); _w8(buf, t+58, 0x24); _w32(buf, t+59, 0x100); _w32(buf, t+63, 8)
96 _w8(buf, t+67, 0x48); _w8(buf, t+68, 0x8B); _w8(buf, t+69, 0x4C); _w8(buf, t+70, 0x24); _w8(buf, t+71, 0x50)
97 _w8(buf, t+72, 0xBA); _w32(buf, t+73, 2)
98 _w8(buf, t+77, 0x4C); _w8(buf, t+78, 0x8D); _w8(buf, t+79, 0x84); _w8(buf, t+80, 0x24); _w32(buf, t+81, 0xD8)
99 _w8(buf, t+85, 0x41); _w8(buf, t+86, 0xB9); _w32(buf, t+87, 0x40)
100 _w8(buf, t+91, 0xFF); _w8(buf, t+92, 0x15); _w32(buf, t+93, 0x200F)
101 _w8(buf, t+97, 0x48); _w8(buf, t+98, 0x8B); _w8(buf, t+99, 0x4C); _w8(buf, t+100, 0x24); _w8(buf, t+101, 0x50)
102 _w8(buf, t+102, 0x48); _w8(buf, t+103, 0xC7); _w8(buf, t+104, 0xC2); _w8(buf, t+105, 0xFF); _w8(buf, t+106, 0xFF); _w8(buf, t+107, 0xFF); _w8(buf, t+108, 0xFF)
103 _w8(buf, t+109, 0xFF); _w8(buf, t+110, 0x15); _w32(buf, t+111, 0x2005)
104 _w8(buf, t+115, 0x31); _w8(buf, t+116, 0xC9)
105 _w8(buf, t+117, 0x48); _w8(buf, t+118, 0x8D); _w8(buf, t+119, 0x15); _w32(buf, t+120, 0xF84)
106 _w8(buf, t+124, 0x45); _w8(buf, t+125, 0x31); _w8(buf, t+126, 0xC0)
107 _w8(buf, t+127, 0x45); _w8(buf, t+128, 0x31); _w8(buf, t+129, 0xC9)
108 // arg5 bInheritHandles = TRUE (W4-b: was 0 in W4-a)
109 _w8(buf, t+130, 0xC7); _w8(buf, t+131, 0x44); _w8(buf, t+132, 0x24); _w8(buf, t+133, 0x20); _w32(buf, t+134, 1)
110 // arg6 dwCreationFlags = 0 (W4-b: was 0x08000000 CREATE_NO_WINDOW in W4-a)
111 _w8(buf, t+138, 0xC7); _w8(buf, t+139, 0x44); _w8(buf, t+140, 0x24); _w8(buf, t+141, 0x28); _w32(buf, t+142, 0)
112 _w8(buf, t+146, 0x48); _w8(buf, t+147, 0xC7); _w8(buf, t+148, 0x44); _w8(buf, t+149, 0x24); _w8(buf, t+150, 0x30); _w32(buf, t+151, 0)
113 _w8(buf, t+155, 0x48); _w8(buf, t+156, 0xC7); _w8(buf, t+157, 0x44); _w8(buf, t+158, 0x24); _w8(buf, t+159, 0x38); _w32(buf, t+160, 0)
114 _w8(buf, t+164, 0x48); _w8(buf, t+165, 0x8D); _w8(buf, t+166, 0x44); _w8(buf, t+167, 0x24); _w8(buf, t+168, 0x58)
115 _w8(buf, t+169, 0x48); _w8(buf, t+170, 0x89); _w8(buf, t+171, 0x44); _w8(buf, t+172, 0x24); _w8(buf, t+173, 0x40)
116 _w8(buf, t+174, 0x48); _w8(buf, t+175, 0x8D); _w8(buf, t+176, 0x84); _w8(buf, t+177, 0x24); _w32(buf, t+178, 0xC0)
117 _w8(buf, t+182, 0x48); _w8(buf, t+183, 0x89); _w8(buf, t+184, 0x44); _w8(buf, t+185, 0x24); _w8(buf, t+186, 0x48)
118 _w8(buf, t+187, 0xFF); _w8(buf, t+188, 0x15); _w32(buf, t+189, 0x1FBF)
119 _w8(buf, t+193, 0x48); _w8(buf, t+194, 0x8B); _w8(buf, t+195, 0x8C); _w8(buf, t+196, 0x24); _w32(buf, t+197, 0xC0)
120 _w8(buf, t+201, 0xBA); _w8(buf, t+202, 0xFF); _w8(buf, t+203, 0xFF); _w8(buf, t+204, 0xFF); _w8(buf, t+205, 0xFF)
121 _w8(buf, t+206, 0xFF); _w8(buf, t+207, 0x15); _w32(buf, t+208, 0x1FB4)
122 _w8(buf, t+212, 0x48); _w8(buf, t+213, 0x8B); _w8(buf, t+214, 0x8C); _w8(buf, t+215, 0x24); _w32(buf, t+216, 0xC0)
123 _w8(buf, t+220, 0x48); _w8(buf, t+221, 0x8D); _w8(buf, t+222, 0x94); _w8(buf, t+223, 0x24); _w32(buf, t+224, 0x118)
124 _w8(buf, t+228, 0xFF); _w8(buf, t+229, 0x15); _w32(buf, t+230, 0x1FA6)
125 _w8(buf, t+234, 0x8B); _w8(buf, t+235, 0x8C); _w8(buf, t+236, 0x24); _w32(buf, t+237, 0x118)
126 _w8(buf, t+241, 0xFF); _w8(buf, t+242, 0x15); _w32(buf, t+243, 0x1FA1)
127 _w8(buf, t+247, 0xCC)
128
129 // ===== .data: child command line (UTF-16) =====
130 nxcwio_put_utf16(buf, PE_HELLO_FOFF_RDATA, cmd)
131
132 // ===== .idata (7 imports, identical to W2c/W4-a) =====
133 let d: i64 = 0x800 // .idata content shifted to file 0x800 (RVA still 0x3000 -> .text IAT refs unchanged)
134 _w32(buf, d+0, 0x3028)
135 _w32(buf, d+12, 0x313E)
136 _w32(buf, d+16, 0x3068)
137 _w64(buf, d+0x28, 0x30A8, 0)
138 _w64(buf, d+0x30, 0x30BC, 0)
139 _w64(buf, d+0x38, 0x30D6, 0)
140 _w64(buf, d+0x40, 0x30F2, 0)
141 _w64(buf, d+0x48, 0x3104, 0)
142 _w64(buf, d+0x50, 0x311A, 0)
143 _w64(buf, d+0x58, 0x3130, 0)
144 _w64(buf, d+0x60, 0, 0)
145 _w64(buf, d+0x68, 0x30A8, 0)
146 _w64(buf, d+0x70, 0x30BC, 0)
147 _w64(buf, d+0x78, 0x30D6, 0)
148 _w64(buf, d+0x80, 0x30F2, 0)
149 _w64(buf, d+0x88, 0x3104, 0)
150 _w64(buf, d+0x90, 0x311A, 0)
151 _w64(buf, d+0x98, 0x3130, 0)
152 _w64(buf, d+0xA0, 0, 0)
153 _w16(buf, d+0xA8, 0)
154 _w8(buf,d+0xAA,67);_w8(buf,d+0xAB,114);_w8(buf,d+0xAC,101);_w8(buf,d+0xAD,97);_w8(buf,d+0xAE,116);_w8(buf,d+0xAF,101)
155 _w8(buf,d+0xB0,74);_w8(buf,d+0xB1,111);_w8(buf,d+0xB2,98);_w8(buf,d+0xB3,79);_w8(buf,d+0xB4,98);_w8(buf,d+0xB5,106)
156 _w8(buf,d+0xB6,101);_w8(buf,d+0xB7,99);_w8(buf,d+0xB8,116);_w8(buf,d+0xB9,87);_w8(buf,d+0xBA,0)
157 _w16(buf, d+0xBC, 0)
158 _w8(buf,d+0xBE,83);_w8(buf,d+0xBF,101);_w8(buf,d+0xC0,116);_w8(buf,d+0xC1,73);_w8(buf,d+0xC2,110);_w8(buf,d+0xC3,102)
159 _w8(buf,d+0xC4,111);_w8(buf,d+0xC5,114);_w8(buf,d+0xC6,109);_w8(buf,d+0xC7,97);_w8(buf,d+0xC8,116);_w8(buf,d+0xC9,105)
160 _w8(buf,d+0xCA,111);_w8(buf,d+0xCB,110);_w8(buf,d+0xCC,74);_w8(buf,d+0xCD,111);_w8(buf,d+0xCE,98);_w8(buf,d+0xCF,79)
161 _w8(buf,d+0xD0,98);_w8(buf,d+0xD1,106);_w8(buf,d+0xD2,101);_w8(buf,d+0xD3,99);_w8(buf,d+0xD4,116);_w8(buf,d+0xD5,0)
162 _w16(buf, d+0xD6, 0)
163 _w8(buf,d+0xD8,65);_w8(buf,d+0xD9,115);_w8(buf,d+0xDA,115);_w8(buf,d+0xDB,105);_w8(buf,d+0xDC,103);_w8(buf,d+0xDD,110)
164 _w8(buf,d+0xDE,80);_w8(buf,d+0xDF,114);_w8(buf,d+0xE0,111);_w8(buf,d+0xE1,99);_w8(buf,d+0xE2,101);_w8(buf,d+0xE3,115)
165 _w8(buf,d+0xE4,115);_w8(buf,d+0xE5,84);_w8(buf,d+0xE6,111);_w8(buf,d+0xE7,74);_w8(buf,d+0xE8,111);_w8(buf,d+0xE9,98)
166 _w8(buf,d+0xEA,79);_w8(buf,d+0xEB,98);_w8(buf,d+0xEC,106);_w8(buf,d+0xED,101);_w8(buf,d+0xEE,99);_w8(buf,d+0xEF,116);_w8(buf,d+0xF0,0)
167 _w16(buf, d+0xF2, 0)
168 _w8(buf,d+0xF4,67);_w8(buf,d+0xF5,114);_w8(buf,d+0xF6,101);_w8(buf,d+0xF7,97);_w8(buf,d+0xF8,116);_w8(buf,d+0xF9,101)
169 _w8(buf,d+0xFA,80);_w8(buf,d+0xFB,114);_w8(buf,d+0xFC,111);_w8(buf,d+0xFD,99);_w8(buf,d+0xFE,101);_w8(buf,d+0xFF,115)
170 _w8(buf,d+0x100,115);_w8(buf,d+0x101,87);_w8(buf,d+0x102,0)
171 _w16(buf, d+0x104, 0)
172 _w8(buf,d+0x106,87);_w8(buf,d+0x107,97);_w8(buf,d+0x108,105);_w8(buf,d+0x109,116);_w8(buf,d+0x10A,70);_w8(buf,d+0x10B,111)
173 _w8(buf,d+0x10C,114);_w8(buf,d+0x10D,83);_w8(buf,d+0x10E,105);_w8(buf,d+0x10F,110);_w8(buf,d+0x110,103);_w8(buf,d+0x111,108)
174 _w8(buf,d+0x112,101);_w8(buf,d+0x113,79);_w8(buf,d+0x114,98);_w8(buf,d+0x115,106);_w8(buf,d+0x116,101);_w8(buf,d+0x117,99)
175 _w8(buf,d+0x118,116);_w8(buf,d+0x119,0)
176 _w16(buf, d+0x11A, 0)
177 _w8(buf,d+0x11C,71);_w8(buf,d+0x11D,101);_w8(buf,d+0x11E,116);_w8(buf,d+0x11F,69);_w8(buf,d+0x120,120);_w8(buf,d+0x121,105)
178 _w8(buf,d+0x122,116);_w8(buf,d+0x123,67);_w8(buf,d+0x124,111);_w8(buf,d+0x125,100);_w8(buf,d+0x126,101);_w8(buf,d+0x127,80)
179 _w8(buf,d+0x128,114);_w8(buf,d+0x129,111);_w8(buf,d+0x12A,99);_w8(buf,d+0x12B,101);_w8(buf,d+0x12C,115);_w8(buf,d+0x12D,115)
180 _w8(buf,d+0x12E,0)
181 _w16(buf, d+0x130, 0)
182 _w8(buf,d+0x132,69);_w8(buf,d+0x133,120);_w8(buf,d+0x134,105);_w8(buf,d+0x135,116);_w8(buf,d+0x136,80);_w8(buf,d+0x137,114)
183 _w8(buf,d+0x138,111);_w8(buf,d+0x139,99);_w8(buf,d+0x13A,101);_w8(buf,d+0x13B,115);_w8(buf,d+0x13C,115);_w8(buf,d+0x13D,0)
184 _w8(buf,d+0x13E,107);_w8(buf,d+0x13F,101);_w8(buf,d+0x140,114);_w8(buf,d+0x141,110);_w8(buf,d+0x142,101);_w8(buf,d+0x143,108)
185 _w8(buf,d+0x144,51);_w8(buf,d+0x145,50);_w8(buf,d+0x146,46);_w8(buf,d+0x147,100);_w8(buf,d+0x148,108);_w8(buf,d+0x149,108);_w8(buf,d+0x14A,0)
186
187 return NX_PE_OK
188}
189
190func gen_puts(s: *u8) -> i64 { var k: i64 = 0; while s[k] != (0 as u8) { k = k + 1 } sys_write(1, s, k); return 0 }
191
192func gen_emit_one(cmd: *u8, outpath: *u8) -> i64 {
193 let buf: *u8 = nx_hal_alloc_pages(PE_CWIO_FILE_SIZE)
194 if (buf as i64) == 0 { return 0 - 1 }
195 if nx_pe_emit_container_io(buf, cmd) != NX_PE_OK { return 0 - 2 }
196 if buf[0] != 0x4D { return 0 - 3 }
197 if nx_pe_write_to_file(outpath, buf, PE_CWIO_FILE_SIZE) != NX_PE_OK { return 0 - 4 }
198 return 0
199}
200
201// Generalized: emit one Job-Object container PE per line of data/elder_containers.tsv
202// (OUTNAME<TAB>CMDLINE = OCI process.args). One emitter, N containers -- the sovereign compose source.
203func main() -> i64 {
204 let lenp: *i64 = sys_mmap(8) as *i64
205 let spec: *u8 = sys_read_file("data/elder_containers.tsv\x00" as *u8, lenp)
206 if (spec as i64) == 0 { gen_puts("GEN: cannot read data/elder_containers.tsv\n" as *u8); return 1 }
207 let n: i64 = lenp[0]
208 let prefix: *u8 = "/mnt/c/Users/elder/nishi-core/nxc2/_offc/" as *u8
209 var emitted: i64 = 0
210 var ls: i64 = 0
211 var i: i64 = 0
212 while i <= n {
213 var atend: i64 = 0
214 if i == n { atend = 1 }
215 if i < n { if spec[i] == (10 as u8) { atend = 1 } }
216 if atend == 1 {
217 if i > ls { if spec[ls] != (35 as u8) {
218 var tab: i64 = ls
219 while tab < i { if spec[tab] == (9 as u8) { break } tab = tab + 1 }
220 if tab < i {
221 let outpath: *u8 = sys_mmap(512)
222 var pi: i64 = 0
223 while prefix[pi] != (0 as u8) { outpath[pi] = prefix[pi]; pi = pi + 1 }
224 var oi: i64 = ls
225 while oi < tab { outpath[pi] = spec[oi]; pi = pi + 1; oi = oi + 1 }
226 outpath[pi] = 0 as u8
227 let cmd: *u8 = sys_mmap(PE_MAGIC_1024)
228 var ci: i64 = 0
229 var si: i64 = tab + 1
230 while si < i { cmd[ci] = spec[si]; ci = ci + 1; si = si + 1 }
231 cmd[ci] = 0 as u8
232 if gen_emit_one(cmd, outpath) == 0 { gen_puts("EMIT " as *u8); gen_puts(outpath); gen_puts("\n" as *u8); emitted = emitted + 1 }
233 else { gen_puts("FAIL " as *u8); gen_puts(outpath); gen_puts("\n" as *u8) }
234 }
235 } }
236 ls = i + 1
237 }
238 i = i + 1
239 }
240 gen_puts("GEN DONE\n" as *u8)
241 return 0
242}