Undefined values
Modules often leave variables in an undefined state, for example when the
variable doesn’t make sense in the current context (think of pe.entry_point
while scanning a non-PE file). YARA handles undefined values in a way that
allows the rule to keep its meaningfulness. Take a look at this rule:
import "pe"
rule Test {
strings:
$a = "some string"
condition:
$a and pe.entry_point == 0x1000
}If the scanned file isn’t a PE file, this rule won’t match even if “some string”
is present because both conditions (the string’s presence and the correct entry
point) must be met. However, consider the or case:
$a or pe.entry_point == 0x1000You would expect the rule to match if the file contains the string, even if it isn’t a PE file. That’s exactly how YARA behaves. The logic is as follows:
If the expression in the condition is undefined, it would be translated
to false and the rule won’t match.
Boolean operators and and or will treat undefined operands as false,
Which means that:
undefinedandtrueisfalseundefinedandfalseisfalseundefinedortrueistrueundefinedorfalseisfalse
All the remaining operators, including the not operator, return undefined if
any of their operands is undefined.
In the expression above, pe.entry_point == 0x1000 will be undefined for non-PE
files, because pe.entry_point is undefined for those files. This implies that
$a or pe.entry_point == 0x1000 will be true if and only if $a is true.
If the condition was pe.entry_point == 0x1000 alone, it evaluates to false
for non-PE files, and so will do pe.entry_point != 0x1000 and not pe.entry_point == 0x1000, as none of these expressions make sense for non-PE
files.
To check if some expression is defined use unary operator defined. Example:
defined pe.entry_point