Bindiff matching algorithm

I've started using bindiff recently and struggle to understand matching algorithm. I've read several articles like:

T. Dullien and R. Rolles. Graph-based comparison of executable objects, BinSlayer, Accurate Comparison of Binary Executables, and also bindiff manual https://www.zynamics.com/bindiff/manual/#chapUnderstanding question about bindiff

And all articles differs on explaining matching algorithm.

The thing that I can't understand is difference between functions signatures and functions attributes.

From manual:

The signature consists of:

• Number of codeblocks
• Number of edges between codeblocks
• Number of calls to subfunctions

Once the two sets of signatures (for the two executables) have been generated, initial matches are created. A match is created if a signature occurs once (and only once) in both examined subsets of signatures.

So the signature of functions are used to construct initial match. But after that article tells us about function attributes.

Attributes:

BinDiff has a list of function attributes (hash matching, name matching, etc.) suitable for generating matches. It starts on a global level, considering all functions of the binary and calculates the first attribute for every function. After the initial global matching step the parents (callers) and children (callees) of each new match are considered

So how the signatures differs from attributes? Both of them are used to construct initial matches. What strategy is first applied to construct initial match: signature matching or functions byte hash matching?

I've started using bindiff recently and struggle to understand matching algorithm.

(...)

So how the signatures differs from attributes?

I think you are confusing at least 3 things:

• There is not a single matching algorithm but a set of matching algorithms. Or heuristics, if you prefer.
• There is not a single function's signature, there are multiple different ones.
• A function signature is (most likely) considered a set of function's attributes as well as values calculated using various of its attributes.

Usually, a function attribute is a thing like the number of edges, nodes, the in-degree, out-degree, number of loops, etc... of a given function. A function signature can be a set of such attributes like, for example, a tuple of attributes such as [nodes, edges, in-degree, out-degree]. It can also be a calculation of various attributes like the MD-Index (that is calculated based on the topology of the graph and the degrees of each basic block) or the "functions byte hash" you mention, which is another type of function's signature.

What strategy is first applied to construct initial match: signature matching or functions byte hash matching?

First of all, remember that a "functions byte hash" is actually a function signature. Then, answering your question without knowing exactly how BinDiff works, I believe that they will use first the heuristics that cause the lesser number of false positives. A signature like "functions byte hash" for non trivial functions is likely going to generate near zero false positives so, instead of trying to initially match some attributes or use any false-positive prone signature, they most likely try that mentioned signature first.

DISCLAIMER: I'm not any of the authors of BinDiff neither I have reverse engineered it to know how it actually works. However, I'm the author of an open source alternative called Diaphora, and I know a bit how such a tool works.

The BinDiff algorithm is a matching algorithm that can be used to classify malware.It performs structural matching using a call graph or flow control chart. By default, three attributes are used for the matching function (number of edges between blocks in the functions, number of returns in the function and the number of basic blocks that make up the function). In other words, the signature is the characteristics (calculated attributes) of each function.

Pointing to the second question, the strategy that applies to build initial matches is basically finding unique blocks (signatures created by unique attributes).