code wiki / _hdl_build / nx_boot_uefi_probe.nx
nx_boot_uefi_probe.nx source
↩ module page · 232 lines · 13131 B
1// nx_boot_uefi_probe.nx -- NOS-R0.1 of the NISHI OS ladder: the UEFI auto-discovery seed.
2//
3// Extends NOS-R0 (nx_boot_uefi): the emitted subsystem-10 EFI_APPLICATION now READS THE
4// MACHINE BACK TO US. Its position-independent entry walks the UEFI SystemTable and prints,
5// via ConOut->OutputString: (1) the "NISHI" banner, then (2) the firmware's OWN vendor
6// string (SystemTable->FirmwareVendor @ +0x18) -- real, unfakeable hardware identity read off
7// the unknown laptop. That readback is the seed of "auto-discover the machine, then install":
8// the OS interrogating firmware instead of being told the specs. GetMemoryMap (the RAM-layout
9// read an installer needs) is the next rung, NOS-R0.2.
10//
11// Same sovereign PE32+ wrapper as nx_boot_uefi (subsystem 10, no imports, PIC entry); only the
12// .text logic grows. Entry ABI (MS x64): RCX=ImageHandle, RDX=SystemTable*. Nonvolatile regs
13// (RSI=SystemTable, RDI=ConOut) survive the firmware calls; pushed/popped per ABI.
14// SystemTable: +0x18 FirmwareVendor(CHAR16*), +0x40 ConOut(EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*)
15// ConOut: +0x08 OutputString(This, CHAR16*)
16//
17// Build (sovereign): ./_offc/nx_sov_build_run.elf nx_boot_uefi_probe (nx_cc->nxasm, no gcc)
18// Self-gate (no mocks): byte-reproducible + structural (machine=0x8664, subsystem=10, PE/MZ,
19// entry=0x1000, entry[0]=push rsi, and the ConOut-read opcodes `48 8B 7E 40` present =
20// proves the discovery read is wired) + tamper liar-kill (subsystem->3 must reject).
21// Scope (honest): EMIT-proven. BOOT/READ-proven (real firmware prints its vendor) = on the
22// laptop USB, after NOS-R0 boots clean. VERDICT log -> knowledge/status/nishi_os.log.
23// Sovereign: syscalls only, no gcc/.sh. license_tier: ORIGINAL
24import "nx_syscalls.nx"
25const PE_MAGIC_4096: i64 = 4096
26
27// ===== PE/COFF + UEFI constants (mirror nx_boot_uefi) ===========================
28const PE_FILE_SIZE: i64 = 0x400
29const PE_MACHINE_AMD64: i64 = 0x8664
30const PE_OH_MAGIC_PEPLUS: i64 = 0x020B
31const PE_SUBSYSTEM_EFI_APP: i64 = 10
32const PE_CHAR_EXEC: i64 = 0x0002
33const PE_CHAR_LARGE_ADDR: i64 = 0x0020
34const PE_SECT_CODE_X_R: i64 = 0x60000020
35
36const FOFF_PE_SIG: i64 = 0x80
37const FOFF_COFF: i64 = 0x84
38const FOFF_OPT: i64 = 0x98
39const FOFF_SECT_TBL: i64 = 0x188
40const FOFF_TEXT: i64 = 0x200
41const RVA_TEXT: i64 = 0x1000
42const OPT_SUBSYS: i64 = 0x98 + 68
43const OPT_ENTRY: i64 = 0x98 + 16
44const IMG_BASE: i64 = 0x10000000
45const TEXT_VSIZE: i64 = 0x67 // 71 bytes code (ends 0x46) + 3 UTF-16 strings (0x47..0x66)
46
47// ===== little-endian byte writers / readers =====================================
48func _w8(buf: *u8, off: i64, v: i64) -> i64 { buf[off] = (v & 0xff) as u8; return off + 1 }
49func _w16(buf: *u8, off: i64, v: i64) -> i64 { _w8(buf, off, v); _w8(buf, off + 1, v >> 8); return off + 2 }
50func _w32(buf: *u8, off: i64, v: i64) -> i64 {
51 _w8(buf, off, v); _w8(buf, off + 1, v >> 8); _w8(buf, off + 2, v >> 16); _w8(buf, off + 3, v >> 24)
52 return off + 4
53}
54func _w64(buf: *u8, off: i64, v: i64) -> i64 { _w32(buf, off, v); _w32(buf, off + 4, v >> 32); return off + 8 }
55func _r16(buf: *u8, off: i64) -> i64 { return (buf[off] as i64) | ((buf[off + 1] as i64) << 8) }
56func _r32(buf: *u8, off: i64) -> i64 {
57 return (buf[off] as i64) | ((buf[off + 1] as i64) << 8) | ((buf[off + 2] as i64) << 16) | ((buf[off + 3] as i64) << 24)
58}
59
60// ===== the EFI image author =====================================================
61func uefi_emit(buf: *u8) -> i64 {
62 // ----- DOS header + PE sig -----
63 _w16(buf, 0, 0x5A4D) // 'MZ'
64 _w32(buf, 0x3C, FOFF_PE_SIG)
65 _w32(buf, FOFF_PE_SIG, 0x00004550) // 'PE\0\0'
66
67 // ----- COFF header -----
68 _w16(buf, FOFF_COFF + 0, PE_MACHINE_AMD64)
69 _w16(buf, FOFF_COFF + 2, 1)
70 _w16(buf, FOFF_COFF + 16, 0xF0)
71 _w16(buf, FOFF_COFF + 18, PE_CHAR_EXEC | PE_CHAR_LARGE_ADDR)
72
73 // ----- Optional header (PE32+) -----
74 _w16(buf, FOFF_OPT + 0, PE_OH_MAGIC_PEPLUS)
75 _w8(buf, FOFF_OPT + 2, 1)
76 _w32(buf, FOFF_OPT + 4, 0x200) // SizeOfCode
77 _w32(buf, FOFF_OPT + 16, RVA_TEXT) // AddressOfEntryPoint
78 _w32(buf, FOFF_OPT + 20, RVA_TEXT) // BaseOfCode
79 _w64(buf, FOFF_OPT + 24, IMG_BASE) // ImageBase
80 _w32(buf, FOFF_OPT + 32, 0x1000) // SectionAlignment
81 _w32(buf, FOFF_OPT + 36, 0x200) // FileAlignment
82 _w32(buf, FOFF_OPT + 56, 0x2000) // SizeOfImage
83 _w32(buf, FOFF_OPT + 60, 0x200) // SizeOfHeaders
84 _w16(buf, FOFF_OPT + 68, PE_SUBSYSTEM_EFI_APP) // Subsystem = 10
85 _w64(buf, FOFF_OPT + 72, 0x100000) // SizeOfStackReserve
86 _w64(buf, FOFF_OPT + 80, 0x1000) // SizeOfStackCommit
87 _w64(buf, FOFF_OPT + 88, 0x100000) // SizeOfHeapReserve
88 _w64(buf, FOFF_OPT + 96, 0x1000) // SizeOfHeapCommit
89 _w32(buf, FOFF_OPT + 108, 16) // NumberOfRvaAndSizes
90
91 // ----- section header: .text -----
92 _w8(buf, FOFF_SECT_TBL + 0, 46) // '.'
93 _w8(buf, FOFF_SECT_TBL + 1, 116) // 't'
94 _w8(buf, FOFF_SECT_TBL + 2, 101) // 'e'
95 _w8(buf, FOFF_SECT_TBL + 3, 120) // 'x'
96 _w8(buf, FOFF_SECT_TBL + 4, 116) // 't'
97 _w32(buf, FOFF_SECT_TBL + 8, TEXT_VSIZE) // VirtualSize
98 _w32(buf, FOFF_SECT_TBL + 12, RVA_TEXT)
99 _w32(buf, FOFF_SECT_TBL + 16, 0x200) // SizeOfRawData
100 _w32(buf, FOFF_SECT_TBL + 20, FOFF_TEXT) // PointerToRawData
101 _w32(buf, FOFF_SECT_TBL + 36, PE_SECT_CODE_X_R)
102
103 // ----- .text: PIC UEFI entry that reads + prints the firmware vendor -----
104 var o: i64 = FOFF_TEXT
105 // prologue
106 o = _w8(buf, o, 0x56) // push rsi
107 o = _w8(buf, o, 0x57) // push rdi
108 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x89); o = _w8(buf, o, 0xD6) // mov rsi,rdx (RSI = SystemTable)
109 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8B); o = _w8(buf, o, 0x7E); o = _w8(buf, o, 0x40) // mov rdi,[rsi+0x40] (RDI = ConOut)
110 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x83); o = _w8(buf, o, 0xEC); o = _w8(buf, o, 0x28) // sub rsp,0x28
111 // P1: OutputString(ConOut, &banner)
112 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x89); o = _w8(buf, o, 0xF9) // mov rcx,rdi
113 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8D); o = _w8(buf, o, 0x15); o = _w32(buf, o, 0x30) // lea rdx,[rip+0x30] -> strA @0x47
114 o = _w8(buf, o, 0xFF); o = _w8(buf, o, 0x57); o = _w8(buf, o, 0x08) // call [rdi+8]
115 // P2: OutputString(ConOut, &label "FW: ")
116 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x89); o = _w8(buf, o, 0xF9) // mov rcx,rdi
117 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8D); o = _w8(buf, o, 0x15); o = _w32(buf, o, 0x33) // lea rdx,[rip+0x33] -> strB @0x57
118 o = _w8(buf, o, 0xFF); o = _w8(buf, o, 0x57); o = _w8(buf, o, 0x08) // call [rdi+8]
119 // P3: OutputString(ConOut, SystemTable->FirmwareVendor) <-- the auto-discovery read
120 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x89); o = _w8(buf, o, 0xF9) // mov rcx,rdi
121 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8B); o = _w8(buf, o, 0x56); o = _w8(buf, o, 0x18) // mov rdx,[rsi+0x18] (FirmwareVendor)
122 o = _w8(buf, o, 0xFF); o = _w8(buf, o, 0x57); o = _w8(buf, o, 0x08) // call [rdi+8]
123 // P4: OutputString(ConOut, &newline)
124 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x89); o = _w8(buf, o, 0xF9) // mov rcx,rdi
125 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8D); o = _w8(buf, o, 0x15); o = _w32(buf, o, 0x26) // lea rdx,[rip+0x26] -> strC @0x61
126 o = _w8(buf, o, 0xFF); o = _w8(buf, o, 0x57); o = _w8(buf, o, 0x08) // call [rdi+8]
127 // epilogue
128 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x83); o = _w8(buf, o, 0xC4); o = _w8(buf, o, 0x28) // add rsp,0x28
129 o = _w8(buf, o, 0x5F) // pop rdi
130 o = _w8(buf, o, 0x5E) // pop rsi
131 o = _w8(buf, o, 0x31); o = _w8(buf, o, 0xC0) // xor eax,eax (EFI_SUCCESS)
132 o = _w8(buf, o, 0xC3) // ret
133 // strA @ .text+0x47 : "NISHI\r\n\0" (immediately after ret at 0x46)
134 o = _w16(buf, o, 0x4E); o = _w16(buf, o, 0x49); o = _w16(buf, o, 0x53)
135 o = _w16(buf, o, 0x48); o = _w16(buf, o, 0x49)
136 o = _w16(buf, o, 0x0D); o = _w16(buf, o, 0x0A); o = _w16(buf, o, 0x00)
137 // strB @ .text+0x57 : "FW: \0"
138 o = _w16(buf, o, 0x46); o = _w16(buf, o, 0x57); o = _w16(buf, o, 0x3A); o = _w16(buf, o, 0x20); o = _w16(buf, o, 0x00)
139 // strC @ .text+0x61 : "\r\n\0"
140 o = _w16(buf, o, 0x0D); o = _w16(buf, o, 0x0A); o = _w16(buf, o, 0x00)
141
142 return PE_FILE_SIZE
143}
144
145// ===== structural self-gate =====================================================
146func uefi_verify(buf: *u8) -> i64 {
147 if buf[0] != (0x4D as u8) { return 0 }
148 if buf[1] != (0x5A as u8) { return 0 }
149 if _r32(buf, 0x3C) != FOFF_PE_SIG { return 0 }
150 if _r32(buf, FOFF_PE_SIG) != 0x00004550 { return 0 }
151 if _r16(buf, FOFF_COFF) != PE_MACHINE_AMD64 { return 0 }
152 if _r16(buf, FOFF_OPT) != PE_OH_MAGIC_PEPLUS { return 0 }
153 if _r16(buf, OPT_SUBSYS) != PE_SUBSYSTEM_EFI_APP { return 0 }
154 if _r32(buf, OPT_ENTRY) != RVA_TEXT { return 0 }
155 if buf[FOFF_TEXT] != (0x56 as u8) { return 0 } // entry[0] = push rsi
156 // the ConOut read `mov rdi,[rsi+0x40]` at .text+0x05 = 48 8B 7E 40 (discovery wiring proof)
157 if buf[FOFF_TEXT + 5] != (0x48 as u8) { return 0 }
158 if buf[FOFF_TEXT + 6] != (0x8B as u8) { return 0 }
159 if buf[FOFF_TEXT + 7] != (0x7E as u8) { return 0 }
160 if buf[FOFF_TEXT + 8] != (0x40 as u8) { return 0 }
161 // the FirmwareVendor read `mov rdx,[rsi+0x18]` = 48 8B 56 18 (the auto-discovery read itself)
162 if buf[FOFF_TEXT + 0x2A] != (0x48 as u8) { return 0 }
163 if buf[FOFF_TEXT + 0x2B] != (0x8B as u8) { return 0 }
164 if buf[FOFF_TEXT + 0x2C] != (0x56 as u8) { return 0 }
165 if buf[FOFF_TEXT + 0x2D] != (0x18 as u8) { return 0 }
166 return 1
167}
168
169// ===== I/O + log helpers ========================================================
170func u_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
171func u_fp(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
172func u_fn(fd: i64, v: i64) -> i64 {
173 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m }
174 let t: *u8 = sys_mmap(28); var k: i64 = 0
175 if m == 0 { t[0] = 48; k = 1 }
176 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
177 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
178 sys_write(fd, bb, k); return 0
179}
180func u_log(sz: i64, repro: i64, structural: i64, tamper: i64, verdict: *u8) -> i64 {
181 let lfd: i64 = sys_openat_append("knowledge/status/nishi_os.log" as *u8, 0x1a4)
182 if lfd < 0 { return 0 - 1 }
183 u_fp(lfd, "NOSR0_1 name=nx_boot_uefi_probe.efi subsystem=10 climate=x86_64-uefi reads=firmware-vendor bytes=" as *u8); u_fn(lfd, sz)
184 u_fp(lfd, " repro=" as *u8); u_fn(lfd, repro)
185 u_fp(lfd, " structural=" as *u8); u_fn(lfd, structural)
186 u_fp(lfd, " tamper_caught=" as *u8); u_fn(lfd, tamper)
187 u_fp(lfd, " scope=emit-proven(read-proof=on-laptop) verdict=" as *u8); u_fp(lfd, verdict); u_fp(lfd, "\n" as *u8)
188 sys_close(lfd); return 0
189}
190
191func main(argc: i64, argv: *i64) -> i64 {
192 let buf: *u8 = sys_mmap(PE_MAGIC_4096)
193 let buf2: *u8 = sys_mmap(PE_MAGIC_4096)
194 let sz: i64 = uefi_emit(buf)
195 let sz2: i64 = uefi_emit(buf2)
196
197 var repro: i64 = 1
198 if sz != sz2 { repro = 0 }
199 var i: i64 = 0
200 while i < sz { if buf[i] != buf2[i] { repro = 0 } i = i + 1 }
201
202 let structural: i64 = uefi_verify(buf)
203
204 _w16(buf2, OPT_SUBSYS, 3)
205 var tamper_caught: i64 = 0
206 if uefi_verify(buf2) == 0 { tamper_caught = 1 }
207
208 var green: i64 = 0
209 if repro == 1 { if structural == 1 { if tamper_caught == 1 { green = 1 } } }
210
211 if green == 1 {
212 let ofd: i64 = sys_openat_wr("_offc/nx_boot_uefi_probe.efi" as *u8, 0x1a4)
213 if ofd < 0 {
214 u_p("NOS-R0.1 RED: cannot write _offc/nx_boot_uefi_probe.efi\n" as *u8)
215 u_log(sz, repro, structural, tamper_caught, "RED" as *u8)
216 sys_exit(1); return 1
217 }
218 sys_write(ofd, buf, sz)
219 sys_close(ofd)
220 u_p("NOS-R0.1 GREEN: authored _offc/nx_boot_uefi_probe.efi (reads+prints firmware vendor) bytes=" as *u8)
221 u_fn(1, sz)
222 u_p(" repro+structural(+ConOut/vendor-read opcodes)+tamper all pass\n" as *u8)
223 u_log(sz, repro, structural, tamper_caught, "GREEN" as *u8)
224 sys_exit(0); return 0
225 }
226
227 u_p("NOS-R0.1 RED: repro=" as *u8); u_fn(1, repro)
228 u_p(" structural=" as *u8); u_fn(1, structural)
229 u_p(" tamper_caught=" as *u8); u_fn(1, tamper_caught); u_p("\n" as *u8)
230 u_log(sz, repro, structural, tamper_caught, "RED" as *u8)
231 sys_exit(1); return 1
232}