1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
//! # 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 //! //! ```rust //! 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(); //! } //! ``` //! //! [KrabsETW]: https://github.com/microsoft/krabsetw/ //! [Source]: https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing #[macro_use] extern crate memoffset; #[macro_use] extern crate bitflags; #[macro_use] extern crate num_derive; extern crate num_traits; #[macro_use] extern crate lazy_static; pub mod native; pub mod parser; pub mod property; pub mod provider; pub mod schema; pub mod trace; mod traits; mod utils;