152 ·GitHub
What is this?
GoodmansKernel is a signed Windows kernel-mode driver that embeds the wasm3 interpreter, letting you load unsigned .wasm modules and run them inside the kernel with direct FFI access to nt/hal exports. You write kernel logic in C or Rust, compile it to wasm32, load it into the driver, and iterate without re-signing each payload.
Is this a full application or just a driver?
It's a kernel-mode WDM driver (.sys) with a Qt6 GUI front-end for loading modules and watching logs; the wasm guest modules are compiled separately and loaded into the driver via IOCTLs.
How do I build and install it?
Build the driver in Visual Studio 2022 with WDK 10.0.26100.0, Qt 6.9, and clang targeting wasm32 for guest modules. To run it if it's not properly signed, enable test signing with 'bcdedit /set testsigning on' before loading the driver.
What tools do I need before I can build this?
VS 2022, WDK 10.0.26100.0, Qt 6.9 for the GUI, and clang with wasm32 target support to compile guest modules.
What are the main limits of running wasm payloads in the kernel this way?
Guest modules can't use f32/f64 types, wasm memory bounds checks are compiled out so a buggy module can still corrupt memory, only one caller per module is allowed at a time, IOCTL payloads are capped at 16MB, and there's a hard limit of 32 module slots.
Is this safe to use license-wise?
The driver itself is MIT licensed, same as the bundled wasm3 and InfinityHook, but it links Qt 6 which is LGPLv3, so redistributing a built binary pulls in LGPL obligations.
What can a loaded wasm module actually do once it's running?
Each module gets a per-slot capability bitmask (ALLOC, READKMEM, WRITEKMEM, MSRREAD/WRITE, PHYSMEM, CPUIDTSC, CALLBACKS, HOSTCALL, INTROSPECT) that gates which host imports like hostreadmsr or hostphysread it's allowed to call.
How do I actually talk to a module after loading it?
Through IOCTLs: LOADMODULE links a .wasm module's imports, CALLEXPORT invokes an export with up to 8 arguments, and TAILLOG/TAILTRACE let you poll its log and trace rings.
Why use wasm instead of just injecting shellcode into the kernel?
wasm3 interprets the guest bytecode with no JIT, so the kernel never executes dynamically generated native code, which keeps the driver compliant with HVCI and other W^X enforcement that would block unsigned native execution.
What's InfinityHook used for here?
It's a credited third-party trampoline technique the driver uses for hooking, giving it process/image notify-style callback interception without relying on undocumented SSDT patching.
What are similar projects?
scriptc, CalcKernel, open-gpu-kernel-modules, ZygiskNext, linux, mquickjs, reactos, lytlnyblOS
Which topics is it in?
qt6, clang, interpreter, driver, virtual-machine, webassembly, kernel, low-level, systems-programming, native, sandbox, wasm
