diff --git a/docs/modules/pe.rst b/docs/modules/pe.rst index b6e6f5f23d..a17bad8139 100644 --- a/docs/modules/pe.rst +++ b/docs/modules/pe.rst @@ -506,3 +506,13 @@ Reference *Example: pe.section_index(pe.entry_point)* +.. c:function:: rich_version(version) + + .. versionadded:: 3.5.0 + + Function returning true if the PE has the specified *version* in the PE's rich + signature. More information can be found here: + + http://www.ntcore.com/files/richsign.htm + + *Example: pe.rich_version(21005)* diff --git a/libyara/include/yara/pe.h b/libyara/include/yara/pe.h index 2316cc4c88..5b16eaecce 100644 --- a/libyara/include/yara/pe.h +++ b/libyara/include/yara/pe.h @@ -448,11 +448,20 @@ typedef struct _WIN_CERTIFICATE { // http://www.ntcore.com/files/richsign.htm // +#define RICH_VERSION_ID(id_version) (id_version >> 16) +#define RICH_VERSION_VERSION(id_version) (id_version & 0xFFFF) + +typedef struct _RICH_VERSION_INFO { + DWORD id_version; //tool id and version (use RICH_VERSION_ID and RICH_VERSION_VERSION macros) + DWORD times; //number of times this tool was used +} RICH_VERSION_INFO, *PRICH_VERSION_INFO; + typedef struct _RICH_SIGNATURE { DWORD dans; DWORD key1; DWORD key2; DWORD key3; + RICH_VERSION_INFO versions[0]; } RICH_SIGNATURE, *PRICH_SIGNATURE; #define RICH_DANS 0x536e6144 // "DanS" diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c index 69b6684a2e..a40285b980 100644 --- a/libyara/modules/pe.c +++ b/libyara/modules/pe.c @@ -1814,6 +1814,44 @@ define_function(language) return_integer(0); } +define_function(rich_version) +{ + YR_OBJECT* module = module(); + PE* pe = (PE*)module->data; + uint64_t version = integer_argument(1); + size_t rich_len; + PRICH_SIGNATURE clear_rich_signature; + SIZED_STRING* rich_string; + int i; + + // Check if the required fields are set + if (is_undefined(module, "rich_signature.length")) + return_integer(UNDEFINED); + + // If not a PE file, return UNDEFINED + if (pe == NULL) + return_integer(UNDEFINED); + + rich_len = get_integer(module, "rich_signature.length"); + rich_string = get_string(module, "rich_signature.clear_data"); + + // If the clear_data was not set, return UNDEFINED + if (rich_string == NULL) + return_integer(UNDEFINED); + + clear_rich_signature = (PRICH_SIGNATURE)rich_string->c_string; + + // Loop over the versions in the rich signature + for (i = 0; + i < (rich_len - sizeof(RICH_SIGNATURE)) / sizeof(RICH_VERSION_INFO); + i++) + { + if(version == RICH_VERSION_VERSION(clear_rich_signature->versions[i].id_version)) + return_integer(1); + } + + return_integer(0); +} begin_declarations; @@ -1961,6 +1999,7 @@ begin_declarations; declare_function("imports", "s", "i", imports_dll); declare_function("locale", "i", "i", locale); declare_function("language", "i", "i", language); + declare_function("rich_version", "i", "i", rich_version); declare_integer("resource_timestamp") begin_struct("resource_version");