diff --git a/src/internals/mod.rs b/src/internals/mod.rs index a7fbc9c..c0230cd 100644 --- a/src/internals/mod.rs +++ b/src/internals/mod.rs @@ -6,6 +6,7 @@ use crate::errors::*; pub use self::compiler::*; pub use self::iterator::*; +pub use self::module_import::*; pub use self::object::*; pub use self::rules::*; pub use self::scan::*; @@ -17,6 +18,7 @@ pub mod string; mod compiler; pub mod configuration; mod iterator; +mod module_import; mod object; mod rules; mod scan; diff --git a/src/internals/module_import.rs b/src/internals/module_import.rs new file mode 100644 index 0000000..11b2551 --- /dev/null +++ b/src/internals/module_import.rs @@ -0,0 +1,45 @@ +use std::ffi::{c_void, CStr}; +use std::fmt::Debug; + +/// Details about a module being imported. +pub struct YrModuleImport<'a>(&'a mut yara_sys::YR_MODULE_IMPORT); + +impl Debug for YrModuleImport<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Debug::fmt("YrModuleImport", f) + } +} + +impl<'a> From<&'a mut yara_sys::YR_MODULE_IMPORT> for YrModuleImport<'a> { + fn from(value: &'a mut yara_sys::YR_MODULE_IMPORT) -> Self { + Self(value) + } +} + +impl YrModuleImport<'_> { + /// Get the name of the module. + pub fn name(&self) -> Option<&[u8]> { + let ptr = self.0.module_name; + if ptr.is_null() { + None + } else { + // Safety: + // - ptr is not null, and is guaranteed by libyara to be nul-terminated + // - returned slice is valid for as long as self, guaranteeing the ptr to stay valid. + let cstr = unsafe { CStr::from_ptr(ptr) }; + Some(cstr.to_bytes()) + } + } + + /// Set the module data to be used by the module. + /// + /// # Safety + /// + /// The caller must guarantee that: + /// - `ptr` is valid for reads of `size` bytes. + /// - `ptr` stays valid for the full duration of the scan. + pub unsafe fn set_module_data(&mut self, ptr: *mut c_void, size: usize) { + self.0.module_data = ptr; + self.0.module_data_size = size as _; + } +} diff --git a/src/internals/scan.rs b/src/internals/scan.rs index 5479fd9..a22881f 100644 --- a/src/internals/scan.rs +++ b/src/internals/scan.rs @@ -13,7 +13,7 @@ use crate::{Rule, YrString}; pub enum CallbackMsg<'r> { RuleMatching(Rule<'r>), RuleNotMatching(Rule<'r>), - ImportModule, + ImportModule(YrModuleImport<'r>), ModuleImported(YrObject<'r>), TooManyMatches(YrString<'r>), ScanFinished, @@ -40,7 +40,10 @@ impl<'r> CallbackMsg<'r> { let context = unsafe { &*context }; RuleNotMatching(Rule::from((context, rule))) } - yara_sys::CALLBACK_MSG_IMPORT_MODULE => ImportModule, + yara_sys::CALLBACK_MSG_IMPORT_MODULE => { + let object = unsafe { &mut *(message_data as *mut yara_sys::YR_MODULE_IMPORT) }; + ImportModule(YrModuleImport::from(object)) + } yara_sys::CALLBACK_MSG_MODULE_IMPORTED => { let object = unsafe { &*(message_data as *mut yara_sys::YR_OBJECT) }; ModuleImported(YrObject::from(object)) diff --git a/yara-sys/bindings/yara-4.5.0-x86_64-apple-darwin.rs b/yara-sys/bindings/yara-4.5.0-x86_64-apple-darwin.rs index 2f00fe1..7159823 100644 --- a/yara-sys/bindings/yara-4.5.0-x86_64-apple-darwin.rs +++ b/yara-sys/bindings/yara-4.5.0-x86_64-apple-darwin.rs @@ -5527,3 +5527,55 @@ extern "C" { rules: *mut *mut YR_RULES, ) -> ::std::os::raw::c_int; } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct YR_MODULE_IMPORT { + pub module_name: *const ::std::os::raw::c_char, + pub module_data: *mut ::std::os::raw::c_void, + pub module_data_size: size_t, +} +#[test] +fn bindgen_test_layout_YR_MODULE_IMPORT() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(YR_MODULE_IMPORT)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(YR_MODULE_IMPORT)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_name) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_name) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_data) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_data) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_data_size) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_data_size) + ) + ); +} diff --git a/yara-sys/bindings/yara-4.5.0-x86_64-pc-windows-gnu.rs b/yara-sys/bindings/yara-4.5.0-x86_64-pc-windows-gnu.rs index 3ab8299..902fa0d 100644 --- a/yara-sys/bindings/yara-4.5.0-x86_64-pc-windows-gnu.rs +++ b/yara-sys/bindings/yara-4.5.0-x86_64-pc-windows-gnu.rs @@ -8134,3 +8134,55 @@ extern "C" { rules: *mut *mut YR_RULES, ) -> ::std::os::raw::c_int; } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct YR_MODULE_IMPORT { + pub module_name: *const ::std::os::raw::c_char, + pub module_data: *mut ::std::os::raw::c_void, + pub module_data_size: size_t, +} +#[test] +fn bindgen_test_layout_YR_MODULE_IMPORT() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(YR_MODULE_IMPORT)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(YR_MODULE_IMPORT)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_name) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_name) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_data) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_data) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_data_size) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_data_size) + ) + ); +} diff --git a/yara-sys/bindings/yara-4.5.0-x86_64-pc-windows-msvc.rs b/yara-sys/bindings/yara-4.5.0-x86_64-pc-windows-msvc.rs index 3ab8299..902fa0d 100644 --- a/yara-sys/bindings/yara-4.5.0-x86_64-pc-windows-msvc.rs +++ b/yara-sys/bindings/yara-4.5.0-x86_64-pc-windows-msvc.rs @@ -8134,3 +8134,55 @@ extern "C" { rules: *mut *mut YR_RULES, ) -> ::std::os::raw::c_int; } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct YR_MODULE_IMPORT { + pub module_name: *const ::std::os::raw::c_char, + pub module_data: *mut ::std::os::raw::c_void, + pub module_data_size: size_t, +} +#[test] +fn bindgen_test_layout_YR_MODULE_IMPORT() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(YR_MODULE_IMPORT)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(YR_MODULE_IMPORT)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_name) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_name) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_data) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_data) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_data_size) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_data_size) + ) + ); +} diff --git a/yara-sys/bindings/yara-4.5.0-x86_64-unknown-linux-gnu.rs b/yara-sys/bindings/yara-4.5.0-x86_64-unknown-linux-gnu.rs index 51f1320..393e13b 100644 --- a/yara-sys/bindings/yara-4.5.0-x86_64-unknown-linux-gnu.rs +++ b/yara-sys/bindings/yara-4.5.0-x86_64-unknown-linux-gnu.rs @@ -5719,3 +5719,55 @@ extern "C" { rules: *mut *mut YR_RULES, ) -> ::std::os::raw::c_int; } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct YR_MODULE_IMPORT { + pub module_name: *const ::std::os::raw::c_char, + pub module_data: *mut ::std::os::raw::c_void, + pub module_data_size: size_t, +} +#[test] +fn bindgen_test_layout_YR_MODULE_IMPORT() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(YR_MODULE_IMPORT)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(YR_MODULE_IMPORT)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_name) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_name) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_data) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_data) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_data_size) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_data_size) + ) + ); +} diff --git a/yara-sys/bindings/yara-4.5.0-x86_64-unknown-linux-musl.rs b/yara-sys/bindings/yara-4.5.0-x86_64-unknown-linux-musl.rs index 51f1320..393e13b 100644 --- a/yara-sys/bindings/yara-4.5.0-x86_64-unknown-linux-musl.rs +++ b/yara-sys/bindings/yara-4.5.0-x86_64-unknown-linux-musl.rs @@ -5719,3 +5719,55 @@ extern "C" { rules: *mut *mut YR_RULES, ) -> ::std::os::raw::c_int; } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct YR_MODULE_IMPORT { + pub module_name: *const ::std::os::raw::c_char, + pub module_data: *mut ::std::os::raw::c_void, + pub module_data_size: size_t, +} +#[test] +fn bindgen_test_layout_YR_MODULE_IMPORT() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(YR_MODULE_IMPORT)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(YR_MODULE_IMPORT)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_name) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_name) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_data) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_data) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).module_data_size) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(YR_MODULE_IMPORT), + "::", + stringify!(module_data_size) + ) + ); +} diff --git a/yara-sys/build.rs b/yara-sys/build.rs index 709042a..cc025d1 100644 --- a/yara-sys/build.rs +++ b/yara-sys/build.rs @@ -431,6 +431,7 @@ mod bindings { .allowlist_type("YR_AC_AUTOMATON") .allowlist_type("YR_AC_MATCH") .allowlist_type("YR_ATOMS_CONFIG") + .allowlist_type("YR_MODULE_IMPORT") .opaque_type("YR_AC_.*") .opaque_type("YR_ATOMS_CONFIG") .opaque_type("YR_FIXUP")