code wiki / _hdl_build / nx_boot_uefi_ramsize.nx

nx_boot_uefi_ramsize.nx source

↩ module page · 200 lines · 13519 B

1// nx_boot_uefi_ramsize.nx -- NOS-R0.3: DISPLAY a discovered hardware value (the RAM map size). 2// 3// Extends R0.2 (the GetMemoryMap call): after calling BootServices->GetMemoryMap, the emitted 4// EFI app now READS the returned MapSize and PRINTS it as hex -- the first rung that shows a real 5// hardware value the OS discovered from the machine. This unlocks an installer UI ("this box has 6// N bytes of RAM, install here"). The hex render is a real LOOP in machine code (8 nibbles MSB 7// first, shr-by-CL + cmp + jcc), which is exactly why the exec-harness grew loop support. 8// 9// Entry ABI (MS x64): RCX=ImageHandle, RDX=SystemTable*. RSI=SystemTable, RDI=ConOut, RBX=hex 10// write pointer (all callee-saved across the firmware call). Prints "RAM:0x" + 8 hex digits + CRLF. 11// GetMemoryMap writes the required map size into *MapSize; we load it and format it. 12// Scratch + hex buffer live in an RWX section (firmware writes MapSize; we write the hex chars). 13// 14// Build (sovereign): ./_offc/nx_sov_build_run.elf nx_boot_uefi_ramsize (nx_cc->nxasm, no gcc) 15// Exec-proof: nx_emu_uefi runs it (GetMemoryMap hook returns 0x1800) -> expect "RAM:0x00001800". 16// Self-gate: byte-reproducible + structural (subsystem=10, entry, GetMemoryMap call opcodes, the 17// shr-by-CL hex-loop opcode present) + tamper (subsystem->3 rejects). 18// Sovereign: syscalls only, no gcc/.sh. license_tier: ORIGINAL 19import "nx_syscalls.nx" 20const PE_MAGIC_4096: i64 = 4096 21 22const PE_FILE_SIZE: i64 = 0x400 23const PE_MACHINE_AMD64: i64 = 0x8664 24const PE_OH_MAGIC_PEPLUS: i64 = 0x020B 25const PE_SUBSYSTEM_EFI_APP: i64 = 10 26const PE_CHAR_EXEC: i64 = 0x0002 27const PE_CHAR_LARGE_ADDR: i64 = 0x0020 28const PE_SECT_CODE_RWX: i64 = 0xE0000020 29 30const FOFF_PE_SIG: i64 = 0x80 31const FOFF_COFF: i64 = 0x84 32const FOFF_OPT: i64 = 0x98 33const FOFF_SECT_TBL: i64 = 0x188 34const FOFF_TEXT: i64 = 0x200 35const RVA_TEXT: i64 = 0x1000 36const OPT_SUBSYS: i64 = 0x98 + 68 37const OPT_ENTRY: i64 = 0x98 + 16 38const IMG_BASE: i64 = 0x10000000 39const TEXT_VSIZE: i64 = 0x100 40 41func _w8(buf: *u8, off: i64, v: i64) -> i64 { buf[off] = (v & 0xff) as u8; return off + 1 } 42func _w16(buf: *u8, off: i64, v: i64) -> i64 { _w8(buf, off, v); _w8(buf, off + 1, v >> 8); return off + 2 } 43func _w32(buf: *u8, off: i64, v: i64) -> i64 { 44 _w8(buf, off, v); _w8(buf, off + 1, v >> 8); _w8(buf, off + 2, v >> 16); _w8(buf, off + 3, v >> 24) 45 return off + 4 46} 47func _w64(buf: *u8, off: i64, v: i64) -> i64 { _w32(buf, off, v); _w32(buf, off + 4, v >> 32); return off + 8 } 48func _r16(buf: *u8, off: i64) -> i64 { return (buf[off] as i64) | ((buf[off + 1] as i64) << 8) } 49func _r32(buf: *u8, off: i64) -> i64 { 50 return (buf[off] as i64) | ((buf[off + 1] as i64) << 8) | ((buf[off + 2] as i64) << 16) | ((buf[off + 3] as i64) << 24) 51} 52 53func uefi_emit(buf: *u8) -> i64 { 54 _w16(buf, 0, 0x5A4D); _w32(buf, 0x3C, FOFF_PE_SIG); _w32(buf, FOFF_PE_SIG, 0x00004550) 55 _w16(buf, FOFF_COFF + 0, PE_MACHINE_AMD64); _w16(buf, FOFF_COFF + 2, 1) 56 _w16(buf, FOFF_COFF + 16, 0xF0); _w16(buf, FOFF_COFF + 18, PE_CHAR_EXEC | PE_CHAR_LARGE_ADDR) 57 _w16(buf, FOFF_OPT + 0, PE_OH_MAGIC_PEPLUS); _w8(buf, FOFF_OPT + 2, 1) 58 _w32(buf, FOFF_OPT + 4, 0x200); _w32(buf, FOFF_OPT + 16, RVA_TEXT); _w32(buf, FOFF_OPT + 20, RVA_TEXT) 59 _w64(buf, FOFF_OPT + 24, IMG_BASE); _w32(buf, FOFF_OPT + 32, 0x1000); _w32(buf, FOFF_OPT + 36, 0x200) 60 _w32(buf, FOFF_OPT + 56, 0x2000); _w32(buf, FOFF_OPT + 60, 0x200) 61 _w16(buf, FOFF_OPT + 68, PE_SUBSYSTEM_EFI_APP) 62 _w64(buf, FOFF_OPT + 72, 0x100000); _w64(buf, FOFF_OPT + 80, 0x1000) 63 _w64(buf, FOFF_OPT + 88, 0x100000); _w64(buf, FOFF_OPT + 96, 0x1000); _w32(buf, FOFF_OPT + 108, 16) 64 _w8(buf, FOFF_SECT_TBL + 0, 46); _w8(buf, FOFF_SECT_TBL + 1, 116); _w8(buf, FOFF_SECT_TBL + 2, 101) 65 _w8(buf, FOFF_SECT_TBL + 3, 120); _w8(buf, FOFF_SECT_TBL + 4, 116) 66 _w32(buf, FOFF_SECT_TBL + 8, TEXT_VSIZE); _w32(buf, FOFF_SECT_TBL + 12, RVA_TEXT) 67 _w32(buf, FOFF_SECT_TBL + 16, 0x200); _w32(buf, FOFF_SECT_TBL + 20, FOFF_TEXT) 68 _w32(buf, FOFF_SECT_TBL + 36, PE_SECT_CODE_RWX) 69 70 // ----- .text: GetMemoryMap, then hex-print *MapSize ----- 71 // data: strLabel@0xAC "RAM:0x", strNL@0xBA "\r\n", HexBuf@0xC0(32), MapSize@0xE0 MapKey@0xE8 DescSize@0xF0 DescVer@0xF8 72 var o: i64 = FOFF_TEXT 73 o = _w8(buf, o, 0x56); o = _w8(buf, o, 0x57); o = _w8(buf, o, 0x53) // push rsi; push rdi; push rbx 74 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x89); o = _w8(buf, o, 0xD6) // mov rsi,rdx 75 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8B); o = _w8(buf, o, 0x7E); o = _w8(buf, o, 0x40)// mov rdi,[rsi+0x40] 76 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x83); o = _w8(buf, o, 0xEC); o = _w8(buf, o, 0x40)// sub rsp,0x40 77 // GetMemoryMap(rcx=&MapSize, rdx=0, r8=&MapKey, r9=&DescSize, [rsp+0x20]=&DescVer) 78 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8D); o = _w8(buf, o, 0x05); o = _w32(buf, o, 0xE3)// lea rax,[rip+DescVer] 79 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x89); o = _w8(buf, o, 0x44); o = _w8(buf, o, 0x24); o = _w8(buf, o, 0x20)// mov [rsp+0x20],rax 80 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8D); o = _w8(buf, o, 0x0D); o = _w32(buf, o, 0xBF)// lea rcx,[rip+MapSize] 81 o = _w8(buf, o, 0x31); o = _w8(buf, o, 0xD2) // xor edx,edx 82 o = _w8(buf, o, 0x4C); o = _w8(buf, o, 0x8D); o = _w8(buf, o, 0x05); o = _w32(buf, o, 0xBE)// lea r8,[rip+MapKey] 83 o = _w8(buf, o, 0x4C); o = _w8(buf, o, 0x8D); o = _w8(buf, o, 0x0D); o = _w32(buf, o, 0xBF)// lea r9,[rip+DescSize] 84 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8B); o = _w8(buf, o, 0x46); o = _w8(buf, o, 0x60)// mov rax,[rsi+0x60] 85 o = _w8(buf, o, 0xFF); o = _w8(buf, o, 0x50); o = _w8(buf, o, 0x38) // call [rax+0x38] 86 // print "RAM:0x" 87 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x89); o = _w8(buf, o, 0xF9) // mov rcx,rdi 88 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8D); o = _w8(buf, o, 0x15); o = _w32(buf, o, 0x6A)// lea rdx,[rip+strLabel] 89 o = _w8(buf, o, 0xFF); o = _w8(buf, o, 0x57); o = _w8(buf, o, 0x08) // call [rdi+8] 90 // rax = *MapSize 91 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8D); o = _w8(buf, o, 0x05); o = _w32(buf, o, 0x94)// lea rax,[rip+MapSize] 92 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8B); o = _w8(buf, o, 0x40); o = _w8(buf, o, 0x00)// mov rax,[rax+0] 93 // hex setup: rbx=&HexBuf, rcx=28 (shift) 94 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8D); o = _w8(buf, o, 0x1D); o = _w32(buf, o, 0x69)// lea rbx,[rip+HexBuf] 95 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0xC7); o = _w8(buf, o, 0xC1); o = _w32(buf, o, 0x1C)// mov rcx,28 96 // loop (RVA 0x105E): emit one hex digit per iteration, shift -= 4 until < 0 97 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x89); o = _w8(buf, o, 0xC2) // mov rdx,rax 98 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0xD3); o = _w8(buf, o, 0xEA) // shr rdx,cl 99 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x83); o = _w8(buf, o, 0xE2); o = _w8(buf, o, 0x0F)// and rdx,0xF 100 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x83); o = _w8(buf, o, 0xC2); o = _w8(buf, o, 0x30)// add rdx,0x30 101 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x83); o = _w8(buf, o, 0xFA); o = _w8(buf, o, 0x39)// cmp rdx,0x39 102 o = _w8(buf, o, 0x7E); o = _w8(buf, o, 0x04) // jle +4 (skip the A-F adjust) 103 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x83); o = _w8(buf, o, 0xC2); o = _w8(buf, o, 0x07)// add rdx,7 104 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x89); o = _w8(buf, o, 0x53); o = _w8(buf, o, 0x00)// mov [rbx+0],rdx 105 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x83); o = _w8(buf, o, 0xC3); o = _w8(buf, o, 0x02)// add rbx,2 106 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x83); o = _w8(buf, o, 0xE9); o = _w8(buf, o, 0x04)// sub rcx,4 107 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x83); o = _w8(buf, o, 0xF9); o = _w8(buf, o, 0x00)// cmp rcx,0 108 o = _w8(buf, o, 0x7D); o = _w8(buf, o, 0xD6) // jge loop (rel -42) 109 // print HexBuf 110 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x89); o = _w8(buf, o, 0xF9) // mov rcx,rdi 111 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8D); o = _w8(buf, o, 0x15); o = _w32(buf, o, 0x2E)// lea rdx,[rip+HexBuf] 112 o = _w8(buf, o, 0xFF); o = _w8(buf, o, 0x57); o = _w8(buf, o, 0x08) // call [rdi+8] 113 // print "\r\n" 114 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x89); o = _w8(buf, o, 0xF9) // mov rcx,rdi 115 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x8D); o = _w8(buf, o, 0x15); o = _w32(buf, o, 0x1B)// lea rdx,[rip+strNL] 116 o = _w8(buf, o, 0xFF); o = _w8(buf, o, 0x57); o = _w8(buf, o, 0x08) // call [rdi+8] 117 // epilogue 118 o = _w8(buf, o, 0x48); o = _w8(buf, o, 0x83); o = _w8(buf, o, 0xC4); o = _w8(buf, o, 0x40)// add rsp,0x40 119 o = _w8(buf, o, 0x5B); o = _w8(buf, o, 0x5F); o = _w8(buf, o, 0x5E) // pop rbx; pop rdi; pop rsi 120 o = _w8(buf, o, 0x31); o = _w8(buf, o, 0xC0); o = _w8(buf, o, 0xC3) // xor eax,eax; ret (ends 0xAC) 121 // strLabel @0xAC "RAM:0x\0" 122 o = _w16(buf, o, 0x52); o = _w16(buf, o, 0x41); o = _w16(buf, o, 0x4D); o = _w16(buf, o, 0x3A); o = _w16(buf, o, 0x30); o = _w16(buf, o, 0x78); o = _w16(buf, o, 0x00) 123 // strNL @0xBA "\r\n\0" 124 o = _w16(buf, o, 0x0D); o = _w16(buf, o, 0x0A); o = _w16(buf, o, 0x00) 125 // HexBuf @0xC0 (32B) + scratch @0xE0.. left zero 126 return PE_FILE_SIZE 127} 128 129func uefi_verify(buf: *u8) -> i64 { 130 if buf[0] != (0x4D as u8) { return 0 } 131 if buf[1] != (0x5A as u8) { return 0 } 132 if _r32(buf, 0x3C) != FOFF_PE_SIG { return 0 } 133 if _r32(buf, FOFF_PE_SIG) != 0x00004550 { return 0 } 134 if _r16(buf, FOFF_COFF) != PE_MACHINE_AMD64 { return 0 } 135 if _r16(buf, FOFF_OPT) != PE_OH_MAGIC_PEPLUS { return 0 } 136 if _r16(buf, OPT_SUBSYS) != PE_SUBSYSTEM_EFI_APP { return 0 } 137 if _r32(buf, OPT_ENTRY) != RVA_TEXT { return 0 } 138 if buf[FOFF_TEXT] != (0x56 as u8) { return 0 } // entry[0] = push rsi 139 if buf[FOFF_TEXT + 0x31] != (0x48 as u8) { return 0 } // mov rax,[rsi+0x60] (BootServices) 140 if buf[FOFF_TEXT + 0x33] != (0x46 as u8) { return 0 } 141 if buf[FOFF_TEXT + 0x35] != (0xFF as u8) { return 0 } // call [rax+0x38] (GetMemoryMap) 142 if buf[FOFF_TEXT + 0x37] != (0x38 as u8) { return 0 } 143 if buf[FOFF_TEXT + 0x61] != (0x48 as u8) { return 0 } // shr rdx,cl (the hex loop's variable shift) 144 if buf[FOFF_TEXT + 0x62] != (0xD3 as u8) { return 0 } 145 if buf[FOFF_TEXT + 0x63] != (0xEA as u8) { return 0 } 146 return 1 147} 148 149func 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 } 150func 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 } 151func u_fn(fd: i64, v: i64) -> i64 { 152 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m } 153 let t: *u8 = sys_mmap(28); var k: i64 = 0 154 if m == 0 { t[0] = 48; k = 1 } 155 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 156 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 157 sys_write(fd, bb, k); return 0 158} 159func u_log(sz: i64, repro: i64, structural: i64, tamper: i64, verdict: *u8) -> i64 { 160 let lfd: i64 = sys_openat_append("knowledge/status/nishi_os.log" as *u8, 0x1a4) 161 if lfd < 0 { return 0 - 1 } 162 u_fp(lfd, "NOSR0_3 name=nx_boot_uefi_ramsize.efi subsystem=10 climate=x86_64-uefi displays=ram-map-size-hex bytes=" as *u8); u_fn(lfd, sz) 163 u_fp(lfd, " repro=" as *u8); u_fn(lfd, repro) 164 u_fp(lfd, " structural=" as *u8); u_fn(lfd, structural) 165 u_fp(lfd, " tamper_caught=" as *u8); u_fn(lfd, tamper) 166 u_fp(lfd, " scope=emit-proven verdict=" as *u8); u_fp(lfd, verdict); u_fp(lfd, "\n" as *u8) 167 sys_close(lfd); return 0 168} 169 170func main(argc: i64, argv: *i64) -> i64 { 171 let buf: *u8 = sys_mmap(PE_MAGIC_4096) 172 let buf2: *u8 = sys_mmap(PE_MAGIC_4096) 173 let sz: i64 = uefi_emit(buf) 174 let sz2: i64 = uefi_emit(buf2) 175 var repro: i64 = 1 176 if sz != sz2 { repro = 0 } 177 var i: i64 = 0 178 while i < sz { if buf[i] != buf2[i] { repro = 0 } i = i + 1 } 179 let structural: i64 = uefi_verify(buf) 180 _w16(buf2, OPT_SUBSYS, 3) 181 var tamper_caught: i64 = 0 182 if uefi_verify(buf2) == 0 { tamper_caught = 1 } 183 var green: i64 = 0 184 if repro == 1 { if structural == 1 { if tamper_caught == 1 { green = 1 } } } 185 if green == 1 { 186 let ofd: i64 = sys_openat_wr("_offc/nx_boot_uefi_ramsize.efi" as *u8, 0x1a4) 187 if ofd < 0 { 188 u_p("NOS-R0.3 RED: cannot write _offc/nx_boot_uefi_ramsize.efi\n" as *u8) 189 u_log(sz, repro, structural, tamper_caught, "RED" as *u8); sys_exit(1); return 1 190 } 191 sys_write(ofd, buf, sz); sys_close(ofd) 192 u_p("NOS-R0.3 GREEN: authored _offc/nx_boot_uefi_ramsize.efi (reads+hex-prints RAM map size) bytes=" as *u8) 193 u_fn(1, sz); u_p(" repro+structural(+hex-loop opcode)+tamper all pass\n" as *u8) 194 u_log(sz, repro, structural, tamper_caught, "GREEN" as *u8); sys_exit(0); return 0 195 } 196 u_p("NOS-R0.3 RED: repro=" as *u8); u_fn(1, repro) 197 u_p(" structural=" as *u8); u_fn(1, structural) 198 u_p(" tamper_caught=" as *u8); u_fn(1, tamper_caught); u_p("\n" as *u8) 199 u_log(sz, repro, structural, tamper_caught, "RED" as *u8); sys_exit(1); return 1 200}