私はバイナリAを持っています。これは、何年も前にビルドされたシンボルを伴うデバッグビルドです。私はバイナリBも持っています。これは、シンボルを伴わないリリースビルドであり、はるかに最近のものです。バイナリAのシンボルをバイナリBの潜在的な候補に一致させる最も効率的な方法を探しています。
デバッグ ビルドがかなり大きく (より多くの入力検証を行い、より多くのものを に出力するstderr
など)、関数は常に時間の経過とともに変化することを考えると、個々の関数をフィンガープリントしようとすると時間が無駄になると思います。
したがって、私は決定しました - 非常に何もないので、間違ったツリーを吠えている可能性があります - 関数をフィンガープリントする最良の方法は、両方のバイナリの呼び出しグラフを作成し、頂点を一致させることです (つまり、機能)。
すでにいくつかの前処理を行っているため、次のデータ構造があります。
# binary A
[[60, 60, 8734], # function 0 is called by functions 60 (twice) and 8734
[193, 441, 505], # function 1 is called by functions 193, 441 and 505
[193, 742],
[23],
[21],
[21],
[26],
[26, 1508, 1509, 1573],
[24],
[25],
...] # (~10k functions)
# binary B
[[8999], # function 0 is called by function 8999
[9016], # function 1 is called by function 9016
[1126],
[7904, 7904, 7913],
[182, 336, 396, 396],
[9010],
[407],
[182, 632],
[20],
[24],
...] # (~10k functions)
重要な注意点は、バイナリA の関数 "0" とバイナリBの関数 "0" の間に対応がないことです。これらは、各バイナリの各関数に割り当てた任意の ID です。
次のステップは、私を混乱させるものです。私のアルゴリズム フーは非常に弱く、先に進む賢い方法が思い浮かびません。私の(非常に限られた)理解は、これを解決するために、何らかの形式の不正確なグラフマッチングを採用したいということです。言い換えれば、どのマッピング Ai -> Bi が 2 つのコールグラフの類似性を最大化するでしょうか?
バイナリAには追加のデバッグ機能があり、プログラムが時間の経過とともに進化するという明らかな事実を考えると、完全に一致するものはおそらくありません。理想的には、次の形式の出力が必要です。
[[(37, 0.998), (8432, 0.912), (442, 0.75)], # matching-ness of function "0" in binary A with function "37" in binary B is 0.998, second most likely candidate is function "8432" in binary B with score 0.912, etc.
[(42, 0.973), (7751, 0.788)], # matching-ness of function "1" in binary A with function "42" in binary B is 0.973, second most likely candidate is function "7751" in binary B with score 0.788, etc.
[(4579, 0.996), (123, 0.934)],
...] # around ~10k mappings
現実的には、候補が1つだけでランキングが出なくてもよかったのですが、夢は叶います。
SO-goers は、私がどこから始めるべきかについて考えを持っていますか?