Function names
In some binaries, it is possible that the name of a library function used in the source code result in a different symbol name being added to the binary. This depends on many factors such as aliasing and weak symbols, but it’s important to consider it when writing rules because you might find a binary that usesmemcmp, while another sample of the same software component, even matching the same version, uses bcmp, which is an alias for memcmp in glibc. Also, decompilers might add a prefix or suffix to the symbol name when applying their own logic to identify functions. For example, an imp. prefix means the function is external to the binary and it is therefore imported.
To illustrate such situation, suppose you have three different samples of the same software component, where:
- Sample A uses
memcmp. - Sample B uses
bcmp. - Sample C uses
bcmp, but the decompiler showsimp.bcmpinstead (a prefix was added).
scope:project. You could, of course, try this:
memcmp or bcmp, with or without the imp. prefix.
Inlined functions
Functions are often inlined by the compiler, meaning the function call is replaced by its code. For example, consider the following code:worker function should be similar to this:
small_work’s code might replace its call within worker. If small_work is the function of interest, the above rule would break, as small_work would no longer be available:
One might feel tempted to useproject:functions({matching = "small_work|worker"}), but this would introduce a bug in the rule, since the matching order is not guaranteed. This method could return theworkerfunction even whensmall_workhas not been inlined, which would be a bug in the rule logic.
Arrays indexing convention
In Lua, arrays are a particular use of tables. By convention, they are 1-based.nil) can be used as keys, effectively creating associative arrays:
Table emptiness
A reference to an empty table evaluates totrue:
next() function: