From cfa9606b756a0c7b32f390df814ac0b258bd7719 Mon Sep 17 00:00:00 2001 From: Ronnie Salomonsen Date: Sun, 9 Apr 2023 11:18:47 +0200 Subject: [PATCH 1/6] Added Time module --- 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/mod.rs | 21 +++++++++++++++++++++ yara-x/src/modules/time/tests.rs | 21 +++++++++++++++++++++ 5 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 yara-x/src/modules/protos/time.proto create mode 100644 yara-x/src/modules/time/mod.rs create mode 100644 yara-x/src/modules/time/tests.rs diff --git a/yara-x/Cargo.toml b/yara-x/Cargo.toml index dc9f5250f..9d465c848 100644 --- a/yara-x/Cargo.toml +++ b/yara-x/Cargo.toml @@ -24,6 +24,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 = [ @@ -62,7 +65,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/mod.rs b/yara-x/src/modules/time/mod.rs new file mode 100644 index 000000000..cb57a3339 --- /dev/null +++ b/yara-x/src/modules/time/mod.rs @@ -0,0 +1,21 @@ +use crate::modules::prelude::*; +use crate::modules::protos::time::*; +use std::time::{SystemTime, UNIX_EPOCH}; + +#[cfg(test)] +mod tests; + +#[module_main] +fn main(_ctx: &ScanContext) -> Time { + // Nothing to do, but we have to return our protobuf + let time_proto = Time::new(); + time_proto +} + +#[module_export(name = "now")] +fn now(ctx: &ScanContext) -> Option { + match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(n) => return Some(n.as_secs() as i64), + Err(_) => return None, + } +} \ No newline at end of file diff --git a/yara-x/src/modules/time/tests.rs b/yara-x/src/modules/time/tests.rs new file mode 100644 index 000000000..a283db350 --- /dev/null +++ b/yara-x/src/modules/time/tests.rs @@ -0,0 +1,21 @@ +use pretty_assertions::assert_eq; + +#[test] +fn e2e_test(){ + let mut src = String::new(); + src.push_str(r#"import "time""#); + src.push_str(r#"rule t {condition: time.now() >= 1680547861}"#); + + let rules = crate::compiler::Compiler::new() + .add_source(src.as_str()) + .unwrap() + .build() + .unwrap(); + + let data = b"DummyData\r"; + + let mut scanner = crate::scanner::Scanner::new(&rules); + let results = scanner.scan(data); + + assert_eq!(results.num_matching_rules(), 1); +} \ No newline at end of file From 7e3d31dd3ebf918222a70e1f4e0503081dcd0bb0 Mon Sep 17 00:00:00 2001 From: Ronnie Salomonsen Date: Mon, 10 Apr 2023 22:27:01 +0200 Subject: [PATCH 2/6] Cleaned up the code for Time module and added unit test to module source as a sub module. --- yara-x/src/modules/time.rs | 41 ++++++++++++++++++++++++++++++++ yara-x/src/modules/time/mod.rs | 21 ---------------- yara-x/src/modules/time/tests.rs | 21 ---------------- yara-x/src/tests/mod.rs | 3 +++ 4 files changed, 44 insertions(+), 42 deletions(-) create mode 100644 yara-x/src/modules/time.rs delete mode 100644 yara-x/src/modules/time/mod.rs delete mode 100644 yara-x/src/modules/time/tests.rs diff --git a/yara-x/src/modules/time.rs b/yara-x/src/modules/time.rs new file mode 100644 index 000000000..cac9451c5 --- /dev/null +++ b/yara-x/src/modules/time.rs @@ -0,0 +1,41 @@ +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 + let time_proto = Time::new(); + time_proto +} + +#[module_export(name = "now")] +fn time_now(ctx: &ScanContext) -> Option { + match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(n) => return Some(n.as_secs() as i64), + Err(_) => return None, + } +} + +#[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); + } +} diff --git a/yara-x/src/modules/time/mod.rs b/yara-x/src/modules/time/mod.rs deleted file mode 100644 index cb57a3339..000000000 --- a/yara-x/src/modules/time/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::modules::prelude::*; -use crate::modules::protos::time::*; -use std::time::{SystemTime, UNIX_EPOCH}; - -#[cfg(test)] -mod tests; - -#[module_main] -fn main(_ctx: &ScanContext) -> Time { - // Nothing to do, but we have to return our protobuf - let time_proto = Time::new(); - time_proto -} - -#[module_export(name = "now")] -fn now(ctx: &ScanContext) -> Option { - match SystemTime::now().duration_since(UNIX_EPOCH) { - Ok(n) => return Some(n.as_secs() as i64), - Err(_) => return None, - } -} \ No newline at end of file diff --git a/yara-x/src/modules/time/tests.rs b/yara-x/src/modules/time/tests.rs deleted file mode 100644 index a283db350..000000000 --- a/yara-x/src/modules/time/tests.rs +++ /dev/null @@ -1,21 +0,0 @@ -use pretty_assertions::assert_eq; - -#[test] -fn e2e_test(){ - let mut src = String::new(); - src.push_str(r#"import "time""#); - src.push_str(r#"rule t {condition: time.now() >= 1680547861}"#); - - let rules = crate::compiler::Compiler::new() - .add_source(src.as_str()) - .unwrap() - .build() - .unwrap(); - - let data = b"DummyData\r"; - - let mut scanner = crate::scanner::Scanner::new(&rules); - let results = scanner.scan(data); - - assert_eq!(results.num_matching_rules(), 1); -} \ No newline at end of file diff --git a/yara-x/src/tests/mod.rs b/yara-x/src/tests/mod.rs index 2b269c88f..6f20af4a9 100644 --- a/yara-x/src/tests/mod.rs +++ b/yara-x/src/tests/mod.rs @@ -795,3 +795,6 @@ fn test_proto2_module() { // condition_true!(r#"test_proto2.bool_yara"#); } + +//#[cfg(test)] +//mod test_time_module; \ No newline at end of file From e5d7b49e9547c4c4d6e3639d32fae878721a5088 Mon Sep 17 00:00:00 2001 From: Ronnie Salomonsen Date: Mon, 10 Apr 2023 22:52:17 +0200 Subject: [PATCH 3/6] Removed some commented leftovers in yara-x/src/mod.rs --- yara-x/src/tests/mod.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/yara-x/src/tests/mod.rs b/yara-x/src/tests/mod.rs index 6f20af4a9..a4c6bfe3e 100644 --- a/yara-x/src/tests/mod.rs +++ b/yara-x/src/tests/mod.rs @@ -794,7 +794,4 @@ fn test_proto2_module() { // [(yara.field_options).name = "bool_yara"]; // condition_true!(r#"test_proto2.bool_yara"#); -} - -//#[cfg(test)] -//mod test_time_module; \ No newline at end of file +} \ No newline at end of file From 4dc5161ad1bc7c89af31771a4b85fa6a915b44ba Mon Sep 17 00:00:00 2001 From: Ronnie Salomonsen Date: Tue, 11 Apr 2023 18:04:41 +0200 Subject: [PATCH 4/6] Small change to module --- yara-x/src/modules/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yara-x/src/modules/time.rs b/yara-x/src/modules/time.rs index cac9451c5..6f32aef9b 100644 --- a/yara-x/src/modules/time.rs +++ b/yara-x/src/modules/time.rs @@ -9,8 +9,8 @@ fn main(_ctx: &ScanContext) -> Time { time_proto } -#[module_export(name = "now")] -fn time_now(ctx: &ScanContext) -> Option { +#[module_export] +fn now(ctx: &ScanContext) -> Option { match SystemTime::now().duration_since(UNIX_EPOCH) { Ok(n) => return Some(n.as_secs() as i64), Err(_) => return None, From a863a8ea24b67afb290bcbbb64e8414d6ed40a7a Mon Sep 17 00:00:00 2001 From: Ronnie Salomonsen Date: Wed, 12 Apr 2023 20:30:32 +0200 Subject: [PATCH 5/6] fixed some formatting with rustfmt. issue was in yara-x/src/tests/mod.rs --- yara-x/src/tests/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yara-x/src/tests/mod.rs b/yara-x/src/tests/mod.rs index a4c6bfe3e..2b269c88f 100644 --- a/yara-x/src/tests/mod.rs +++ b/yara-x/src/tests/mod.rs @@ -794,4 +794,4 @@ fn test_proto2_module() { // [(yara.field_options).name = "bool_yara"]; // condition_true!(r#"test_proto2.bool_yara"#); -} \ No newline at end of file +} From 4f7fe16b392b073347b4b5c0f5ecd4c001f8e35b Mon Sep 17 00:00:00 2001 From: Ronnie Salomonsen Date: Wed, 19 Apr 2023 21:49:36 +0200 Subject: [PATCH 6/6] Updated code to fix Clippy issues. --- yara-x/src/modules/time.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/yara-x/src/modules/time.rs b/yara-x/src/modules/time.rs index 6f32aef9b..76ac94c36 100644 --- a/yara-x/src/modules/time.rs +++ b/yara-x/src/modules/time.rs @@ -5,16 +5,12 @@ use std::time::{SystemTime, UNIX_EPOCH}; #[module_main] fn main(_ctx: &ScanContext) -> Time { // Nothing to do, but we have to return our protobuf - let time_proto = Time::new(); - time_proto + Time::new() } #[module_export] fn now(ctx: &ScanContext) -> Option { - match SystemTime::now().duration_since(UNIX_EPOCH) { - Ok(n) => return Some(n.as_secs() as i64), - Err(_) => return None, - } + Some(SystemTime::now().duration_since(UNIX_EPOCH).ok()?.as_secs() as i64) } #[cfg(test)]