From 8d0a143ec50695f440371a91bb45bad37dc5a9b5 Mon Sep 17 00:00:00 2001 From: Ronnie Salomonsen Date: Fri, 18 Aug 2023 14:03:47 +0200 Subject: [PATCH] feat: implement time module (#17) --- yara-x/Cargo.toml | 4 ++- yara-x/src/modules/modules.rs | 2 ++ yara-x/src/modules/protos/time.proto | 13 ++++++++++ yara-x/src/modules/time.rs | 37 ++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 yara-x/src/modules/protos/time.proto create mode 100644 yara-x/src/modules/time.rs diff --git a/yara-x/Cargo.toml b/yara-x/Cargo.toml index 67b2690c4..627b58cff 100644 --- a/yara-x/Cargo.toml +++ b/yara-x/Cargo.toml @@ -27,6 +27,9 @@ test_proto3-module = [] text-module = [ "dep:lingua" ] +# The Time module allows you to retrieve epoch in seconds that can +# be used in conditions of a rule to check againts other epoch time. +time-module = [] # Features that are enabled by default. default = [ @@ -69,7 +72,6 @@ yara-x-proto = { workspace = true } lingua = { version = "1.4.0", optional = true, default-features = false, features = ["english", "german", "french", "spanish"] } - [build-dependencies] protobuf = { workspace = true } protobuf-codegen = { workspace = true } diff --git a/yara-x/src/modules/modules.rs b/yara-x/src/modules/modules.rs index b968e2d7c..8dfb8359a 100644 --- a/yara-x/src/modules/modules.rs +++ b/yara-x/src/modules/modules.rs @@ -3,5 +3,7 @@ pub mod text; #[cfg(feature = "test_proto2-module")] pub mod test_proto2; +#[cfg(feature = "time-module")] +pub mod time; #[cfg(feature = "test_proto3-module")] pub mod test_proto3; \ No newline at end of file diff --git a/yara-x/src/modules/protos/time.proto b/yara-x/src/modules/protos/time.proto new file mode 100644 index 000000000..fe1373850 --- /dev/null +++ b/yara-x/src/modules/protos/time.proto @@ -0,0 +1,13 @@ +syntax = "proto2"; + +import "yara.proto"; + +option (yara.module_options) = { + name : "time" + root_message: "Time" + rust_module: "time" +}; + +message Time { + // This module contains only exported functions, and doesn't return any data +} \ No newline at end of file diff --git a/yara-x/src/modules/time.rs b/yara-x/src/modules/time.rs new file mode 100644 index 000000000..76ac94c36 --- /dev/null +++ b/yara-x/src/modules/time.rs @@ -0,0 +1,37 @@ +use crate::modules::prelude::*; +use crate::modules::protos::time::*; +use std::time::{SystemTime, UNIX_EPOCH}; + +#[module_main] +fn main(_ctx: &ScanContext) -> Time { + // Nothing to do, but we have to return our protobuf + Time::new() +} + +#[module_export] +fn now(ctx: &ScanContext) -> Option { + Some(SystemTime::now().duration_since(UNIX_EPOCH).ok()?.as_secs() as i64) +} + +#[cfg(test)] +mod tests { + #[test] + fn end2end() { + let rules = crate::compiler::Compiler::new() + .add_source( + r#"import "time" + rule rule_1 { condition: time.now() >= 0 } + rule rule_2 { condition: time.now() <= 0 } + rule rule_3 { condition: time.now() != 0 } + rule rule_4 { condition: time.now() == 0 } + "#, + ) + .unwrap() + .build() + .unwrap(); + + let mut scanner = crate::scanner::Scanner::new(&rules); + + assert_eq!(scanner.scan(&[]).num_matching_rules(), 2); + } +}