forked from Hugal31/yara-rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 306f966
Showing
17 changed files
with
565 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/target | ||
**/*.rs.bk | ||
Cargo.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "yara" | ||
version = "0.1.0" | ||
authors = ["Hugo Laloge <[email protected]>"] | ||
description = "Rust bindings for VirusTotal/yara" | ||
|
||
[dependencies] | ||
failure = "~0.1.0" | ||
yara-sys = { path = "yara-sys" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
use std::fmt; | ||
use std::str::Utf8Error; | ||
|
||
use failure::{Context, Backtrace, Fail}; | ||
|
||
use yara_sys::{ERROR_INSUFFICIENT_MEMORY, ERROR_SCAN_TIMEOUT, ERROR_SUCCESS}; | ||
|
||
#[derive(Debug)] | ||
pub struct Error { | ||
inner: Context<ErrorKind>, | ||
} | ||
|
||
impl Error { | ||
pub fn kind(&self) -> ErrorKind { | ||
*self.inner.get_context() | ||
} | ||
} | ||
|
||
impl fmt::Display for Error { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
self.inner.fmt(f) | ||
} | ||
} | ||
|
||
impl Fail for Error { | ||
fn cause(&self) -> Option<&Fail> { | ||
self.inner.cause() | ||
} | ||
|
||
fn backtrace(&self) -> Option<&Backtrace> { | ||
self.inner.backtrace() | ||
} | ||
} | ||
|
||
#[derive(Clone, Copy, Debug, Fail, Eq, PartialEq)] | ||
pub enum ErrorKind { | ||
#[fail(display = "Utf8 error: {:?}", _0)] | ||
Utf8(#[cause] Utf8Error), | ||
#[fail(display = "{}", _0)] | ||
Yara(#[cause] YaraError), | ||
} | ||
|
||
impl From<Context<ErrorKind>> for Error { | ||
fn from(ctx: Context<ErrorKind>) -> Error { | ||
Error { inner: ctx } | ||
} | ||
} | ||
|
||
impl From<ErrorKind> for Error { | ||
fn from(kind: ErrorKind) -> Error { | ||
Error { inner: Context::new(kind) } | ||
} | ||
} | ||
|
||
pub type YaraError = YaraErrorKind; | ||
|
||
impl From<YaraError> for Error { | ||
fn from(error: YaraError) -> Error { | ||
ErrorKind::Yara(error).into() | ||
} | ||
} | ||
|
||
#[derive(Clone, Copy, Debug, Fail, Eq, PartialEq)] | ||
#[fail(display = "Error(s) during rule compilation.")] | ||
pub struct CompilationError(); | ||
|
||
#[derive(Clone, Copy, Debug, Fail, Eq, PartialEq)] | ||
pub enum YaraErrorKind { | ||
#[fail(display = "Insufficient memory to complete the operation.")] | ||
InsufficientMemory, | ||
#[fail(display = "Timeouted during scan.")] | ||
ScanTimeout, | ||
#[fail(display = "Unknown Yara error: {}", _0)] | ||
Unknown(u32), | ||
} | ||
|
||
impl YaraErrorKind { | ||
pub(crate) fn from_yara(code: i32) -> Result<(), YaraErrorKind> { | ||
let code = code as u32; | ||
use self::YaraErrorKind::*; | ||
|
||
match code { | ||
ERROR_SUCCESS => Ok(()), | ||
ERROR_INSUFFICIENT_MEMORY => Err(InsufficientMemory), | ||
ERROR_SCAN_TIMEOUT => Err(ScanTimeout), | ||
_ => Err(Unknown(code)), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub use yara_sys::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
use std::ffi; | ||
use std::ptr; | ||
|
||
use yara_sys; | ||
|
||
use errors::*; | ||
|
||
use super::{Compiler, Rules}; | ||
|
||
pub fn compiler_create() -> Result<*mut Compiler, YaraError> { | ||
let mut pointer: *mut Compiler = ptr::null_mut(); | ||
let result = unsafe { yara_sys::yr_compiler_create(&mut pointer) }; | ||
|
||
YaraErrorKind::from_yara(result).map(|()| pointer) | ||
} | ||
|
||
pub fn compiler_destroy(compiler_ptr: *mut Compiler) { | ||
unsafe { | ||
yara_sys::yr_compiler_destroy(compiler_ptr); | ||
} | ||
} | ||
|
||
pub fn compiler_add_string( | ||
compiler_ptr: *mut Compiler, | ||
string: &str, | ||
namespace: Option<&str>, | ||
) -> Result<(), CompilationError> { | ||
let string = ffi::CString::new(string).unwrap(); | ||
let namespace = namespace.map(|n| ffi::CString::new(n).unwrap()); | ||
let result = unsafe { | ||
yara_sys::yr_compiler_add_string( | ||
compiler_ptr, | ||
string.as_ptr(), | ||
namespace.as_ref().map_or(ptr::null(), |s| s.as_ptr()), | ||
) | ||
}; | ||
|
||
// TODO Add callbacks to get better errors | ||
if result == 0 { | ||
Ok(()) | ||
} else { | ||
Err(CompilationError()) | ||
} | ||
} | ||
|
||
pub fn compiler_get_rules(compiler_ptr: *mut Compiler) -> Result<*mut Rules, YaraError> { | ||
let mut pointer = ptr::null_mut(); | ||
let result = unsafe { yara_sys::yr_compiler_get_rules(compiler_ptr, &mut pointer) }; | ||
|
||
YaraErrorKind::from_yara(result).map(|()| pointer) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
mod compiler; | ||
mod rules; | ||
mod scan; | ||
|
||
pub use self::compiler::*; | ||
pub use self::rules::*; | ||
pub use self::scan::*; | ||
|
||
use yara_sys; | ||
|
||
use errors::*; | ||
|
||
pub type Compiler = yara_sys::YR_COMPILER; | ||
pub type Rule = yara_sys::YR_RULE; | ||
pub type Rules = yara_sys::YR_RULES; | ||
|
||
/// Initialize the Yara library | ||
/// | ||
/// Can be called multiple times without problems | ||
pub fn initialize() -> Result<(), YaraError> { | ||
let result = unsafe { yara_sys::yr_initialize() }; | ||
|
||
YaraErrorKind::from_yara(result) | ||
} | ||
|
||
/// De-initialize the Yara library | ||
/// | ||
/// Must not be called more time than [`initialize`]. | ||
pub fn finalize() -> Result<(), YaraError> { | ||
let result = unsafe { yara_sys::yr_finalize() }; | ||
|
||
YaraErrorKind::from_yara(result) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use std::ffi; | ||
|
||
use yara_sys; | ||
|
||
use errors::*; | ||
|
||
use super::Rules; | ||
|
||
pub fn rules_destroy(rules: *mut Rules) { | ||
unsafe { | ||
yara_sys::yr_rules_destroy(rules); | ||
} | ||
} | ||
|
||
// TODO Check if non mut | ||
pub fn rules_save(rules: *mut Rules, filename: &str) -> Result<(), YaraError> { | ||
let filename = ffi::CString::new(filename).unwrap(); | ||
let result = unsafe { yara_sys::yr_rules_save(rules, filename.as_ptr()) }; | ||
|
||
YaraErrorKind::from_yara(result) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
use std::ffi::CStr; | ||
use std::fs::File; | ||
use std::mem; | ||
use std::os::raw; | ||
|
||
use yara_sys; | ||
|
||
use super::{Rule, Rules}; | ||
|
||
use errors::*; | ||
|
||
#[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||
enum CallbackMsg { | ||
RuleMatching, | ||
RuleNotMatching, | ||
ScanFinished, | ||
ImportModule, | ||
ModuleImported, | ||
UnknownMsg, | ||
} | ||
|
||
impl CallbackMsg { | ||
pub fn from_yara(code: i32) -> Self { | ||
use self::CallbackMsg::*; | ||
let code = code as u32; | ||
|
||
match code { | ||
yara_sys::CALLBACK_MSG_RULE_MATCHING => RuleMatching, | ||
yara_sys::CALLBACK_MSG_RULE_NOT_MATCHING => RuleNotMatching, | ||
yara_sys::CALLBACK_MSG_SCAN_FINISHED => ScanFinished, | ||
yara_sys::CALLBACK_MSG_IMPORT_MODULE => ImportModule, | ||
yara_sys::CALLBACK_MSG_MODULE_IMPORTED => ModuleImported, | ||
_ => UnknownMsg, | ||
} | ||
} | ||
} | ||
|
||
#[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||
enum CallbackReturn { | ||
Continue, | ||
Abort, | ||
Error, | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct Match { | ||
|
||
} | ||
|
||
impl CallbackReturn { | ||
pub fn to_yara(&self) -> i32 { | ||
use self::CallbackReturn::*; | ||
|
||
let res = match self { | ||
Continue => yara_sys::CALLBACK_CONTINUE, | ||
Abort => yara_sys::CALLBACK_ABORT, | ||
Error => yara_sys::CALLBACK_ERROR, | ||
}; | ||
res as i32 | ||
} | ||
} | ||
|
||
#[derive(Default)] | ||
struct ScanResults { | ||
matches: Vec<()>, | ||
} | ||
|
||
pub fn rules_scan_mem(rules: *mut Rules, mem: &[u8], timeout: i32) -> Result<(), YaraError> { | ||
let mut results = Ok(ScanResults::default()); | ||
let result = unsafe { | ||
yara_sys::yr_rules_scan_mem( | ||
rules, | ||
mem.as_ptr(), | ||
mem.len(), | ||
0, | ||
Some(scan_callback), | ||
mem::transmute(&mut results), | ||
timeout, | ||
) | ||
}; | ||
YaraErrorKind::from_yara(result).map_err(|e| e.into()) | ||
.and(results) | ||
.map(|_| ()) // TODO Change | ||
} | ||
|
||
#[cfg(unix)] | ||
pub fn rules_scan_fd(rules: *mut Rules, file: File, timeout: i32) -> Result<(), Error> { | ||
use std::os::unix::io::AsRawFd; | ||
|
||
let mut results = Ok(ScanResults::default()); | ||
let fd = file.as_raw_fd(); | ||
let result = unsafe { | ||
yara_sys::yr_rules_scan_fd( | ||
rules, | ||
fd, | ||
0, | ||
Some(scan_callback), | ||
mem::transmute(&mut results), | ||
timeout, | ||
) | ||
}; | ||
YaraErrorKind::from_yara(result).map_err(|e| e.into()) | ||
.and(results) | ||
.map(|_| ()) // TODO Change | ||
} | ||
|
||
extern "C" fn scan_callback( | ||
message: raw::c_int, | ||
message_data: *mut raw::c_void, | ||
user_data: *mut raw::c_void, | ||
) -> i32 { | ||
let results: &mut Result<ScanResults, Error> = unsafe { mem::transmute(user_data) }; | ||
let message = CallbackMsg::from_yara(message); | ||
|
||
if message == CallbackMsg::RuleMatching { | ||
let rule: &Rule = unsafe { mem::transmute(message_data) }; | ||
let truc = unsafe { CStr::from_ptr(rule.__bindgen_anon_1.identifier) }; | ||
} | ||
|
||
CallbackReturn::Continue.to_yara() | ||
} |
Oops, something went wrong.