code wiki / _hdl_build / nx_nxos_shim.nx

nx_nxos_shim.nx source

↩ module page · 616 lines · 45604 B

1// nx_nxos_shim.nx -- N1-full: emit the Nishi OS BOOT SHIM (BOOTX64.EFI). Constitution A2: PE32+ exists 2// ONLY here, at the UEFI firmware boundary -- the one toll every 2026 OS pays. Everything the shim 3// LOADS is Nishi-native NXE, and as of N1-full it is READ FROM THE ESP AT BOOT: the shim walks 4// HandleProtocol(LoadedImage) -> DeviceHandle -> HandleProtocol(SimpleFileSystem) -> OpenVolume -> 5// Open(L"KERNEL.NXE", READ) -> Read into a zero-filled in-image reserve, then VALIDATES it 6// (magic+ver qword vs an expected constant, payload sum64 re-derived vs the header -- wrong = a 7// loud "NXE!" on ConOut then hold, NEVER a blind jump), queries GOP for the framebuffer, builds 8// boot-info {fb_base,fb_size,...}, sets rbx=&bootinfo and jumps to the NXE entry. The kernel is a 9// FILE on the ESP now, not bytes baked into the loader -- a kernel update is a file copy. 10// 11// NEVER-BRICK (#26): every firmware call the shim makes is read-only discovery or a READ-mode 12// file operation -- LocateProtocol, HandleProtocol x2, OpenVolume, Open(mode=READ ONLY), Read -- 13// plus ConOut OutputString on the refusal path ONLY. The call census below pins the EXACT set; 14// a writable Open cannot appear without flipping a tooth. Zero Set-Variable-class calls, zero 15// flash/firmware writes. Section is CODE|READ|WRITE|EXEC (0xE0000020) because boot-info and the 16// kernel reserve live in-image. 17// license_tier: ORIGINAL 18import "nx_syscalls.nx" 19const EMIT_BUF_PAGE: i64 = 4096 20 21const FOFF_PE_SIG: i64 = 0x80 22const FOFF_COFF: i64 = 0x84 23const FOFF_OPT: i64 = 0x98 24const FOFF_SECT_TBL: i64 = 0x188 25const FOFF_TEXT: i64 = 0x200 26const RVA_TEXT: i64 = 0x1000 27const IMG_BASE: i64 = 0x10000000 28// Section layout. Code runs [0,SOFF_SCRATCH); data follows. EVERY rip-relative displacement 29// below is computed from the LIVE emit position (`o`) rather than a hand-copied literal, and 30// every forward branch to BAD is rel32 -- the rel8 trap has bitten five times in this lane and 31// a growing body makes the short form a false economy. 32const SOFF_SCRATCH: i64 = 0x400 // file-chain slots: +00 li* +08 fs* +10 root* +18 file* 33 // +20 readsize (preloaded NXE_MAX; Read rewrites it) 34 // +28 aifile* +30 ai readsize (preloaded AI_MAX) 35const SOFF_BOOTINFO: i64 = 0x480 // +00 fb · +08 fbsize · +10 conin · +18 tally · +20 key 36 // +28 mapkey · +30 imagehandle · +38 systab · +40 mapbuf 37 // +48 mapsize · +50 descsize · +58 descver 38 // +60 gmm_status · +68 ebs_status · +70 nxe_entry (0x80 wide) 39const SOFF_EXPECT: i64 = 0x500 40const SOFF_ERRSTR: i64 = 0x510 41const SOFF_GUID: i64 = 0x520 // GOP GUID 42const SOFF_LIGUID: i64 = 0x530 // EFI_LOADED_IMAGE_PROTOCOL GUID 43const SOFF_FSGUID: i64 = 0x540 // EFI_SIMPLE_FILE_SYSTEM_PROTOCOL GUID 44const SOFF_FNAME: i64 = 0x550 // UTF-16LE "KERNEL.NXE" + NUL (22 bytes) 45const SOFF_AINAME: i64 = 0x570 // UTF-16LE "NISHI.AI" + NUL (18 bytes) -- the OPTIONAL file 46// The map buffer and the kernel reserve are VIRTUAL-ONLY: the raw file ends at RAW_DATA_END and 47// the PE loader zero-fills [RAW_DATA_END, VirtualSize). Firmware supplies both regions and we 48// never call AllocatePool while boot services are alive. 49const SOFF_MMBUF: i64 = 0x5C0 50const MM_BUF_BYTES: i64 = 0x4000 // 16 KiB for the memory map 51const SOFF_NXE: i64 = 0x45C0 // = SOFF_MMBUF + MM_BUF_BYTES; the file-read lands here 52const SOFF_AI: i64 = 0x6DC0 // = SOFF_NXE + NXE_MAX; the OPTIONAL assistant blob lands here 53const AI_MAX: i64 = 0x1000 // 4 KiB assistant reserve. Same ceiling discipline as NXE_MAX: 54 // the Read request size IS this number, so an oversized file is 55 // truncated, fails its own sum64, and is REFUSED -- never 56 // half-loaded and used. 57const NXE_MAX: i64 = 0x2800 // kernel reserve ceiling. The emitter REFUSES a KERNEL.NXE 58 // larger than this -- a ceiling nobody checks is a silent 59 // wrap, and a truncated Read would only surface as a boot 60 // mystery. Raise it HERE when the kernel grows (and mind the 61 // emulator's 0x8000 stack top: image end must stay below it). 62const RAW_DATA_END: i64 = 0x600 // raw file: code + constants only, 0x200-aligned 63 64func _w8(b: *u8, o: i64, v: i64) -> i64 { b[o] = (v & 0xff) as u8; return o + 1 } 65func _w16(b: *u8, o: i64, v: i64) -> i64 { _w8(b,o,v); _w8(b,o+1,v>>8); return o + 2 } 66func _w32(b: *u8, o: i64, v: i64) -> i64 { _w8(b,o,v); _w8(b,o+1,v>>8); _w8(b,o+2,v>>16); _w8(b,o+3,v>>24); return o + 4 } 67func _w64(b: *u8, o: i64, v: i64) -> i64 { _w32(b, o, v); _w32(b, o + 4, v >> 32); return o + 8 } 68func _r16(b: *u8, o: i64) -> i64 { return (b[o] as i64) | ((b[o + 1] as i64) << 8) } 69func _r32(b: *u8, o: i64) -> i64 { return (b[o] as i64) | ((b[o+1] as i64)<<8) | ((b[o+2] as i64)<<16) | ((b[o+3] as i64)<<24) } 70func _r64(b: *u8, o: i64) -> i64 { 71 var v: i64 = 0; var i: i64 = 0 72 while i < 8 { v = v | ((b[o + i] as i64) << (8 * i)); i = i + 1 } 73 return v 74} 75func e_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 76func e_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 } 77func e_fn(fd: i64, v: i64) -> i64 { 78 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m } 79 let t: *u8 = sys_mmap(28); var k: i64 = 0 80 if m == 0 { t[0] = 48; k = 1 } 81 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 82 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 83 sys_write(fd, bb, k); return 0 84} 85// rel8 that REFUSES an out-of-range displacement instead of masking it -- the raw `& 0xff` form 86// wraps into the middle of an instruction and leaves the build green. Refusal is a build error. 87func rel8f(target: i64, next_ip: i64) -> i64 { 88 let d: i64 = target - next_ip 89 if d > 127 { e_p("NXSHIM EMIT REFUSED: rel8 out of range d=" as *u8); e_fn(1, d); e_p("\n" as *u8); sys_exit(3) } 90 if d < (0 - 128) { e_p("NXSHIM EMIT REFUSED: rel8 out of range d=" as *u8); e_fn(1, d); e_p("\n" as *u8); sys_exit(3) } 91 return d & 0xff 92} 93 94// EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID (UEFI spec bytes, mixed-endian) 95func gop_guid_byte(i: i64) -> i64 { 96 if i==0 { return 0xDE } if i==1 { return 0xA9 } if i==2 { return 0x42 } if i==3 { return 0x90 } 97 if i==4 { return 0xDC } if i==5 { return 0x23 } if i==6 { return 0x38 } if i==7 { return 0x4A } 98 if i==8 { return 0x96 } if i==9 { return 0xFB } if i==10 { return 0x7A } if i==11 { return 0xDE } 99 if i==12 { return 0xD0 } if i==13 { return 0x80 } if i==14 { return 0x51 } return 0x6A 100} 101// EFI_LOADED_IMAGE_PROTOCOL_GUID 5B1B31A1-9562-11d2-8E3F-00A0C969723B (spec bytes, mixed-endian) 102func li_guid_byte(i: i64) -> i64 { 103 if i==0 { return 0xA1 } if i==1 { return 0x31 } if i==2 { return 0x1B } if i==3 { return 0x5B } 104 if i==4 { return 0x62 } if i==5 { return 0x95 } if i==6 { return 0xD2 } if i==7 { return 0x11 } 105 if i==8 { return 0x8E } if i==9 { return 0x3F } if i==10 { return 0x00 } if i==11 { return 0xA0 } 106 if i==12 { return 0xC9 } if i==13 { return 0x69 } if i==14 { return 0x72 } return 0x3B 107} 108// EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID 964E5B22-6459-11D2-8E39-00A0C969723B (spec bytes, mixed-endian) 109func fs_guid_byte(i: i64) -> i64 { 110 if i==0 { return 0x22 } if i==1 { return 0x5B } if i==2 { return 0x4E } if i==3 { return 0x96 } 111 if i==4 { return 0x59 } if i==5 { return 0x64 } if i==6 { return 0xD2 } if i==7 { return 0x11 } 112 if i==8 { return 0x8E } if i==9 { return 0x39 } if i==10 { return 0x00 } if i==11 { return 0xA0 } 113 if i==12 { return 0xC9 } if i==13 { return 0x69 } if i==14 { return 0x72 } return 0x3B 114} 115// ASCII of "KERNEL.NXE" -- the writer AND the gate comparator both read this one table; the gate's 116// tamper bite (t6) proves the comparator actually discriminates. 117func fname_ch(i: i64) -> i64 { 118 if i==0 { return 0x4B } if i==1 { return 0x45 } if i==2 { return 0x52 } if i==3 { return 0x4E } 119 if i==4 { return 0x45 } if i==5 { return 0x4C } if i==6 { return 0x2E } if i==7 { return 0x4E } 120 if i==8 { return 0x58 } if i==9 { return 0x45 } return 0 121} 122// ASCII of "NISHI.AI" -- the OPTIONAL assistant blob 123func ainame_ch(i: i64) -> i64 { 124 if i==0 { return 0x4E } if i==1 { return 0x49 } if i==2 { return 0x53 } if i==3 { return 0x48 } 125 if i==4 { return 0x49 } if i==5 { return 0x2E } if i==6 { return 0x41 } if i==7 { return 0x49 } 126 return 0 127} 128// gate comparators (also exercised by the t6 non-vacuity bite) 129func chk_guids(buf: *u8) -> i64 { 130 var i: i64 = 0 131 while i < 16 { 132 if (buf[FOFF_TEXT + SOFF_GUID + i] as i64) != gop_guid_byte(i) { return 0 } 133 if (buf[FOFF_TEXT + SOFF_LIGUID + i] as i64) != li_guid_byte(i) { return 0 } 134 if (buf[FOFF_TEXT + SOFF_FSGUID + i] as i64) != fs_guid_byte(i) { return 0 } 135 i = i + 1 136 } 137 return 1 138} 139func chk_fname(buf: *u8) -> i64 { 140 var i: i64 = 0 141 while i < 10 { 142 if (buf[FOFF_TEXT + SOFF_FNAME + i * 2] as i64) != fname_ch(i) { return 0 } 143 if (buf[FOFF_TEXT + SOFF_FNAME + i * 2 + 1] as i64) != 0 { return 0 } 144 i = i + 1 145 } 146 if (buf[FOFF_TEXT + SOFF_FNAME + 20] as i64) != 0 { return 0 } 147 if (buf[FOFF_TEXT + SOFF_FNAME + 21] as i64) != 0 { return 0 } 148 i = 0 149 while i < 8 { 150 if (buf[FOFF_TEXT + SOFF_AINAME + i * 2] as i64) != ainame_ch(i) { return 0 } 151 if (buf[FOFF_TEXT + SOFF_AINAME + i * 2 + 1] as i64) != 0 { return 0 } 152 i = i + 1 153 } 154 if (buf[FOFF_TEXT + SOFF_AINAME + 16] as i64) != 0 { return 0 } 155 if (buf[FOFF_TEXT + SOFF_AINAME + 17] as i64) != 0 { return 0 } 156 return 1 157} 158 159// ===== shim .text: every byte commented; BAD path + data laid out below ========================== 160// The emitter RECORDS every FF-prefixed control transfer it emits (site + kind) so the never-brick 161// census is taken over INSTRUCTIONS THE EMITTER ACTUALLY EMITTED, not over bytes that merely look 162// like one. This replaced a byte scan that FALSE-FLAGGED `48 8D 05 FF 00 00 00` (lea rax,[rip+255]) 163// -- the 0xFF was a displacement byte. Same family as the kernel's byte-frequency tooth: 164// A BYTE SCAN IS A PROXY; THE EMITTER IS THE AUTHORITY ON WHAT IT EMITTED. 165// kind: 1 = call rax (firmware service) - 2 = call [rax+8] (ConOut refusal) - 3 = jmp rax (handoff) 166func ff_rec(site: *i64, kind: *i64, n: *i64, at: i64, k: i64) -> i64 { 167 site[n[0]] = at; kind[n[0]] = k; n[0] = n[0] + 1; return 0 168} 169func emit_code(t: *u8, ffsite: *i64, ffkind: *i64, ffn: *i64) -> i64 { 170 var o: i64 = 0 171 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xEC); o=_w8(t,o,0x48) // sub rsp,0x48 172 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x54); o=_w8(t,o,0x24); o=_w8(t,o,0x40) // mov [rsp+0x40],rdx systab 173 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x4C); o=_w8(t,o,0x24); o=_w8(t,o,0x38) // mov [rsp+0x38],rcx ImageHandle 174 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x42); o=_w8(t,o,0x60) // mov rax,[rdx+0x60] BootServices 175 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x0D); o=_w32(t,o,SOFF_GUID-(o+4)) // lea rcx,[rip+..] &GOP_GUID 176 o=_w8(t,o,0x48); o=_w8(t,o,0x31); o=_w8(t,o,0xD2) // xor rdx,rdx 177 o=_w8(t,o,0x4C); o=_w8(t,o,0x8D); o=_w8(t,o,0x44); o=_w8(t,o,0x24); o=_w8(t,o,0x30) // lea r8,[rsp+0x30] &gop 178 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x80); o=_w32(t,o,0x140) // mov rax,[rax+0x140] LocateProtocol 179 ff_rec(ffsite,ffkind,ffn,o,1); o=_w8(t,o,0xFF); o=_w8(t,o,0xD0) // call rax (1) 180 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x44); o=_w8(t,o,0x24); o=_w8(t,o,0x30) // mov rax,[rsp+0x30] gop 181 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x40); o=_w8(t,o,0x18) // mov rax,[rax+0x18] Mode 182 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x78); o=_w8(t,o,0x18) // mov rdi,[rax+0x18] FrameBufferBase 183 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x48); o=_w8(t,o,0x20) // mov rcx,[rax+0x20] FrameBufferSize 184 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x1D); o=_w32(t,o,SOFF_BOOTINFO-(o+4)) // lea rbx,[rip+..] &bootinfo 185 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x7B); o=_w8(t,o,0x00) // mov [rbx+0],rdi fb_base 186 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x4B); o=_w8(t,o,0x08) // mov [rbx+8],rcx fb_size 187 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x4C); o=_w8(t,o,0x24); o=_w8(t,o,0x40) // mov rcx,[rsp+0x40] systab 188 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x4B); o=_w8(t,o,0x38) // mov [rbx+0x38],rcx SystemTable 189 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x41); o=_w8(t,o,0x30) // mov rax,[rcx+0x30] ConIn 190 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x43); o=_w8(t,o,0x10) // mov [rbx+0x10],rax input cap 191 // N4: the kernel needs the ImageHandle (saved at entry, before LocateProtocol clobbered rcx) 192 // and a zero-filled buffer for the memory map. Both are handed over in boot-info. 193 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x44); o=_w8(t,o,0x24); o=_w8(t,o,0x38) // mov rax,[rsp+0x38] ImageHandle 194 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x43); o=_w8(t,o,0x30) // mov [rbx+0x30],rax 195 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_MMBUF-(o+4)) // lea rax,[rip+..] &mapbuf 196 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x43); o=_w8(t,o,0x40) // mov [rbx+0x40],rax 197 // ---- N1-full: read /KERNEL.NXE from the ESP we booted from -------------------------------- 198 // Chain: LoadedImage -> DeviceHandle -> SimpleFileSystem -> OpenVolume -> Open(READ) -> Read. 199 // Every call's status is CHECKED; any failure takes the same NXE! refusal path as a bad 200 // payload -- a loader that limps past a failed read jumps into zeros. 201 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x44); o=_w8(t,o,0x24); o=_w8(t,o,0x40) // mov rax,[rsp+0x40] systab 202 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x40); o=_w8(t,o,0x60) // mov rax,[rax+0x60] BootServices 203 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x44); o=_w8(t,o,0x24); o=_w8(t,o,0x28) // mov [rsp+0x28],rax save BS 204 // HandleProtocol(ImageHandle, &LI_GUID, &scratch.li) 205 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x4C); o=_w8(t,o,0x24); o=_w8(t,o,0x38) // mov rcx,[rsp+0x38] ImageHandle 206 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x15); o=_w32(t,o,SOFF_LIGUID-(o+4)) // lea rdx,[rip+..] &LI_GUID 207 o=_w8(t,o,0x4C); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_SCRATCH-(o+4)) // lea r8,[rip+..] &scratch.li 208 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x80); o=_w32(t,o,0x98) // mov rax,[rax+0x98] HandleProtocol 209 ff_rec(ffsite,ffkind,ffn,o,1); o=_w8(t,o,0xFF); o=_w8(t,o,0xD0) // call rax (2) 210 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xF8); o=_w8(t,o,0x00) // cmp rax,0 211 let chk1_at: i64 = o 212 o=_w8(t,o,0x0F); o=_w8(t,o,0x85); o=_w32(t,o,0) // jnz rel32 BAD (patched) 213 // dev = li->DeviceHandle 214 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_SCRATCH-(o+4)) // lea rax,[rip+..] &scratch 215 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x08) // mov rcx,[rax] li* 216 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x49); o=_w8(t,o,0x18) // mov rcx,[rcx+0x18] DeviceHandle 217 // HandleProtocol(dev, &FS_GUID, &scratch.fs) 218 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x15); o=_w32(t,o,SOFF_FSGUID-(o+4)) // lea rdx,[rip+..] &FS_GUID 219 o=_w8(t,o,0x4C); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,(SOFF_SCRATCH+8)-(o+4)) // lea r8,[rip+..] &scratch.fs 220 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x44); o=_w8(t,o,0x24); o=_w8(t,o,0x28) // mov rax,[rsp+0x28] BS 221 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x80); o=_w32(t,o,0x98) // mov rax,[rax+0x98] HandleProtocol 222 ff_rec(ffsite,ffkind,ffn,o,1); o=_w8(t,o,0xFF); o=_w8(t,o,0xD0) // call rax (3) 223 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xF8); o=_w8(t,o,0x00) // cmp rax,0 224 let chk2_at: i64 = o 225 o=_w8(t,o,0x0F); o=_w8(t,o,0x85); o=_w32(t,o,0) // jnz rel32 BAD (patched) 226 // OpenVolume(fs, &scratch.root) 227 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_SCRATCH-(o+4)) // lea rax,[rip+..] &scratch 228 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x48); o=_w8(t,o,0x08) // mov rcx,[rax+8] fs* 229 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x15); o=_w32(t,o,(SOFF_SCRATCH+0x10)-(o+4)) // lea rdx,[rip+..] &scratch.root 230 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x41); o=_w8(t,o,0x08) // mov rax,[rcx+8] ->OpenVolume 231 ff_rec(ffsite,ffkind,ffn,o,1); o=_w8(t,o,0xFF); o=_w8(t,o,0xD0) // call rax (4) 232 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xF8); o=_w8(t,o,0x00) // cmp rax,0 233 let chk3_at: i64 = o 234 o=_w8(t,o,0x0F); o=_w8(t,o,0x85); o=_w32(t,o,0) // jnz rel32 BAD (patched) 235 // Open(root, &scratch.file, L"KERNEL.NXE", EFI_FILE_MODE_READ, 0) 236 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_SCRATCH-(o+4)) // lea rax,[rip+..] &scratch 237 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x48); o=_w8(t,o,0x10) // mov rcx,[rax+0x10] root* 238 o=_w8(t,o,0x48); o=_w8(t,o,0x31); o=_w8(t,o,0xC0) // xor rax,rax 239 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x44); o=_w8(t,o,0x24); o=_w8(t,o,0x20) // mov [rsp+0x20],rax Attributes=0 (5th arg) 240 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x15); o=_w32(t,o,(SOFF_SCRATCH+0x18)-(o+4)) // lea rdx,[rip+..] &scratch.file 241 o=_w8(t,o,0x4C); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_FNAME-(o+4)) // lea r8,[rip+..] L"KERNEL.NXE" 242 o=_w8(t,o,0x49); o=_w8(t,o,0xC7); o=_w8(t,o,0xC1); o=_w32(t,o,1) // mov r9,1 EFI_FILE_MODE_READ -- the 243 // ONLY mode this loader will ever 244 // pass; a writable open of the boot 245 // volume is impossible by construction 246 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x41); o=_w8(t,o,0x08) // mov rax,[rcx+8] ->Open 247 ff_rec(ffsite,ffkind,ffn,o,1); o=_w8(t,o,0xFF); o=_w8(t,o,0xD0) // call rax (5) 248 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xF8); o=_w8(t,o,0x00) // cmp rax,0 249 let chk4_at: i64 = o 250 o=_w8(t,o,0x0F); o=_w8(t,o,0x85); o=_w32(t,o,0) // jnz rel32 BAD (patched) 251 // Read(file, &scratch.readsize, &nxe_reserve). readsize is preloaded with NXE_MAX in DATA; 252 // firmware rewrites it to the byte count actually read. A file larger than the reserve gets 253 // TRUNCATED by this very request size, the sum64 check then fails, and the refusal is loud. 254 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_SCRATCH-(o+4)) // lea rax,[rip+..] &scratch 255 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x48); o=_w8(t,o,0x18) // mov rcx,[rax+0x18] file* 256 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x15); o=_w32(t,o,(SOFF_SCRATCH+0x20)-(o+4)) // lea rdx,[rip+..] &readsize 257 o=_w8(t,o,0x4C); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_NXE-(o+4)) // lea r8,[rip+..] &nxe_reserve 258 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x41); o=_w8(t,o,0x20) // mov rax,[rcx+0x20] ->Read 259 ff_rec(ffsite,ffkind,ffn,o,1); o=_w8(t,o,0xFF); o=_w8(t,o,0xD0) // call rax (6) 260 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xF8); o=_w8(t,o,0x00) // cmp rax,0 261 let chk5_at: i64 = o 262 o=_w8(t,o,0x0F); o=_w8(t,o,0x85); o=_w32(t,o,0) // jnz rel32 BAD (patched) 263 // ---- OPTIONAL /NISHI.AI: SEARCH EVERY VOLUME, do not assume our own ----------------------- 264 // FS-2 finding: putting the ESP under GPT made Windows protect it, so the file a user actually 265 // swaps cannot live there. The loader therefore stops assuming "the file is on the volume I 266 // booted from" and asks firmware for EVERY filesystem it knows, trying each in turn. Absence 267 // stays the DEFAULT and is never an error: exhausting the list stores a null pointer and boots 268 // exactly as before. Scratch: +0x38 handle buffer, +0x40 handle count, and rbx+0x60 the index. 269 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x44); o=_w8(t,o,0x24); o=_w8(t,o,0x28) // mov rax,[rsp+0x28] BS 270 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x15); o=_w32(t,o,SOFF_FSGUID-(o+4)) // lea rdx,&FS_GUID 271 o=_w8(t,o,0x49); o=_w8(t,o,0xC7); o=_w8(t,o,0xC0); o=_w32(t,o,0) // mov r8,0 SearchKey NULL. 272 // NOT `xor r8,r8` (4D 31 C0): 273 // that is a REX.WRB form outside 274 // the audited set, and the 275 // emulator REFUSED it. Reusing an 276 // already-allowed shape beats 277 // widening the decode surface for 278 // a register zero. 279 o=_w8(t,o,0x4C); o=_w8(t,o,0x8D); o=_w8(t,o,0x0D); o=_w32(t,o,(SOFF_SCRATCH+0x40)-(o+4)) // lea r9,&count 280 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x0D); o=_w32(t,o,(SOFF_SCRATCH+0x38)-(o+4)) // lea rcx,&buf 281 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x4C); o=_w8(t,o,0x24); o=_w8(t,o,0x20) // mov [rsp+0x20],rcx 282 o=_w8(t,o,0x48); o=_w8(t,o,0xC7); o=_w8(t,o,0xC1); o=_w32(t,o,2) // mov rcx,2 = ByProtocol 283 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x80); o=_w32(t,o,0x138) // mov rax,[rax+0x138] LocateHandleBuffer 284 ff_rec(ffsite,ffkind,ffn,o,1); o=_w8(t,o,0xFF); o=_w8(t,o,0xD0) // call rax 285 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xF8); o=_w8(t,o,0x00) // cmp rax,0 286 let ai_locfail_at: i64 = o 287 o=_w8(t,o,0x0F); o=_w8(t,o,0x85); o=_w32(t,o,0) // jnz AI_ABSENT 288 o=_w8(t,o,0x48); o=_w8(t,o,0x31); o=_w8(t,o,0xC0) // xor rax,rax 289 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x43); o=_w8(t,o,0x60) // mov [rbx+0x60],rax i=0 290 let ai_vol_loop: i64 = o 291 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_SCRATCH-(o+4)) // lea rax,&scratch 292 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x50); o=_w8(t,o,0x40) // mov rdx,[rax+0x40] count 293 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x4B); o=_w8(t,o,0x60) // mov rcx,[rbx+0x60] i 294 o=_w8(t,o,0x48); o=_w8(t,o,0x39); o=_w8(t,o,0xD1) // cmp rcx,rdx 295 let ai_exhausted_at: i64 = o 296 o=_w8(t,o,0x0F); o=_w8(t,o,0x84); o=_w32(t,o,0) // jz AI_ABSENT (exhausted) 297 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x50); o=_w8(t,o,0x38) // mov rdx,[rax+0x38] buf 298 o=_w8(t,o,0x48); o=_w8(t,o,0xC1); o=_w8(t,o,0xE1); o=_w8(t,o,0x03) // shl rcx,3 299 o=_w8(t,o,0x48); o=_w8(t,o,0x01); o=_w8(t,o,0xCA) // add rdx,rcx 300 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x0A) // mov rcx,[rdx] handle 301 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x15); o=_w32(t,o,SOFF_FSGUID-(o+4)) // lea rdx,&FS_GUID 302 o=_w8(t,o,0x4C); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,(SOFF_SCRATCH+8)-(o+4)) // lea r8,&fs 303 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x44); o=_w8(t,o,0x24); o=_w8(t,o,0x28) // mov rax,[rsp+0x28] BS 304 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x80); o=_w32(t,o,0x98) // mov rax,[rax+0x98] HandleProtocol 305 ff_rec(ffsite,ffkind,ffn,o,1); o=_w8(t,o,0xFF); o=_w8(t,o,0xD0) // call rax 306 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xF8); o=_w8(t,o,0x00) // cmp rax,0 307 let ai_next1_at: i64 = o 308 o=_w8(t,o,0x0F); o=_w8(t,o,0x85); o=_w32(t,o,0) // jnz NEXT_VOL 309 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_SCRATCH-(o+4)) // lea rax,&scratch 310 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x48); o=_w8(t,o,0x08) // mov rcx,[rax+8] fs* 311 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x15); o=_w32(t,o,(SOFF_SCRATCH+0x10)-(o+4)) // lea rdx,&root 312 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x41); o=_w8(t,o,0x08) // mov rax,[rcx+8] OpenVolume 313 ff_rec(ffsite,ffkind,ffn,o,1); o=_w8(t,o,0xFF); o=_w8(t,o,0xD0) // call rax 314 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xF8); o=_w8(t,o,0x00) // cmp rax,0 315 let ai_next2_at: i64 = o 316 o=_w8(t,o,0x0F); o=_w8(t,o,0x85); o=_w32(t,o,0) // jnz NEXT_VOL 317 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_SCRATCH-(o+4)) // lea rax,&scratch 318 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x48); o=_w8(t,o,0x10) // mov rcx,[rax+0x10] root* 319 o=_w8(t,o,0x48); o=_w8(t,o,0x31); o=_w8(t,o,0xC0) // xor rax,rax 320 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x44); o=_w8(t,o,0x24); o=_w8(t,o,0x20) // mov [rsp+0x20],rax Attr=0 321 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x15); o=_w32(t,o,(SOFF_SCRATCH+0x28)-(o+4)) // lea rdx,&aifile 322 o=_w8(t,o,0x4C); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_AINAME-(o+4)) // lea r8,&NISHI.AI name 323 o=_w8(t,o,0x49); o=_w8(t,o,0xC7); o=_w8(t,o,0xC1); o=_w32(t,o,1) // mov r9,1 READ ONLY, always 324 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x41); o=_w8(t,o,0x08) // mov rax,[rcx+8] Open 325 ff_rec(ffsite,ffkind,ffn,o,1); o=_w8(t,o,0xFF); o=_w8(t,o,0xD0) // call rax 326 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xF8); o=_w8(t,o,0x00) // cmp rax,0 327 let ai_next3_at: i64 = o 328 o=_w8(t,o,0x0F); o=_w8(t,o,0x85); o=_w32(t,o,0) // jnz NEXT_VOL (not here) 329 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_SCRATCH-(o+4)) // lea rax,&scratch 330 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x48); o=_w8(t,o,0x28) // mov rcx,[rax+0x28] aifile* 331 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x15); o=_w32(t,o,(SOFF_SCRATCH+0x30)-(o+4)) // lea rdx,&readsize 332 o=_w8(t,o,0x4C); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_AI-(o+4)) // lea r8,&ai_reserve 333 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x41); o=_w8(t,o,0x20) // mov rax,[rcx+0x20] Read 334 ff_rec(ffsite,ffkind,ffn,o,1); o=_w8(t,o,0xFF); o=_w8(t,o,0xD0) // call rax 335 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xF8); o=_w8(t,o,0x00) // cmp rax,0 336 let ai_next4_at: i64 = o 337 o=_w8(t,o,0x0F); o=_w8(t,o,0x85); o=_w32(t,o,0) // jnz NEXT_VOL (failed read 338 // is ABSENT, never partial) 339 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x05); o=_w32(t,o,SOFF_AI-(o+4)) // lea rax,&ai_reserve 340 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x43); o=_w8(t,o,0x78) // mov [rbx+0x78],rax 341 let ai_done_at: i64 = o 342 o=_w8(t,o,0xE9); o=_w32(t,o,0) // jmp AI_DONE 343 let ai_next_lbl: i64 = o 344 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x43); o=_w8(t,o,0x60) // NEXT_VOL: mov rax,[rbx+0x60] 345 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xC0); o=_w8(t,o,0x01) // add rax,1 346 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x43); o=_w8(t,o,0x60) // mov [rbx+0x60],rax 347 let ai_loop_back: i64 = o 348 o=_w8(t,o,0xE9); o=_w32(t,o,0) // jmp AI_VOL_LOOP 349 let ai_absent_lbl: i64 = o 350 o=_w8(t,o,0x48); o=_w8(t,o,0x31); o=_w8(t,o,0xC0) // AI_ABSENT: xor rax,rax 351 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x43); o=_w8(t,o,0x78) // mov [rbx+0x78],rax = 0 OFF 352 let ai_done_lbl: i64 = o 353 _w32(t, ai_locfail_at + 2, ai_absent_lbl - (ai_locfail_at + 6)) 354 _w32(t, ai_exhausted_at + 2, ai_absent_lbl - (ai_exhausted_at + 6)) 355 _w32(t, ai_next1_at + 2, ai_next_lbl - (ai_next1_at + 6)) 356 _w32(t, ai_next2_at + 2, ai_next_lbl - (ai_next2_at + 6)) 357 _w32(t, ai_next3_at + 2, ai_next_lbl - (ai_next3_at + 6)) 358 _w32(t, ai_next4_at + 2, ai_next_lbl - (ai_next4_at + 6)) 359 _w32(t, ai_done_at + 1, ai_done_lbl - (ai_done_at + 5)) 360 _w32(t, ai_loop_back + 1, ai_vol_loop - (ai_loop_back + 5)) 361 // ---- validate the NXE we just read (unchanged from the embed era: the format is the gate) -- 362 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x15); o=_w32(t,o,SOFF_NXE-(o+4)) // lea rdx,[rip+..] &NXE 363 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x42); o=_w8(t,o,0x00) // mov rax,[rdx+0] magic|ver qword 364 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x0D); o=_w32(t,o,SOFF_EXPECT-(o+4)) // lea rcx,[rip+..] &expect 365 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x49); o=_w8(t,o,0x00) // mov rcx,[rcx+0] 366 o=_w8(t,o,0x48); o=_w8(t,o,0x39); o=_w8(t,o,0xC8) // cmp rax,rcx 367 let chk6_at: i64 = o 368 o=_w8(t,o,0x0F); o=_w8(t,o,0x85); o=_w32(t,o,0) // jnz rel32 BAD (patched) 369 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x72); o=_w8(t,o,0x18) // mov rsi,[rdx+0x18] text_off 370 o=_w8(t,o,0x48); o=_w8(t,o,0x01); o=_w8(t,o,0xD6) // add rsi,rdx (payload*) 371 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x6A); o=_w8(t,o,0x20) // mov rbp,[rdx+0x20] text_size 372 o=_w8(t,o,0x48); o=_w8(t,o,0xC1); o=_w8(t,o,0xED); o=_w8(t,o,0x03) // shr rbp,3 (qwords; size is 8-padded) 373 o=_w8(t,o,0x48); o=_w8(t,o,0xC7); o=_w8(t,o,0xC1); o=_w32(t,o,0) // mov rcx,0 (sum acc) 374 let sumloop_at: i64 = o 375 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x46); o=_w8(t,o,0x00) // SUMLOOP: mov rax,[rsi+0] 376 o=_w8(t,o,0x48); o=_w8(t,o,0x01); o=_w8(t,o,0xC1) // add rcx,rax 377 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xC6); o=_w8(t,o,0x08) // add rsi,8 378 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xED); o=_w8(t,o,0x01) // sub rbp,1 379 o=_w8(t,o,0x48); o=_w8(t,o,0x83); o=_w8(t,o,0xFD); o=_w8(t,o,0x00) // cmp rbp,0 380 let dsum: i64 = rel8f(sumloop_at, o + 2) 381 o=_w8(t,o,0x75); o=_w8(t,o,dsum) // jnz SUMLOOP (refusing rel8) 382 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x42); o=_w8(t,o,0x38) // mov rax,[rdx+0x38] stored sum 383 o=_w8(t,o,0x48); o=_w8(t,o,0x39); o=_w8(t,o,0xC1) // cmp rcx,rax 384 let chk7_at: i64 = o 385 o=_w8(t,o,0x0F); o=_w8(t,o,0x85); o=_w32(t,o,0) // jnz rel32 BAD (patched) 386 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x42); o=_w8(t,o,0x18) // mov rax,[rdx+0x18] 387 o=_w8(t,o,0x48); o=_w8(t,o,0x01); o=_w8(t,o,0xD0) // add rax,rdx 388 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x6A); o=_w8(t,o,0x10) // mov rbp,[rdx+0x10] entry_off 389 o=_w8(t,o,0x48); o=_w8(t,o,0x01); o=_w8(t,o,0xE8) // add rax,rbp 390 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0x43); o=_w8(t,o,0x70) // stash the NXE entry at +0x70 391 // (NOT +0x28 -- that is &MapKey) 392 // N4 NOTE: ExitBootServices is deliberately NOT done here. Surrendering the firmware is 393 // the KERNEL's decision, not the loader's -- doing it in the shim would kill ConIn before 394 // the kernel ever ran, silently regressing N3's keyboard. The shim's job ends at handing 395 // over ImageHandle, SystemTable, a map buffer and the file it read; the kernel takes the 396 // machine when ready. 397 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x43); o=_w8(t,o,0x70) // mov rax,[rbx+0x70] NXE entry 398 ff_rec(ffsite,ffkind,ffn,o,3); o=_w8(t,o,0xFF); o=_w8(t,o,0xE0) // jmp rax -> KERNEL.NXE 399 let bad_at: i64 = o 400 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x44); o=_w8(t,o,0x24); o=_w8(t,o,0x40) // BAD: mov rax,[rsp+0x40] systab 401 o=_w8(t,o,0x48); o=_w8(t,o,0x8B); o=_w8(t,o,0x40); o=_w8(t,o,0x40) // mov rax,[rax+0x40] ConOut 402 o=_w8(t,o,0x48); o=_w8(t,o,0x8D); o=_w8(t,o,0x15); o=_w32(t,o,SOFF_ERRSTR-(o+4)) // lea rdx,[rip+..] "NXE!" 403 o=_w8(t,o,0x48); o=_w8(t,o,0x89); o=_w8(t,o,0xC1) // mov rcx,rax (This) 404 ff_rec(ffsite,ffkind,ffn,o,2); o=_w8(t,o,0xFF); o=_w8(t,o,0x50); o=_w8(t,o,0x08) // call [rax+8] OutputString (refusal path) 405 o=_w8(t,o,0xEB); o=_w8(t,o,0xFE) // hold (unpainted -> RED, correctly) 406 // Patch every forward branch to BAD now that its address is known. rel32 always: this body 407 // has grown every rung and the rel8 wrap is the most-recurred bug in the lane. 408 _w32(t, chk1_at + 2, bad_at - (chk1_at + 6)) 409 _w32(t, chk2_at + 2, bad_at - (chk2_at + 6)) 410 _w32(t, chk3_at + 2, bad_at - (chk3_at + 6)) 411 _w32(t, chk4_at + 2, bad_at - (chk4_at + 6)) 412 _w32(t, chk5_at + 2, bad_at - (chk5_at + 6)) 413 _w32(t, chk6_at + 2, bad_at - (chk6_at + 6)) 414 _w32(t, chk7_at + 2, bad_at - (chk7_at + 6)) 415 return o 416} 417 418func main(argc: i64, argv: *i64) -> i64 { 419 // KERNEL.NXE is needed at BUILD time only for the expect qword (format identity) and the 420 // reserve ceiling check -- its BYTES no longer ship inside the shim. 421 let lenp: *i64 = sys_mmap(16) as *i64 422 let nxe: *u8 = sys_read_file("_offc/KERNEL.NXE" as *u8, lenp) 423 let nlen: i64 = lenp[0] 424 if nlen <= 0x48 { e_p("NXSHIM REFUSED: _offc/KERNEL.NXE missing/short (run nx_nxe_kernel0 first)\n" as *u8); sys_exit(2); return 2 } 425 if nlen > NXE_MAX { 426 e_p("NXSHIM REFUSED: KERNEL.NXE (" as *u8); e_fn(1, nlen) 427 e_p("B) exceeds the shim reserve NXE_MAX (" as *u8); e_fn(1, NXE_MAX) 428 e_p("B) -- raise NXE_MAX in nx_nxos_shim.nx; a boot-time Read truncated by the reserve would only surface as a sum mismatch\n" as *u8) 429 sys_exit(2); return 2 430 } 431 432 let vsize: i64 = SOFF_AI + AI_MAX 433 let rawsz: i64 = RAW_DATA_END 434 let ftotal: i64 = FOFF_TEXT + rawsz 435 let buf: *u8 = sys_mmap(ftotal + EMIT_BUF_PAGE) 436 437 // ----- PE32+ headers (mirrors the proven nx_gop_efi layout; section is R/W/X for bootinfo) ---- 438 _w16(buf, 0, 0x5A4D) 439 _w32(buf, 0x3C, FOFF_PE_SIG) 440 _w32(buf, FOFF_PE_SIG, 0x00004550) 441 _w16(buf, FOFF_COFF + 0, 0x8664) 442 _w16(buf, FOFF_COFF + 2, 1) 443 _w16(buf, FOFF_COFF + 16, 0xF0) 444 _w16(buf, FOFF_COFF + 18, 0x0002 | 0x0020) 445 _w16(buf, FOFF_OPT + 0, 0x020B) 446 _w8(buf, FOFF_OPT + 2, 1) 447 _w32(buf, FOFF_OPT + 4, rawsz) // SizeOfCode 448 _w32(buf, FOFF_OPT + 16, RVA_TEXT) // entry 449 _w32(buf, FOFF_OPT + 20, RVA_TEXT) 450 _w64(buf, FOFF_OPT + 24, IMG_BASE) 451 _w32(buf, FOFF_OPT + 32, 0x1000) 452 _w32(buf, FOFF_OPT + 36, 0x200) 453 // SizeOfImage MUST cover the VIRTUAL size (mm buffer + kernel reserve), not the raw file -- 454 // a loader allocating only the raw pages would hand the kernel reserve to someone else. 455 _w32(buf, FOFF_OPT + 56, 0x1000 + ((vsize + 0xFFF) / 0x1000) * 0x1000) 456 _w32(buf, FOFF_OPT + 60, 0x200) 457 _w16(buf, FOFF_OPT + 68, 10) // Subsystem EFI_APPLICATION 458 _w64(buf, FOFF_OPT + 72, 0x100000) 459 _w64(buf, FOFF_OPT + 80, 0x1000) 460 _w64(buf, FOFF_OPT + 88, 0x100000) 461 _w64(buf, FOFF_OPT + 96, 0x1000) 462 _w32(buf, FOFF_OPT + 108, 16) 463 _w8(buf, FOFF_SECT_TBL+0, 46); _w8(buf, FOFF_SECT_TBL+1, 116); _w8(buf, FOFF_SECT_TBL+2, 101) 464 _w8(buf, FOFF_SECT_TBL+3, 120); _w8(buf, FOFF_SECT_TBL+4, 116) // ".text" 465 _w32(buf, FOFF_SECT_TBL + 8, vsize) // VirtualSize > raw: loader zero-fills the tail 466 _w32(buf, FOFF_SECT_TBL + 12, RVA_TEXT) 467 _w32(buf, FOFF_SECT_TBL + 16, rawsz) 468 _w32(buf, FOFF_SECT_TBL + 20, FOFF_TEXT) 469 _w32(buf, FOFF_SECT_TBL + 36, 0xE0000020) // CODE|EXEC|READ|WRITE (bootinfo lives in-image) 470 471 // ----- .text: code + data constants (NO embedded kernel any more) -------------------------- 472 var g: i64 = 0 473 var i: i64 = 0 474 let tcode: *u8 = sys_mmap(EMIT_BUF_PAGE) 475 let ffsite: *i64 = sys_mmap(8 * 64) as *i64 476 let ffkind: *i64 = sys_mmap(8 * 64) as *i64 477 let ffn: *i64 = sys_mmap(16) as *i64 478 ffn[0] = 0 479 let tlen: i64 = emit_code(tcode, ffsite, ffkind, ffn) 480 while i < tlen { buf[FOFF_TEXT + i] = tcode[i]; i = i + 1 } 481 // data 482 _w64(buf, FOFF_TEXT + SOFF_EXPECT, _r64(nxe, 0)) // expected magic|ver qword 483 _w16(buf, FOFF_TEXT + SOFF_ERRSTR + 0, 0x4E); _w16(buf, FOFF_TEXT + SOFF_ERRSTR + 2, 0x58) 484 _w16(buf, FOFF_TEXT + SOFF_ERRSTR + 4, 0x45); _w16(buf, FOFF_TEXT + SOFF_ERRSTR + 6, 0x21) 485 _w16(buf, FOFF_TEXT + SOFF_ERRSTR + 8, 0x00) // "NXE!" 486 i = 0 487 while i < 16 { _w8(buf, FOFF_TEXT + SOFF_GUID + i, gop_guid_byte(i)); i = i + 1 } 488 i = 0 489 while i < 16 { _w8(buf, FOFF_TEXT + SOFF_LIGUID + i, li_guid_byte(i)); i = i + 1 } 490 i = 0 491 while i < 16 { _w8(buf, FOFF_TEXT + SOFF_FSGUID + i, fs_guid_byte(i)); i = i + 1 } 492 i = 0 493 while i < 10 { _w16(buf, FOFF_TEXT + SOFF_FNAME + i * 2, fname_ch(i)); i = i + 1 } 494 _w16(buf, FOFF_TEXT + SOFF_FNAME + 20, 0) // UTF-16 NUL 495 i = 0 496 while i < 8 { _w16(buf, FOFF_TEXT + SOFF_AINAME + i * 2, ainame_ch(i)); i = i + 1 } 497 _w16(buf, FOFF_TEXT + SOFF_AINAME + 16, 0) // UTF-16 NUL 498 _w64(buf, FOFF_TEXT + SOFF_SCRATCH + 0x20, NXE_MAX) // Read request size 499 _w64(buf, FOFF_TEXT + SOFF_SCRATCH + 0x30, AI_MAX) // AI Read request size 500 501 // ===== self-gate (every run) ================================================================= 502 // G1 PE structural + the two size fields a file-read shim cannot afford to get wrong 503 var t1: i64 = 0 504 if buf[0] == (0x4D as u8) { if _r32(buf, FOFF_PE_SIG) == 0x00004550 { if _r16(buf, FOFF_OPT+68) == 10 { 505 if _r32(buf, FOFF_SECT_TBL + 8) == vsize { 506 if _r32(buf, FOFF_OPT + 56) == (0x1000 + ((vsize + 0xFFF) / 0x1000) * 0x1000) { t1 = 1 } 507 } 508 } } } 509 // G2 the filename the firmware will be asked for, byte-exact UTF-16LE + the Read size preload 510 var t2: i64 = 0 511 if chk_fname(buf) == 1 { if _r64(buf, FOFF_TEXT + SOFF_SCRATCH + 0x20) == NXE_MAX { 512 if _r64(buf, FOFF_TEXT + SOFF_SCRATCH + 0x30) == AI_MAX { t2 = 1 } 513 } } 514 // G3 code provably ends before the data base -- an inserted instruction that pushes code into 515 // the scratch region is caught HERE, not as a boot mystery. 516 var t3: i64 = 0 517 if tlen <= SOFF_SCRATCH { t3 = 1 } 518 // G4 NEVER-BRICK CALL CENSUS, at the audited set for N1-full + the optional assistant file: 519 // EXACTLY eight `call rax` (LocateProtocol · HandleProtocol x2 · OpenVolume · Open(KERNEL,READ) 520 // · Read(kernel) · Open(NISHI.AI,READ) · Read(ai)), EXACTLY one `call [rax+8]` 521 // (ConOut->OutputString, refusal path only), EXACTLY one `jmp rax` (the NXE handoff). The count 522 // moved from 6 to 8 DELIBERATELY and is stated here with each call named -- growing a 523 // never-brick allow-set silently is the failure mode this tooth exists to prevent. 524 // The census walks the RECORDED sites. Each recorded site is also re-read from the emitted 525 // bytes and must still BE the instruction the emitter said it was -- so a recording that drifts 526 // from the emission is caught, not trusted. 527 var callrax: i64 = 0 528 var call50: i64 = 0 529 var jmprax: i64 = 0 530 var badff: i64 = 0 531 var bad_at_off: i64 = 0 - 1 532 var bad_next: i64 = 0 533 i = 0 534 while i < ffn[0] { 535 let at: i64 = ffsite[i] 536 let k: i64 = ffkind[i] 537 let b0: i64 = buf[FOFF_TEXT + at] as i64 538 let b1: i64 = buf[FOFF_TEXT + at + 1] as i64 539 var ok: i64 = 0 540 if b0 == 0xFF { 541 if k == 1 { if b1 == 0xD0 { callrax = callrax + 1; ok = 1 } } 542 if k == 2 { if b1 == 0x50 { if (buf[FOFF_TEXT + at + 2] as i64) == 8 { call50 = call50 + 1; ok = 1 } } } 543 if k == 3 { if b1 == 0xE0 { jmprax = jmprax + 1; ok = 1 } } 544 } 545 if ok == 0 { badff = badff + 1; if bad_at_off < 0 { bad_at_off = at; bad_next = b1 } } 546 i = i + 1 547 } 548 if ffn[0] != 13 { badff = badff + 1 } // the audited set is exactly ten control transfers 549 var t4: i64 = 0 550 if callrax == 11 { if call50 == 1 { if jmprax == 1 { if badff == 0 { t4 = 1 } } } } 551 // G5 all three GUIDs placed (GOP + LoadedImage + SimpleFS) 552 var t5: i64 = 0 553 if chk_guids(buf) == 1 { t5 = 1 } 554 // G6 tamper bite: the comparators must actually DISCRIMINATE. Flip one GUID byte and one 555 // filename byte; each comparator must go RED, then GREEN again after restore. A gate that 556 // cannot fail is not a gate. 557 var t6: i64 = 0 558 let wasg: i64 = buf[FOFF_TEXT + SOFF_LIGUID + 7] as i64 559 buf[FOFF_TEXT + SOFF_LIGUID + 7] = ((wasg + 1) & 0xff) as u8 560 let bite_g: i64 = chk_guids(buf) 561 buf[FOFF_TEXT + SOFF_LIGUID + 7] = wasg as u8 562 let wasf: i64 = buf[FOFF_TEXT + SOFF_FNAME + 4] as i64 563 buf[FOFF_TEXT + SOFF_FNAME + 4] = ((wasf + 1) & 0xff) as u8 564 let bite_f: i64 = chk_fname(buf) 565 buf[FOFF_TEXT + SOFF_FNAME + 4] = wasf as u8 566 if bite_g == 0 { if bite_f == 0 { if chk_guids(buf) == 1 { if chk_fname(buf) == 1 { t6 = 1 } } } } 567 g = t1 + t2 + t3 + t4 + t5 + t6 568 569 e_p("NXOS-SHIM teeth: pe=" as *u8); e_fn(1, t1); e_p(" fname=" as *u8); e_fn(1, t2) 570 e_p(" code_fits=" as *u8); e_fn(1, t3); e_p("(tlen=" as *u8); e_fn(1, tlen); e_p(")" as *u8) 571 e_p(" callcensus=" as *u8); e_fn(1, t4); e_p("(callrax=" as *u8); e_fn(1, callrax) 572 e_p(" call50=" as *u8); e_fn(1, call50); e_p(" jmprax=" as *u8); e_fn(1, jmprax) 573 e_p(" ffsites=" as *u8); e_fn(1, ffn[0]) 574 e_p(" bad=" as *u8); e_fn(1, badff); e_p("@" as *u8); e_fn(1, bad_at_off); e_p("nb=" as *u8); e_fn(1, bad_next) 575 // NAME THE OFFENDING BYTE IN CONTEXT. A bare offset costs a whole build cycle to localize, and 576 // an FF inside an IMMEDIATE looks identical to an FF that starts an instruction until you see 577 // its neighbours -- the exact trap that made the kernel's byte-frequency tooth a false RED. 578 if bad_at_off >= 0 { 579 e_p(" ctx=" as *u8) 580 var cx: i64 = bad_at_off - 4 581 if cx < 0 { cx = 0 } 582 while cx <= (bad_at_off + 3) { 583 if cx == bad_at_off { e_p("[" as *u8) } 584 e_fn(1, buf[FOFF_TEXT + cx] as i64) 585 if cx == bad_at_off { e_p("]" as *u8) } 586 e_p("." as *u8) 587 cx = cx + 1 588 } 589 } 590 e_p(")" as *u8) 591 e_p(" guids=" as *u8); e_fn(1, t5); e_p(" tamper=" as *u8); e_fn(1, t6); e_p("\n" as *u8) 592 e_p("NXOS-SHIM: code=" as *u8); e_fn(1, tlen); e_p("B reserve=" as *u8); e_fn(1, NXE_MAX) 593 e_p("B ai_reserve=" as *u8); e_fn(1, AI_MAX); e_p("B kernel_now=" as *u8); e_fn(1, nlen) 594 e_p("B file=" as *u8); e_fn(1, ftotal); e_p("B teeth=" as *u8); e_fn(1, g); e_p("of6\n" as *u8) 595 596 if g == 6 { 597 let fd: i64 = sys_openat_wr("_offc/nx_nxos_shim.efi" as *u8, 0x1a4) 598 if fd < 0 { e_p("NXSHIM RED: cannot write _offc/nx_nxos_shim.efi\n" as *u8); sys_exit(2); return 2 } 599 sys_write(fd, buf, ftotal) 600 sys_close(fd) 601 } 602 let lf: i64 = sys_openat_append("knowledge/status/nishi_os.log" as *u8, 0x1a4) 603 if lf >= 0 { 604 e_fp(lf, "NXSHIM name=nx_nxos_shim.efi subsystem=10 reads=/KERNEL.NXE reserve=" as *u8); e_fn(lf, NXE_MAX) 605 e_fp(lf, " kernel_now=" as *u8); e_fn(lf, nlen) 606 e_fp(lf, " teeth=" as *u8); e_fn(lf, g); e_fp(lf, "of6 verdict=" as *u8) 607 if g == 6 { e_fp(lf, "GREEN\n" as *u8) } else { e_fp(lf, "RED\n" as *u8) } 608 sys_close(lf) 609 } 610 if g == 6 { 611 e_p("NXOS-SHIM GREEN: PE toll paid at the firmware boundary only; the kernel is a FILE the shim reads and validates\n" as *u8) 612 sys_exit(0); return 0 613 } 614 e_p("NXOS-SHIM RED\n" as *u8) 615 sys_exit(1); return 1 616}