use malwaredb_api::YaraSearchRequest;
use tracing::error;
use uuid::Uuid;
use yara_x::errors::CompileError;
use yara_x::{Compiler, Rules};
#[cfg(not(any(
target_arch = "aarch64",
target_arch = "riscv64",
target_arch = "s390x",
target_arch = "x86_64"
)))]
compile_error!("Compile error: Yara not supported on this architecture.");
pub(crate) const MAX_YARA_PROCESSES: usize = 4;
pub struct YaraTask {
pub id: Uuid,
pub yara_string: String,
pub yara_bytes: Vec<u8>,
pub last_file_id: Option<u64>,
pub user_id: u32,
}
impl YaraTask {
pub(crate) fn process_yara_rules(&self, sample: &[u8]) -> anyhow::Result<Vec<String>> {
let rules = Rules::deserialize(&self.yara_bytes)?;
let mut scanner = yara_x::Scanner::new(&rules);
let mut results = Vec::new();
match scanner.scan(sample) {
Ok(matches) => {
for rule in matches.matching_rules() {
results.push(String::from(rule.identifier()));
}
}
Err(e) => {
error!("Error scanning sample: {e}");
}
}
Ok(results)
}
}
pub(crate) fn compile_yara_rules(request: YaraSearchRequest) -> Result<Rules, CompileError> {
let mut compiler = Compiler::new();
for rule in request.rules {
compiler.add_source(&*rule)?;
}
Ok(compiler.build())
}