我一直在使用vb.net开发防病毒软件。病毒扫描程序工作正常,但我正在考虑优化扫描速度的方法(因为大文件会永久占用)。
我用于检测病毒的算法是通过二进制(转换为十六进制)签名。我想我不必四处寻找整个文件是否只是病毒,我认为应该扫描而不是扫描整个文件有一个特定的位置和特定的字节数。无论如何,如果有人可以提供有关此主题的任何帮助,请这样做。
提前感谢。
顺便说一句,病毒签名来自clamAv防病毒软件的hex集合...
这一切取决于,病毒签名的定义是什么?我建议您解析可执行文件并仅使用code-section。但是多态病毒以加密形式将恶意代码保留在数据部分中。所以我不太确定。您是否正在使用某种n-gram技术?还是只挖掘频繁的十六进制代码?扫描时间是非常重要的问题!一旦我编写了一个命令行更清晰的文件,就可以在不到一秒钟的时间内找到一个文件-在几秒钟内感染大量文件。该技术是frequent opcode mining.
是的,防病毒可以通过保护Internet威胁来优化设备的速度。 Kaspersky antivirus是主题之一
也许您的模式扫描效率低下。我可以使用这样的代码在大约1/20秒的时间内扫描7 MB文件中的模式。请注意,如果您确实要使用这样的代码,则必须进行更正。当您意识到自己不在寻找匹配项时,不能始终将MatchedLength设置回0,但是它确实适用于此特定模式。您必须对模式进行预处理,以便在找不到匹配项时知道将其重置为什么,但这不会为算法增加大量时间。我可以努力正确地完成算法,但是如果您的问题只涉及性能,我现在就不做。我只是说明,如果正确执行,可以快速扫描大型文件。
Sub Main(ByVal args As String())
If args.Length < 1 Then Return
Dim startTime As Long = Stopwatch.GetTimestamp()
Dim pattern As Byte()
pattern = System.Text.Encoding.UTF8.GetBytes("SFMB")
Dim bufferSize As Integer = 4096
Using reader As New System.IO.FileStream(args(0), IO.FileMode.Open, _
Security.AccessControl.FileSystemRights.Read, IO.FileShare.Read, bufferSize, IO.FileOptions.SequentialScan)
Dim buffer(bufferSize - 1) As Byte
Dim readLength = reader.Read(buffer, 0, bufferSize)
Dim matchedLength As Integer = 0
Dim searchPos As Integer = 0
Dim fileOffset As Integer = 0
Do While readLength > 0
For searchPos = 0 To readLength - 1
If pattern(matchedLength) = buffer(searchPos) Then
matchedLength += 1
Else
matchedLength = 0
End If
If matchedLength = pattern.Length Then
Console.WriteLine("Found pattern at position {0}", fileOffset + searchPos - matchedLength + 1)
matchedLength = 0
End If
Next
fileOffset += readLength
readLength = reader.Read(buffer, 0, bufferSize)
Loop
End Using
Dim endTime As Long = Stopwatch.GetTimestamp()
Console.WriteLine("Search took {0} seconds", (endTime - startTime) / Stopwatch.Frequency)
End Sub
有关如何同时匹配多个模式的一些想法。这只是我的脑袋,我还没有尝试编译代码:
创建一个类以包含有关模式状态的信息:
Class PatternInfo
Public pattern As Byte()
Public matchedBytes As integer
End Class
声明一个变量以跟踪您需要检查的所有模式,并通过模式的第一个字节为它们建立索引以进行快速查找:
Dim patternIndex As Dictionary(Of Byte, IEnumerable(Of PatternInfo))
检查当前可能匹配的所有模式,以查看下一个字节是否也匹配这些模式;如果没有,请停止在该位置查看该模式:
Dim activePatterns As New LinkedList(Of PatternInfo)
Dim newPatterns As IEnumerable(Of PatternInfo)
For Each activePattern in activePatterns.ToArray
If activePattern.pattern(matchedBytes) = buffer(searchPos) Then
activePattern.matchedBytes += 1
If activePattern.matchedBytes >= activePattern.pattern.Length Then
Console.WriteLine("Found pattern at position {0}", searchPos - matchedBytes + 1)
End If
Else
activePatterns.Remove(activePattern)
End If
Next
查看当前字节是否看起来像您要搜索的新模式的开头;如果是这样,请将其添加到活动模式列表中:
If patternIndex.TryGetValue(buffer(searchPos), newPatterns) Then
For Each newPattern in newPatterns
activePatterns.Add(New PatternInfo() With { _
.pattern = newPattern.pattern, .matchedBytes = 1 }
Next
End If