1use malwaredb_api::YaraSearchRequest;
4
5use tracing::error;
6use uuid::Uuid;
7use yara_x::errors::CompileError;
8use yara_x::{Compiler, Rules};
9
10#[cfg(not(any(
11 target_arch = "aarch64",
12 target_arch = "riscv64",
13 target_arch = "s390x",
14 target_arch = "x86_64"
15)))]
16compile_error!("Compile error: Yara not supported on this architecture.");
17
18pub(crate) const MAX_YARA_PROCESSES: usize = 4;
19
20pub const YARA_VERSION: &str = yara_x::VERSION;
22
23pub struct YaraTask {
25 pub id: Uuid,
27
28 pub yara_string: String,
30
31 pub yara_bytes: Vec<u8>,
33
34 pub last_file_id: Option<u64>,
36
37 pub user_id: u32,
39}
40
41impl YaraTask {
42 pub(crate) fn process_yara_rules(&self, sample: &[u8]) -> anyhow::Result<Vec<String>> {
43 let rules = Rules::deserialize(&self.yara_bytes)?;
45 let mut scanner = yara_x::Scanner::new(&rules);
46 let mut results = Vec::new();
47 match scanner.scan(sample) {
48 Ok(matches) => {
49 for rule in matches.matching_rules() {
50 results.push(String::from(rule.identifier()));
51 }
52 }
53 Err(e) => {
54 error!("Error scanning sample: {e}");
55 }
56 }
57
58 Ok(results)
59 }
60}
61
62pub(crate) fn compile_yara_rules(request: YaraSearchRequest) -> Result<Rules, CompileError> {
63 let mut compiler = Compiler::new();
64
65 for rule in request.rules {
66 compiler.add_source(&*rule)?;
67 }
68
69 Ok(compiler.build())
70}