在C#中搜索字符串中的部分子字符串

时间:2012-08-20 20:50:14

标签: c# string hex match partial

好的,所以我试图在C#中制作一个基本的恶意软件扫描程序,我的问题就是说我有一个特定位代码的Hex签名

例如

        {
            System.IO.File.Delete(@"C:\Users\Public\DeleteTest\test.txt");
        }

        //Which will have a hex of 53797374656d2e494f2e46696c652e44656c657465284022433a5c55736572735c5075626c69635c44656c657465546573745c746573742e74787422293b

获取更改为 -

        {
            System.IO.File.Delete(@"C:\Users\Public\DeleteTest\notatest.txt");
        }
//Which will have a hex of 53797374656d2e494f2e46696c652e44656c657465284022433a5c55736572735c5075626c69635c44656c657465546573745c6e6f7461746573742e74787422293b

请记住,这些位将在程序的整个十六进制内 - 我怎样才能获取我的基本签名并查找部分匹配,这些匹配表示匹配率为90%因此会被标记。

我会做一个通配符但是这对于稍微复杂的事情不起作用,因为它可能被编码略微不同但是大多数都是相同的。那么有没有办法可以为子字符串进行百分比匹配?我正在研究Levenshtein距离,但我不知道如何将它应用到这个给定的场景中。

提前感谢任何输入

3 个答案:

答案 0 :(得分:1)

使用编辑距离就可以了。您可以使用两个字符串并计算编辑距离,该距离将是一个整数值,表示将一个字符串带到另一个字符串所需的操作数。您可以根据该数字设置自己的阈值。

例如,您可以静态设置如果距离小于五次编辑,则更改是相关的。

您还可以使用您正在比较的字符串的长度并取一定百分比。您的示例长度为36个字符,因此(int)(input.Length * 0.88m)将是有效的threashold。

答案 1 :(得分:1)

首先,您的程序位应该完全匹配,否则它已被修改或损坏。通常,您将在原始二进制文件上存储MD5哈希,并根据新版本检查MD5以查看它们是否“足够相同”(MD5不能保证100%匹配)。

除此之外,为了检测随机二进制文件中的恶意软件,您必须知道要查找的模式类型。例如,如果我知道一件恶意软件使用一些二进制XYZ注入代码,我将在可执行文件的位中查找XYZ。当然,模式比这更复杂,因为恶意软件位可以在chuncks中展开。更有趣的是,一些病毒是自我变形的。这意味着每次运行时,它都会自行修改,这意味着扫描仪不知道要找到的确切模式。在这些情况下,扫描仪必须知道可以生成衍生物的类型并查找所有衍生物。

在查找%匹配方面,除非您有约束,否则此操作非常耗时。通过比较2个字符串,您无法分辨哪些部分被删除,添加或替换。例如,如果我有一个起始字符串'ABCD',那么'AABCDD'是100%匹配还是更少,因为添加了内容?怎么样'ABCDABCD';这里匹配两次。 'AXBXCXD'怎么样?那么'CDAB'呢?

现有许多DIFF工具可以告诉您文件的哪些部分已被更改(这可能导致%)。不幸的是,由于我上面描述的问题,它们都不是完美的。你会发现你有假阴性,误报等等。这对你来说可能“足够好”。

在您确定适合您的特定算法之前,您必须确定搜索的限制。否则,您的扫描将是NP难的,这会导致不合理的运行时间(您的扫描仪可能会整天运行以检查一个文件)。

答案 2 :(得分:0)

我建议你研究Levenshtein distanceDamerau-Levenshtein distance

前者告诉你需要多少次添加/删除操作才能将一个字符串转换为另一个字符串;后者告诉你需要多少次添加/删除/替换操作才能将一个字符串转换成另一个字符串。

在编写用户可以搜索内容的程序时,我会使用这些内容,但他们可能不知道确切的拼写。

这两篇文章都有代码示例。