[−][src]Crate ferrisetw
Event Windows Tracing FTW!
Basically a rip off KrabsETW written in Rust, hence the name Ferris
🦀
All credits go to the team at Microsoft who develop KrabsEtw, without it, this project probably wouldn't be a thing.
What's ETW
Event Tracing for Windows (ETW) is an efficient kernel-level tracing facility that lets you log kernel or application-defined events to a log file. You can consume the events in real time or from a log file and use them to debug an application or to determine where performance issues are occurring in the application. Source
ETW is made out of three components:
- Controllers
- Providers
- Consumers
This crate provides the means to start and stop a controller, enable/disable providers and finally to consume the events within our own defined callback.
Motivation
Even though ETW is a extremely powerful tracing mechanism, interacting with it is not easy by any means. There's a lot of details and caveats that have to be taken into consideration in order to make it work. On the other hand, once we manage to start consuming a trace session in real-time we have to deal with the process of finding the Schema and parsing the properties. All this process can be tedious and cumbersome, therefore tools like KrabsETW come in very handy to simplify the interaction with ETW.
Since lately I've been working very closely with ETW and Rust, I thought that having a tool that would simplify ETW management written in Rust and available as a crate for other to consume would be pretty neat and that's where this crate comes into play 🔥
Disclaimer
This project is still WIP. There's still plenty of things to evaluate/investigate and things to fix and do better. Any help would be greatly appreciated, also any issues you may have!
Although I encourage everyone to use Rust, I do believe that, at the moment, if you plan on interacting with ETW in a production level and the programming language is not a constraint you should definitely consider KrabsETW as a more robust and tested option. Hopefully in next iterations I'll be able to remove this disclaimer 😃
Getting started
If you are familiar with KrabsEtw you'll see using the crate is very similar, in case you are not familiar with it the following example shows the basics on how to build a provider, start a trace and handle the Event in the callback
fn callback(record: EventRecord, schema_locator: &mut SchemaLocator) { // Within the callback we first locate the proper Schema for the event match schema_locator.event_schema(record) { Ok(schema) => { // At the moment we can only filter by checking the event_id if schema.event_id() == 2 { // We build the Parser based on the Schema let mut parser = Parser::create(&schema); // Finally, Parse data from the Event, proper error handling should be done // Type annotations or Fully Qualified Syntax are needed when calling TryParse // Supported types implement the trait TryParse for Parser let process_id: u32 = parser.try_parse("ProcessID").unwrap(); let image_name: String = parser.try_parse("ImageName").unwrap(); println!("PID: {} ImageName: {}", process_id, image_name); } } Err(err) => println!("Error {:?}", err), }; } fn main() { // First we build a Provider let process_provider = Provider::new() .by_guid("22fb2cd6-0e7b-422b-a0c7-2fad1fd0e716") // Microsoft-Windows-Kernel-Process .add_callback(process_callback) .build() .unwrap(); // We start a trace session for the previously registered provider // This call will spawn a new thread which listens to the events let mut trace = UserTrace::new() .named(String::from("MyProvider")) .enable(process_provider) .start() .unwrap(); std::thread::sleep(Duration::new(20, 0)); // We stop the trace trace.stop(); }
Modules
native | Abstraction layer for Native functions and types |
parser | ETW Types Parser |
property | ETW Event Property information |
provider | ETW Providers abstraction. |
schema | ETW Event Schema locator and handler |
trace | ETW Tracing/Session abstraction |