pub struct Scanner<'r> { /* private fields */ }Expand description
Scans data in blocks
This scanner is designed for scenarios where the data to be scanned is not available as a single contiguous block of memory, but rather arrives in smaller, discrete blocks, allowing for incremental scanning.
§Examples
let rules = compile(r#"rule test { strings: $a = "abc" condition: $a }"#).unwrap();
let mut scanner = blocks::Scanner::new(&rules);
// Scan the first block of data.
scanner.scan(0, b"xabcy").unwrap();
// Scan a second block of data, which can overlap with the first.
scanner.scan(3, b"cyz").unwrap();
// Finish the scan and get the results.
let results = scanner.finish().unwrap();
assert_eq!(results.matching_rules().len(), 1);§Limitations of Block Scanning
Block scanning works by analyzing data in chunks rather than as a whole file. This makes it useful for streaming or memory-constrained scenarios, but it comes with important limitations compared to standard scanning:
- Modules won’t work. Parsers for structured formats (e.g., PE, ELF) require access to the entire file and cannot be applied in block scanning mode.
- Other modules like
hashwon’t work either, as they require access to all the scanned data during the evaluation of the rule’s condition, something that can’t be guaranteed in block scanning mode. The hash functions will returnundefinedwhen used in a multi-block context. - Built-in functions like
uint8,uint16,uint32, etc., have the same limitation. They also returnundefinedin block scanning mode. - The
filesizekeyword returnsundefinedin block scanning mode. - Patterns won’t match across block boundaries. Every match will be completely contained within one of the blocks.
All these limitations imply that in block scanning mode you should only use rules that rely on text, hex or regex patterns.
§Data Consistency in Overlapping Blocks
When Scanner::scan is invoked multiple times with different blocks
that may overlap, the user is responsible for ensuring data consistency.
This means that if the same region of the original data is present in two
or more overlapping blocks, the content of that region must be identical
across all calls to this function.
Generally speaking, the scanner does not verify this consistency and assumes the user provides accurate and consistent data. In debug releases the scanner may try to verify this consistency, but only when some pattern matches in the overlapping region.
Implementations§
Source§impl<'r> Scanner<'r>
impl<'r> Scanner<'r>
Sourcepub fn match_context_size(&mut self, size: usize) -> &mut Self
pub fn match_context_size(&mut self, size: usize) -> &mut Self
Sets the context size for matches.
This specifies how many bytes at the left and right of each match will
be reported by crate::Match::data_with_context. By default, the
match context size is 0, which means that crate::Match::data_with_context
will return exactly the same data as crate::Match::data.
Source§impl<'r> Scanner<'r>
impl<'r> Scanner<'r>
Sourcepub fn scan(&mut self, base: usize, data: &[u8]) -> Result<&mut Self, ScanError>
pub fn scan(&mut self, base: usize, data: &[u8]) -> Result<&mut Self, ScanError>
Scans a block of data.
This method processes a given block of data, searching for patterns
defined in the YARA rules. The base argument specifies the offset
of the current block within the overall data being scanned. In most
cases you will want to call this method multiple times, providing a
different block on each call.
§Arguments
base- The starting offset of thedatablock within overall data being scanned.data- The byte slice representing the current block of data to scan.
§Returns
A Result indicating success or a ScanError if the scan operation
fails.
Sourcepub fn finish(&mut self) -> Result<ScanResults<'_, 'r>, ScanError>
pub fn finish(&mut self) -> Result<ScanResults<'_, 'r>, ScanError>
Finalizes the scanning process.
After all data blocks have been scanned, this method evaluates the conditions of the YARA rules and produces the final scan results.
Sourcepub fn set_global<T: TryInto<Variable>>(
&mut self,
ident: &str,
value: T,
) -> Result<&mut Self, VariableError>
pub fn set_global<T: TryInto<Variable>>( &mut self, ident: &str, value: T, ) -> Result<&mut Self, VariableError>
Sets the value of a global variable.
The variable must has been previously defined by calling
crate::Compiler::define_global, and the type it has during the
definition must match the type of the new value (T).
The variable will retain the new value in subsequent scans, unless this function is called again for setting a new value.
Sourcepub fn set_timeout(&mut self, timeout: Duration) -> &mut Self
pub fn set_timeout(&mut self, timeout: Duration) -> &mut Self
Sets a timeout for scan operations.
The scan functions will return an ScanError::Timeout once the provided timeout duration has elapsed. The scanner will make every effort to stop promptly after the designated timeout duration. However, in some cases, particularly with rules containing only a few patterns, the scanner could potentially continue running for a longer period than the specified timeout.
Sourcepub fn max_matches_per_pattern(&mut self, n: usize) -> &mut Self
pub fn max_matches_per_pattern(&mut self, n: usize) -> &mut Self
Sets the maximum number of matches per pattern.
When some pattern reaches the maximum number of patterns it won’t produce more matches.
Sourcepub fn fast_scan(&mut self, yes: bool) -> &mut Self
pub fn fast_scan(&mut self, yes: bool) -> &mut Self
Enables or disables fast scan mode.
In fast scan mode, the scanner avoids tracking matches for patterns
when it is not necessary (e.g. when a rule condition only performs a
simple boolean check $a).
Note that using fast scan mode implies that not all matches will be
reported. For instance, when iterating matches using ScanResults,
you won’t get all occurrences of the pattern in the file, only the first
one.
Sourcepub fn console_log<F>(&mut self, callback: F) -> &mut Self
pub fn console_log<F>(&mut self, callback: F) -> &mut Self
Sets a callback that is invoked every time a YARA rule calls the
console module.
The callback function is invoked with a string representing the
message being logged. The function can print the message to stdout,
append it to a file, etc. If no callback is set these messages are
ignored.
Sourcepub fn slowest_rules(&self, n: usize) -> Vec<ProfilingData<'_>>
Available on crate feature rules-profiling only.
pub fn slowest_rules(&self, n: usize) -> Vec<ProfilingData<'_>>
rules-profiling only.Returns profiling data for the slowest N rules.
The profiling data reflects the cumulative execution time of each rule
across all scanned files. This information is useful for identifying
performance bottlenecks. To reset the profiling data and start fresh
for subsequent scans, use crate::Scanner::clear_profiling_data.
Sourcepub fn clear_profiling_data(&mut self)
Available on crate feature rules-profiling only.
pub fn clear_profiling_data(&mut self)
rules-profiling only.Clears all accumulated profiling data.
This method resets the profiling data collected during rule execution across scanned files. Use this to start a new profiling session, ensuring the results reflect only the data gathered after this method is called.
Trait Implementations§
Auto Trait Implementations§
impl<'r> !RefUnwindSafe for Scanner<'r>
impl<'r> !Send for Scanner<'r>
impl<'r> !Sync for Scanner<'r>
impl<'r> !UnwindSafe for Scanner<'r>
impl<'r> Freeze for Scanner<'r>
impl<'r> Unpin for Scanner<'r>
impl<'r> UnsafeUnpin for Scanner<'r>
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.