This project lets users write plugins that can hook windows system calls. I've open sourced a C++ and also a Rust driver. The rust driver embeds web assembly into the windows kernel for handling hook events, while the C++ version maps dlls to the kernel. Included is also a Rust project PDBReSym which handles downloading, parsing, and symbolicating using PDBs. This tool doesn't rely on the normal Microsoft DIA sdk apis for symbols and is significantly faster.
This work was presented at DEFCON 30 this week. Happy to answer any questions!
I thought one of the goals of dtrace was to make the in-kernel code weak enough (for example by forbidden unrestricted looping) to make system administrators confident injecting code in the kernel was safe.
Aren’t “embedding web assembly into the kernel” and “mapping DLLs into the kernel” too dangerous to call this a dtrace reimplementation?
I can't speak to the original intent for severely limiting the language dtrace uses (no loops, user defined functions, etc). However, I can say that web assembly itself is designed to be sandboxed so I wouldn't say that is too dangerous at all. It would be quite nice if Microsoft explored a web assembly kernel engine. You see designs like this with ebpf already, they all are trying to do the same - create a statically verifiable language and isolate it's execution. I'd argue using something like web assembly is much better than designing a new language like dtrace does honestly. It's good enough for browsers to run untrusted code, kernel is not terribly different. My WASM kernel driver is however just a POC to vet the idea.
For dlls in the kernel, yes absolutely insecure. It's intended to be a tool run in an analysis VM not on endpoint user systems. The security model is simply different for the DLL based architecture. One of the big reasons I am ok with this design is because driver signature enforcement already must be manually disabled to load the C driver that uses DLLs like this. With DSE off you can already easily load unsigned kernel code so this doesn't open any additional security holes.
it's a dtrace reimplementation because it's using those kernel interfaces. The architecture of the scripting system on top of that could be anything. The wasm rust system mirrors MS' architecture, the C++ DLL system differs intentionally from it.
“To prevent DIF from inducing an infinite loop in probe context, only forward branches are permitted. This safety provision may seem draconian — it eliminates loops altogether — but in practice we have not discovered it to present a serious limitation”
And we disagree about what can be called “a dtrace reimplementation”. Because there’s decades of prior art on tracing, I wouldn’t call anything that allows looping that.
From their quote it does represent a big limitation unfortunately. No loops limits the ability to do relatively simple string manipulations and iterate over other object collections where the size isn't statically known. The best you can do is basically manually unroll loops up to a fixed size. For windows dtrace for example it prevents you from writing your own wide to narrow strong routine, as well as doing sub string matches. Also, enumerating bit enums and converting flags to strings. There's many more cases too of course. I can understand the design limitation to some extent. But using the same kernel tracing APIs then extending it with a more powerful, arguably potentially less secure language, was a primary motivator for why I did this research at all. Ebpf for example allows loops. I disagree with you that a reimplementation must follow the complete architecture of the system being reimplemented, that's quite a strict interpretation in my opinion. You're of course entitled to that, I hope it's interesting/useful regardless of terminology :)
6 comments
[ 2.2 ms ] story [ 20.2 ms ] threadThis work was presented at DEFCON 30 this week. Happy to answer any questions!
Aren’t “embedding web assembly into the kernel” and “mapping DLLs into the kernel” too dangerous to call this a dtrace reimplementation?
For dlls in the kernel, yes absolutely insecure. It's intended to be a tool run in an analysis VM not on endpoint user systems. The security model is simply different for the DLL based architecture. One of the big reasons I am ok with this design is because driver signature enforcement already must be manually disabled to load the C driver that uses DLLs like this. With DSE off you can already easily load unsigned kernel code so this doesn't open any additional security holes.
it's a dtrace reimplementation because it's using those kernel interfaces. The architecture of the scripting system on top of that could be anything. The wasm rust system mirrors MS' architecture, the C++ DLL system differs intentionally from it.
“To prevent DIF from inducing an infinite loop in probe context, only forward branches are permitted. This safety provision may seem draconian — it eliminates loops altogether — but in practice we have not discovered it to present a serious limitation”
And we disagree about what can be called “a dtrace reimplementation”. Because there’s decades of prior art on tracing, I wouldn’t call anything that allows looping that.
[0] http://dtrace.org/blogs/bmc/2005/07/19/dtrace-safety/