在两个二进制文件中查找匹配序列

时间:2020-03-06 14:35:05  来源:igfitidea点击:

让我从一些背景开始。

今天早上,我们的一位用户报告说,Testuff的安装文件已被CA防病毒软件感染了病毒。我确信这是一个误报,因此我在网上查看了发现另一个程序(SpyBot)的用户也报告了相同的问题。

现在,对于实际问题。

假设防病毒软件正在文件中寻找特定的二进制签名,我想在两个文件中找到匹配的序列,并希望找到一种方法来调整设置脚本以防止该序列出现。

我在Python中尝试了以下方法,但是它已经运行了很长时间了,我想知道是否有更好或者更快的方法。

from difflib import SequenceMatcher

spybot = open("spybotsd160.exe", "rb").read()
testuff = open("TestuffSetup.exe", "rb").read()

s = SequenceMatcher(None, spybot, testuff)
print s.find_longest_match(0, len(spybot), 0, len(testuff))

是否有更好的Python库或者其他可以做到这一点的语言?
也欢迎使用完全不同的方法来解决该问题。

解决方案

我们为什么不联系CA并要求他们告诉他们他们正在寻找该病毒的内容?

或者,我们可以复制文件并更改每个字节,直到警告消失(取决于大小,可能要花一些时间)。

病毒检测可能比单纯查找固定字符串复杂得多。

最好不要怀疑这些算法所需的复杂性和时间。

如果我们对此处链接的.ps文档感兴趣,则可以找到对该主题的很好介绍。

如果存在这些算法的良好实现,我就无法判断。

请参阅最长的常见子字符串问题。我想difflib使用DP解决方案,这肯定太慢了,无法比较可执行文件。使用后缀树/数组可以做得更好。

使用perl Tree :: Suffix可能是最简单的解决方案。显然,它给出了指定长度范围内的所有常见子字符串:

@lcs = $tree->lcs;
@lcs = $tree->lcs($min_len, $max_len);
@lcs = $tree->longest_common_substrings;

请注意,即使我们确实是这样找到的,也无法保证最长的匹配实际上就是所寻找的匹配。相反,我们可能会发现例如同一编译器添加的通用初始化代码或者字符串表。

我怀疑寻找二进制字符串不会对我们有帮助。安装程序可能正在做一些"可疑"的事情。

我们可能需要与CA和spybot讨论将安装程序列入白名单或者触发警报的原因。