use std::time::Duration;
use ferrisetw::parser::Parser;
use ferrisetw::provider::kernel_providers;
use ferrisetw::provider::{EventFilter, Provider};
use ferrisetw::schema_locator::SchemaLocator;
use ferrisetw::trace::KernelTrace;
use ferrisetw::EventRecord;
use windows::core::HSTRING;
use windows::Win32::Foundation::HANDLE;
use windows::Win32::System::LibraryLoader::{LoadLibraryExW, LOAD_LIBRARY_FLAGS};
mod utils;
use utils::{Status, StatusNotifier, TestKind};
const TEST_LIBRARY_NAME: &str = "crypt32.dll";
#[test]
fn kernel_trace_tests() {
let passed1 = Status::new(TestKind::ExpectSuccess);
let notifier1 = passed1.notifier();
let moved_trace = create_simple_kernel_trace_trace(notifier1);
generate_image_load_events();
passed1.assert_passed();
moved_trace.stop().unwrap();
println!("Test passed");
}
fn create_simple_kernel_trace_trace(notifier: StatusNotifier) -> KernelTrace {
println!("We are process {}", std::process::id());
let our_process_only = EventFilter::ByPids(vec![std::process::id() as _]);
let kernel_provider = Provider::kernel(&kernel_providers::IMAGE_LOAD_PROVIDER)
.add_filter(our_process_only)
.add_callback(
move |record: &EventRecord, schema_locator: &SchemaLocator| {
let schema = schema_locator.event_schema(record).unwrap();
let parser = Parser::create(record, &schema);
if has_seen_dll_load(record, &parser) {
notifier.notify_success();
}
},
)
.build();
KernelTrace::new()
.enable(kernel_provider)
.start_and_process()
.unwrap()
}
fn load_library(libname: &str) {
let widename = HSTRING::from(libname);
let res =
unsafe { LoadLibraryExW(&widename, HANDLE::default(), LOAD_LIBRARY_FLAGS::default()) };
res.unwrap();
}
fn generate_image_load_events() {
std::thread::sleep(Duration::from_secs(1));
println!("Will load a specific DLL...");
load_library(TEST_LIBRARY_NAME);
println!("Loading done.");
}
fn has_seen_dll_load(record: &EventRecord, parser: &Parser) -> bool {
if record.process_id() == std::process::id() {
let filename = parser.try_parse::<String>("FileName");
println!(" this one's for us: {:?}", filename);
if let Ok(filename) = filename {
if filename.ends_with(TEST_LIBRARY_NAME) {
return true;
}
}
}
false
}