From 4f1337dae103dcc159667f1fada37a76e455d0a8 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Tue, 21 Nov 2023 10:54:39 +0100 Subject: [PATCH] feat: implement `locale` and `language` function in PE module --- yara-x/src/modules/pe/mod.rs | 35 ++++++++++++++++++++++++++++++ yara-x/src/modules/pe/tests/mod.rs | 29 +++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/yara-x/src/modules/pe/mod.rs b/yara-x/src/modules/pe/mod.rs index 61b5c113c..73ac8eb0f 100644 --- a/yara-x/src/modules/pe/mod.rs +++ b/yara-x/src/modules/pe/mod.rs @@ -505,6 +505,41 @@ fn exports_index_regexp( } } +/// Returns true if the PE contains some resource with the specified locale +/// identifier. +/// +/// Locale identifiers are 16-bit integers and can be found here: +/// https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/available-language-packs-for-windows?view=windows-11 +#[module_export] +fn locale(ctx: &ScanContext, loc: i64) -> Option { + let pe = ctx.module_output::()?; + let loc: u32 = match loc.try_into() { + Ok(lang) => lang, + Err(_) => return Some(false), + }; + Some(pe.resources.iter().any(|resource| { + resource.language.is_some_and(|rsrc_lang| rsrc_lang & 0xffff == loc) + })) +} + +/// Returns true if the PE contains some resource with the specified language +/// identifier. +/// +/// Language identifiers are the lowest 8-bit of locale identifiers and can +/// be found here: +/// https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/available-language-packs-for-windows?view=windows-11 +#[module_export] +fn language(ctx: &ScanContext, lang: i64) -> Option { + let pe = ctx.module_output::()?; + let lang: u32 = match lang.try_into() { + Ok(lang) => lang, + Err(_) => return Some(false), + }; + Some(pe.resources.iter().any(|resource| { + resource.language.is_some_and(|rsrc_lang| rsrc_lang & 0xff == lang) + })) +} + enum MatchCriteria<'a> { Any, Regexp(RegexpId), diff --git a/yara-x/src/modules/pe/tests/mod.rs b/yara-x/src/modules/pe/tests/mod.rs index de4cab318..401d0c008 100644 --- a/yara-x/src/modules/pe/tests/mod.rs +++ b/yara-x/src/modules/pe/tests/mod.rs @@ -309,3 +309,32 @@ fn checksum() { &pe ); } + +#[test] +fn locale_and_language() { + let pe = create_binary_from_zipped_ihex( + "src/modules/pe/tests/testdata/db6a9934570fa98a93a979e7e0e218e0c9710e5a787b18c6948f2eedd9338984.in.zip", + ); + + rule_true!( + r#" + import "pe" + rule test { + condition: + pe.language(0x09) // English + } + "#, + &pe + ); + + rule_true!( + r#" + import "pe" + rule test { + condition: + pe.locale(0x0409) // English US + } + "#, + &pe + ); +}