PE rich signature improvements (#1135)

* rich_internal function now returns the sum of counts
of the matching rich entries instead of a boolean

It remains backwards compatible thanks to non-null values being
considered as true and when not found it returns 0 (false).

* Update documentation of the `toolid` and `version` in PE module
to reflect changes of behavior: it now returns the sum of counts matching
to given `toolid` and `version`.

* Added test for the updated rich_signature function
This commit is contained in:
Marc-Etienne M.Léveillé
2019-09-23 12:49:22 +02:00
committed by Victor M. Alvarez
parent ce470b7bd4
commit e68eff9868
3 changed files with 33 additions and 25 deletions
+16 -8
View File
@@ -792,25 +792,33 @@ Reference
.. versionadded:: 3.5.0
Function returning true if the PE has the specified *version* in the PE's rich
signature. Provide the optional *toolid* argument to only match when both match
for one entry. More information can be found here:
Function returning a sum of count values of all matching *version*
records. Provide the optional *toolid* argument to only match when both
match for one entry. More information can be found here:
http://www.ntcore.com/files/richsign.htm
*Example: pe.rich_signature.version(21005)*
Note: Prior to version *3.11.0*, this function returns only a boolean
value (0 or 1) if the given *version* and optional *toolid* is present
in an entry.
*Example: pe.rich_signature.version(24215, 261) == 61*
.. c:function:: toolid(toolid, [version])
.. versionadded:: 3.5.0
Function returning true if the PE has the specified *id* in the PE's rich
signature. Provide the optional *version* argument to only match when both
match for one entry. More information can be found here:
Function returning a sum of count values of all matching *toolid*
records. Provide the optional *version* argument to only match when
both match for one entry. More information can be found here:
http://www.ntcore.com/files/richsign.htm
*Example: pe.rich_signature.toolid(222)*
Note: Prior to version *3.11.0*, this function returns only a boolean
value (0 or 1) if the given *toolid* and optional *version* is present
in an entry.
*Example: pe.rich_signature.toolid(170, 40219) >= 99 and pe.rich_signature.toolid(170, 40219) <= 143*
.. c:function:: exports(function_name)
+6 -17
View File
@@ -2220,6 +2220,8 @@ static uint64_t rich_internal(
rich_count = \
(rich_length - sizeof(RICH_SIGNATURE)) / sizeof(RICH_VERSION_INFO);
uint64_t count_sum = 0;
for (i = 0; i < rich_count; i++)
{
DWORD id_version = yr_le32toh(clear_rich_signature->versions[i].id_version);
@@ -2227,27 +2229,14 @@ static uint64_t rich_internal(
int match_version = (version == RICH_VERSION_VERSION(id_version));
int match_toolid = (toolid == RICH_VERSION_ID(id_version));
if (version != UNDEFINED && toolid != UNDEFINED)
if ((version == UNDEFINED || match_version) &&
(toolid == UNDEFINED || match_toolid))
{
// check version and toolid
if (match_version && match_toolid)
return true;
}
else if (version != UNDEFINED)
{
// check only version
if (match_version)
return true;
}
else if (toolid != UNDEFINED)
{
// check only toolid
if (match_toolid)
return true;
count_sum += yr_le32toh(clear_rich_signature->versions[i].times);
}
}
return false;
return count_sum;
}
+11
View File
@@ -207,6 +207,17 @@ int main(int argc, char** argv)
}",
"tests/data/tiny-idata-51ff");
assert_true_rule_file(
"import \"pe\" \
rule test { \
condition: \
pe.rich_signature.toolid(157, 40219) == 1 and \
pe.rich_signature.toolid(1, 0) > 40 and pe.rich_signature.toolid(1, 0) < 45 and \
pe.rich_signature.version(30319) and \
pe.rich_signature.version(40219, 170) == 11 \
}",
"tests/data/079a472d22290a94ebb212aa8015cdc8dd28a968c6b4d3b88acdd58ce2d3b885");
yr_finalize();
return 0;
}