Оптимизация скорости антивирусного сканирования - PullRequest
1 голос
/ 15 марта 2011

Я занимаюсь разработкой антивируса с использованием vb.net. Антивирусный сканер работает нормально, но я думал о способах оптимизации скорости сканирования (потому что большие файлы занимают вечность).

Алгоритм, который я использую для обнаружения вирусов, - через двоичные (преобразованные в шестнадцатеричные) подписи. Я думаю, что мне не нужно просматривать весь файл, чтобы найти вирус или нет, я думаю, что есть определенное место и определенное количество байтов, которые я должен сканировать вместо сканирования всего файла. В любом случае, если кто-то может оказать какую-либо помощь в этом вопросе, сделайте это.

Заранее спасибо.

Кстати, вирусные сигнатуры происходят из шестнадцатеричной коллекции антивируса clamAv ...

Ответы [ 2 ]

1 голос
/ 06 октября 2012

Ну, все зависит, каково определение сигнатуры вируса?
Предлагаю вам разобрать исполняемый файл и использовать только code-section .
Но полиморфный вирус хранит там вредоносный код в разделе данных в зашифрованном виде. Так что я не очень уверен.
Вы используете какую-то технику n-граммы? Или просто майнинг частых шестнадцатеричных кодов?
Время сканирования - очень важная проблема!
После того, как я написал saner для командной строки, он смог найти файл менее чем за секунду - за тонну файлов за секунды.
Техника была frequent opcode mining.

0 голосов
/ 16 марта 2011

Возможно, ваше сканирование шаблона неэффективно. Я могу сканировать шаблон в файле размером 7 МБ примерно за 1/20 секунды, используя такой код. Обратите внимание: если вы действительно хотите использовать подобный код, вы должны внести исправление. Вы не всегда можете установить 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

EDIT

Вот некоторые мысли о том, как вы можете сопоставить несколько шаблонов одновременно. Это не в моей голове, и я не пытался скомпилировать код:

Создайте класс, который будет содержать информацию о состоянии шаблона:

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
...