boreal/
lib.rs

1//! **boreal** is a YARA rules evaluator, used to search for textual and binary patterns.
2//!
3//! This crate is a reimplementation of the [YARA library](https://github.com/VirusTotal/yara).
4//! It aims to provide the same set of functionalities, and be fully compatible with all existing
5//! YARA rules.
6//!
7//! Here is an example on how to use the library.
8//!
9//! ```
10//! use boreal::Compiler;
11//!
12//! // Rules must first be added to a compiler.
13//! let mut compiler = Compiler::new();
14//! compiler.add_rules_str(r#"
15//! rule example {
16//!     meta:
17//!         description = "This is an YARA rule example"
18//!         date = "2022-11-11"
19//!     strings:
20//!         $s1 = { 78 6d 6c 68 74 74 70 2e 73 65 6e 64 28 29 }
21//!         $s2 = "tmp.dat" fullword wide
22//!     condition:
23//!         any of them
24//! }
25//! "#)?;
26//!
27//! // Then, all added rules are compiled into a scanner object.
28//! let scanner = compiler.into_scanner();
29//!
30//! // Use this object to scan strings or files.
31//! let res = scanner.scan_mem(b"<\0t\0m\0p\0.\0d\0a\0t\0>\0").unwrap();
32//! assert!(res.matched_rules.iter().any(|rule| rule.name == "example"));
33//!
34//! # Ok::<(), boreal::compiler::AddRuleError>(())
35//! ```
36
37// Deny most of allowed by default lints from rustc.
38#![deny(explicit_outlives_requirements)]
39#![deny(keyword_idents)]
40#![deny(macro_use_extern_crate)]
41#![deny(non_ascii_idents)]
42#![deny(noop_method_call)]
43#![deny(rust_2021_compatibility)]
44#![deny(single_use_lifetimes)]
45#![deny(trivial_casts)]
46#![deny(trivial_numeric_casts)]
47#![deny(unused_crate_dependencies)]
48#![deny(unused_extern_crates)]
49#![deny(unused_import_braces)]
50#![deny(unused_lifetimes)]
51#![deny(unused_qualifications)]
52#![deny(unused_results)]
53#![deny(unsafe_op_in_unsafe_fn)]
54// Do the same for clippy
55#![deny(clippy::all)]
56#![deny(clippy::pedantic)]
57#![deny(clippy::undocumented_unsafe_blocks)]
58// Allow some useless pedantic lints
59#![allow(clippy::module_name_repetitions)]
60#![allow(clippy::unnested_or_patterns)]
61#![allow(clippy::match_same_arms)]
62#![allow(clippy::too_many_lines)]
63#![allow(clippy::single_match_else)]
64#![allow(clippy::inline_always)]
65#![allow(clippy::struct_field_names)]
66#![allow(clippy::struct_excessive_bools)]
67#![allow(unsafe_code)]
68#![deny(missing_docs)]
69#![deny(clippy::cargo)]
70// Handled by cargo-deny
71#![allow(clippy::multiple_crate_versions)]
72#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
73
74// Used in integration tests, not in the library.
75// This is to remove the "unused_crate_dependencies" warning, maybe a better solution
76// could be found.
77#[cfg(test)]
78use base64 as _;
79#[cfg(test)]
80use glob as _;
81#[cfg(test)]
82use tempfile as _;
83#[cfg(test)]
84use yara as _;
85
86// If the "hash" feature is enabled but not the "object" feature, the tlsh2 crate
87// is added but unused, Since it depends on both being enabled. I don't think
88// there is a way to express this in the cargo dependencies, and this dependency
89// is extremely light, so it is just ignored in this case.
90#[cfg(all(feature = "hash", not(feature = "object")))]
91use tlsh2 as _;
92
93pub(crate) mod atoms;
94mod bitmaps;
95mod bytes_pool;
96pub use bytes_pool::{BytesSymbol, StringSymbol};
97pub mod compiler;
98pub use compiler::rule::{Metadata, MetadataValue};
99pub use compiler::Compiler;
100mod evaluator;
101mod matcher;
102pub mod memory;
103pub mod module;
104pub mod regex;
105pub mod scanner;
106pub use scanner::Scanner;
107pub mod statistics;
108mod timeout;
109
110#[cfg(test)]
111mod test_helpers;