Impossible OS Docs

Win32 PE Loader

What is it?

The PE loader is what lets Impossible OS run Windows programs natively: it reads a 64-bit PE32+ executable, maps its sections into a new process, binds its imports and starts it in user mode. The kernel half already works for simple images: validation, fixed-base section mapping and import binding ship today. What is missing is the user-mode half that makes a compiled Windows program actually run: relocations, imports that can be called, and a Windows C runtime. This roadmap's nine sections are all still open; the kernel pieces shipped under the Binary Format System roadmap instead.

How does it work?

Today. A file reaches the loader through the ordinary exec path: SYS_EXEC runs task_exec(), which reads the file and hands it to exec_load_fmt(). That picks the loader by the file's magic bytes: 7F ELF for ELF, EIF! for EIF and MZ for PE (exec.c). There is no "PE first, ELF second" probing; each format is recognised by its own header.

flowchart LR
    A[SYS_EXEC] --> B[task_exec]
    B --> C[exec_load_fmt: match magic]
    C -->|MZ| D[pe_validate]
    D --> E[pe_load: map sections at ImageBase]
    E --> F[bind imports to SSDT slots]
    F --> G[register module and .pdata]
    G --> H[ring-3 entry, RCX = PEB]
  • Validation. pe_validate() accepts only AMD64 (0x8664) images with a PE32+ optional header (0x20B); 32-bit images are rejected (pe.c, structures in pe.h).
  • Mapping. pe_load() maps the headers and each section page by page at the image's own ImageBase, zero-fills uninitialised data and marks non-code sections no-execute. Cleanup on failure is incomplete: pe_rollback() unmaps a contiguous run of pages from ImageBase, so a section mapped past a gap in the RVAs can survive it, and a page whose mapping fails leaks its frame. Limits: ImageBase at least 16 MiB, up to 96 sections and a 256 MiB mapped image. The file itself is capped lower: SYS_EXEC stages it in kernel heap and refuses anything over 512 KiB (EXEC_KMALLOC_STAGE_MAX); the 16 MiB EXEC_MAX_IMAGE_SIZE bounds only what the format dispatcher accepts (exec.h).
  • Imports. The import directory is walked for up to 64 DLLs and 4,096 names each. A by-name import found in a built-in table is written into the IAT as that function's SSDT service number, not as an address; anything else, including every import by ordinal, is written as 0.
  • Exception data. The .pdata table is recorded with the module so kernel exception dispatch can unwind through it, and the module is added to the PEB loader lists.
  • Launch. The new thread enters ring 3 with RCX pointing at the PEB.

System calls. The SYSCALL fast path is already set up: STAR, LSTAR and FMASK are programmed in syscall_fast.c with the entry stub in syscall_entry.asm, and the GDT already puts user data (0x18) just below user code (0x20), the order SYSRET needs (gdt.h). INT 0x80 and INT 0x2E still work too.

What are its interfaces?

Interface Status
pe_validate(), pe_load(), PE32+ structures in pe.h Shipped
Built-in import tables for kernel32.dll (14 names) and ntdll.dll (96 Nt* names) Shipped; see Win32 API Surface
SYSCALL/SYSRET entry, STAR/LSTAR/FMASK Shipped
Base relocations, ASLR Planned
TLS directory, delay-load and bound imports, ordinal imports Not handled
crt0_pe.asm, kernel32_stub.c, libcrt.a Planned

How do I use it?

The loader is exercised by the kernel suite (make test-exec, which checks PE structure sizes, validation of good and bad images, section mapping, module registration and the ImageBase floor in test_exec.c) and by a hand-assembled PE that exits with status 0 (test_loader_pe.c). A normal compiled Windows program cannot run yet: its calls through the IAT would jump to a service number or to 0.

What is not implemented yet?

How does it compare with Windows 11 and Linux?

Windows 11 loads images in user mode with ntdll's Ldr* routines, rebases them for ASLR, resolves imports against real DLLs and enters the kernel through KiSystemCall64. Linux runs PE programs only through Wine, which loads them in user space on top of the ELF system. Impossible OS loads PE32+ in the kernel as a first-class format beside ELF and EIF; today it maps and binds images but cannot yet run a compiled Windows program.

See also

Impossible OS is free software under the GPL-3.0-only license. Last updated Edit this page on GitHub