1

vb.netを使用してウイルス対策を開発しています。ウイルス スキャナは正常に動作しますが、スキャン速度を最適化する方法を考えていました (大きなファイルは永遠にかかるため)。

ウイルスを検出するために私が使用しているアルゴリズムは、バイナリ (16 進数に変換された) 署名によるものです。ファイル全体をスキャンするのではなく、特定の場所と特定のバイト数をスキャンする必要があると思います。とにかく、誰かがこの主題について助けを提供できるなら、そうしてください.

前もって感謝します。

ところで、ウイルス シグネチャは、clamAv アンチウイルスの 16 進コレクションから取得されます...

4

2 に答える 2

1

まあそれはすべて依存します、ウイルス署名の定義は何ですか?
実行可能ファイルを解析し、code-sectionのみを使用することをお勧めします。
しかし、ポリモーフィック ウイルスは、暗号化された形式でデータ セクションに悪意のあるコードを保持します。ですから、よくわかりません。
ある種の n-gram 手法を使用していますか? それとも、頻繁に 16 進コードを採掘するだけですか?
スキャン時間は非常に重要な問題です。
コマンドラインの正気を書いたら、それは1秒もかからずにファイルを見つけることができました-数秒で大量のファイルに感染します。
テクニックはfrequent opcode mining.

于 2012-10-06T17:13:50.150 に答える
0

おそらく、パターン スキャンが非効率的です。このようなコードを使用すると、約 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
于 2011-03-16T13:00:07.460 に答える