Skip to content

Commit

Permalink
Set and get configuration (#35)
Browse files Browse the repository at this point in the history
feat: add set and get configuration

Co-authored-by: Ivan Krivosheev <ikrivosheev@ptsecurity.com>
  • Loading branch information
ikrivosheev and Ivan Krivosheev committed Jul 22, 2021
1 parent 6d40365 commit 967b23a
Show file tree
Hide file tree
Showing 9 changed files with 280 additions and 49 deletions.
52 changes: 52 additions & 0 deletions src/internals/configuration.rs
@@ -0,0 +1,52 @@
use std::ffi::c_void;

use yara_sys;

use crate::errors::*;

/// A `ConfigName` is enum of available configuration options
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ConfigName {
/// Stack size to use for YR_CONFIG_STACK_SIZE
StackSize,
/// Maximum number of strings to allow per yara rule. Will be mapped to YR_CONFIG_MAX_STRINGS_PER_RULE
MaxStringsPerRule,
/// Maximum number of bytes to allow per yara match. Will be mapped to YR_CONFIG_MAX_MATCH_DATA
MaxMatchData,
}

#[cfg(unix)]
type EnumType = u32;
#[cfg(windows)]
type EnumType = i32;

impl ConfigName {
pub fn to_yara(&self) -> EnumType {
use self::ConfigName::*;
let res = match self {
StackSize => yara_sys::_YR_CONFIG_NAME_YR_CONFIG_STACK_SIZE,
MaxStringsPerRule => yara_sys::_YR_CONFIG_NAME_YR_CONFIG_MAX_STRINGS_PER_RULE,
MaxMatchData => yara_sys::_YR_CONFIG_NAME_YR_CONFIG_MAX_MATCH_DATA,
};
res as EnumType
}
}

pub fn set_configuration(name: ConfigName, value: u32) -> Result<(), YaraError> {
let result = unsafe {
yara_sys::yr_set_configuration(name.to_yara(), &value as *const u32 as *mut c_void)
};

yara_sys::Error::from_code(result).map_err(Into::into)
}

pub fn get_configuration(name: ConfigName) -> Result<u32, YaraError> {
let value: u32 = 0;
let result = unsafe {
yara_sys::yr_get_configuration(name.to_yara(), &value as *const u32 as *mut c_void)
};

yara_sys::Error::from_code(result)
.map_err(Into::into)
.map(|_| value)
}
23 changes: 13 additions & 10 deletions src/internals/mod.rs
@@ -1,22 +1,25 @@
use std::sync::Mutex;

use lazy_static::lazy_static;
pub use yara_sys;

use crate::errors::*;

pub use self::compiler::*;
pub use self::configuration::*;
pub use self::rules::*;
pub use self::scan::*;

pub mod matches;
pub mod meta;
pub mod string;

mod compiler;
mod configuration;
mod rules;
mod scan;
mod stream;

pub use self::compiler::*;
pub use self::rules::*;
pub use self::scan::*;

use std::sync::Mutex;

use lazy_static::lazy_static;

use crate::errors::*;

lazy_static! {
static ref INIT_MUTEX: Mutex<()> = Mutex::new(());
}
Expand Down
3 changes: 2 additions & 1 deletion src/internals/scan.rs
@@ -1,15 +1,16 @@
use std::convert::TryInto;
use std::ffi::{CStr, CString};
use std::fs::File;
use std::os::raw::c_void;
#[cfg(unix)]
use std::os::unix::io::AsRawFd;
#[cfg(windows)]
use std::os::windows::io::AsRawHandle;

use yara_sys::{YR_SCANNER, YR_SCAN_CONTEXT};

use crate::errors::*;
use crate::Rule;
use std::convert::TryInto;

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
enum CallbackMsg {
Expand Down
30 changes: 21 additions & 9 deletions src/lib.rs
Expand Up @@ -45,6 +45,17 @@
//! [Yara-doc]: https://yara.readthedocs.io/en/stable/gettingstarted.html
//! [polydet]: https://github.com/Polydet/polydet/

pub use internals::ConfigName;
use internals::{get_configuration, set_configuration};

pub use crate::compiler::Compiler;
pub use crate::errors::*;
use crate::initialize::InitializationToken;
pub use crate::matches::Match;
pub use crate::rules::*;
pub use crate::scanner::Scanner;
pub use crate::string::YrString;

mod compiler;
mod initialize;
mod internals;
Expand All @@ -55,15 +66,6 @@ mod string;

pub mod errors;

use crate::initialize::InitializationToken;

pub use crate::compiler::Compiler;
pub use crate::errors::*;
pub use crate::matches::Match;
pub use crate::rules::*;
pub use crate::scanner::Scanner;
pub use crate::string::YrString;

/// Yara initialization token.
///
/// Act as an initialization token to keep the library initialized.
Expand Down Expand Up @@ -134,6 +136,16 @@ impl Yara {
InitializationToken::new().map(|token| Yara { _token: token })
}

/// Set the configuration variable
pub fn set_configuration(&self, name: ConfigName, value: u32) -> Result<(), YaraError> {
set_configuration(name, value)
}

/// Get the configuration variable
pub fn get_configuration(&self, name: ConfigName) -> Result<u32, YaraError> {
get_configuration(name)
}

/// Create and initialize the library.
#[deprecated = "Use new"]
pub fn create() -> Result<Yara, YaraError> {
Expand Down
7 changes: 6 additions & 1 deletion src/scanner.rs
Expand Up @@ -322,7 +322,12 @@ mod test {

let bytes = if cfg!(windows) {
// the string is in utf-16 format, filter out the zeroes.
string.matches[0].data.clone().into_iter().filter(|v| *v != 0).collect()
string.matches[0]
.data
.clone()
.into_iter()
.filter(|v| *v != 0)
.collect()
} else {
string.matches[0].data.clone()
};
Expand Down
9 changes: 8 additions & 1 deletion tests/tests.rs
@@ -1,6 +1,6 @@
extern crate yara;

use yara::{CompileErrorLevel, Compiler, Error, Metadata, MetadataValue, Rules, Yara};
use yara::{CompileErrorLevel, Compiler, ConfigName, Error, Metadata, MetadataValue, Rules, Yara};

const RULES: &str = r#"
rule is_awesome {
Expand Down Expand Up @@ -42,6 +42,13 @@ fn test_initialize() {
assert!(Yara::new().is_ok());
}

#[test]
fn test_configuration() {
let yara = Yara::new().expect("Should be Ok");
assert_eq!(Ok(()), yara.set_configuration(ConfigName::StackSize, 100));
assert_eq!(Ok(100), yara.get_configuration(ConfigName::StackSize));
}

#[test]
fn test_create_compiler() {
assert!(Compiler::new().is_ok());
Expand Down
99 changes: 76 additions & 23 deletions yara-sys/bindings/yara-4.1.1-unix.rs
Expand Up @@ -96,22 +96,57 @@ pub type __time_t = ::std::os::raw::c_long;
pub type __suseconds_t = ::std::os::raw::c_long;
pub type __syscall_slong_t = ::std::os::raw::c_long;
pub type FILE = _IO_FILE;
pub type _IO_lock_t = ::std::os::raw::c_void;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _IO_marker {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _IO_codecvt {
_unused: [u8; 0],
pub _next: *mut _IO_marker,
pub _sbuf: *mut _IO_FILE,
pub _pos: ::std::os::raw::c_int,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _IO_wide_data {
_unused: [u8; 0],
#[test]
fn bindgen_test_layout__IO_marker() {
assert_eq!(
::std::mem::size_of::<_IO_marker>(),
24usize,
concat!("Size of: ", stringify!(_IO_marker))
);
assert_eq!(
::std::mem::align_of::<_IO_marker>(),
8usize,
concat!("Alignment of ", stringify!(_IO_marker))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<_IO_marker>()))._next as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(_IO_marker),
"::",
stringify!(_next)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<_IO_marker>()))._sbuf as *const _ as usize },
8usize,
concat!(
"Offset of field: ",
stringify!(_IO_marker),
"::",
stringify!(_sbuf)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<_IO_marker>()))._pos as *const _ as usize },
16usize,
concat!(
"Offset of field: ",
stringify!(_IO_marker),
"::",
stringify!(_pos)
)
);
}
pub type _IO_lock_t = ::std::os::raw::c_void;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _IO_FILE {
Expand All @@ -137,10 +172,10 @@ pub struct _IO_FILE {
pub _shortbuf: [::std::os::raw::c_char; 1usize],
pub _lock: *mut _IO_lock_t,
pub _offset: __off64_t,
pub _codecvt: *mut _IO_codecvt,
pub _wide_data: *mut _IO_wide_data,
pub _freeres_list: *mut _IO_FILE,
pub _freeres_buf: *mut ::std::os::raw::c_void,
pub __pad1: *mut ::std::os::raw::c_void,
pub __pad2: *mut ::std::os::raw::c_void,
pub __pad3: *mut ::std::os::raw::c_void,
pub __pad4: *mut ::std::os::raw::c_void,
pub __pad5: size_t,
pub _mode: ::std::os::raw::c_int,
pub _unused2: [::std::os::raw::c_char; 20usize],
Expand Down Expand Up @@ -378,43 +413,43 @@ fn bindgen_test_layout__IO_FILE() {
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._codecvt as *const _ as usize },
unsafe { &(*(::std::ptr::null::<_IO_FILE>())).__pad1 as *const _ as usize },
152usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_codecvt)
stringify!(__pad1)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._wide_data as *const _ as usize },
unsafe { &(*(::std::ptr::null::<_IO_FILE>())).__pad2 as *const _ as usize },
160usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_wide_data)
stringify!(__pad2)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._freeres_list as *const _ as usize },
unsafe { &(*(::std::ptr::null::<_IO_FILE>())).__pad3 as *const _ as usize },
168usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_freeres_list)
stringify!(__pad3)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._freeres_buf as *const _ as usize },
unsafe { &(*(::std::ptr::null::<_IO_FILE>())).__pad4 as *const _ as usize },
176usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_freeres_buf)
stringify!(__pad4)
)
);
assert_eq!(
Expand Down Expand Up @@ -3608,12 +3643,30 @@ extern "C" {
rules: *mut *mut YR_RULES,
) -> ::std::os::raw::c_int;
}
pub const _YR_CONFIG_NAME_YR_CONFIG_STACK_SIZE: _YR_CONFIG_NAME = 0;
pub const _YR_CONFIG_NAME_YR_CONFIG_MAX_STRINGS_PER_RULE: _YR_CONFIG_NAME = 1;
pub const _YR_CONFIG_NAME_YR_CONFIG_MAX_MATCH_DATA: _YR_CONFIG_NAME = 2;
pub const _YR_CONFIG_NAME_YR_CONFIG_LAST: _YR_CONFIG_NAME = 3;
pub type _YR_CONFIG_NAME = ::std::os::raw::c_uint;
pub use self::_YR_CONFIG_NAME as YR_CONFIG_NAME;
extern "C" {
pub fn yr_initialize() -> ::std::os::raw::c_int;
}
extern "C" {
pub fn yr_finalize() -> ::std::os::raw::c_int;
}
extern "C" {
pub fn yr_set_configuration(
arg1: YR_CONFIG_NAME,
arg2: *mut ::std::os::raw::c_void,
) -> ::std::os::raw::c_int;
}
extern "C" {
pub fn yr_get_configuration(
arg1: YR_CONFIG_NAME,
arg2: *mut ::std::os::raw::c_void,
) -> ::std::os::raw::c_int;
}
pub type YR_SCANNER = YR_SCAN_CONTEXT;
extern "C" {
pub fn yr_scanner_create(
Expand Down

0 comments on commit 967b23a

Please sign in to comment.