簡體   English   中英

簽名模式解析效率

[英]Signature Patterns Parsing Efficiency

我將二進制文件轉換為十六進制字符串,以在它們中搜索用戶提供的特定模式,就像防病毒軟件處理其特征庫一樣。 如果找到了模式,則它將返回true。

我面臨的一個困難是通配符和緩慢的掃描速度。 用戶擁有數千個模式,每個模式最多200個字符,甚至更多。

例如,此模式用於驗證文件是否在C ++下編譯,而“?” 字符是通配符(可以匹配任何一個字符):

55 8B EC 53 8B 5D 08 56 8B 75 0C 85 F6 57 8B 7D 10 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 01

與該模式相似的模式全部堆疊在一個長度不等的文件中,所以我想您已經大致了解了。

這是我正在使用的代碼(工作正常,但與僅在幾秒鍾內執行模式掃描的其他工具(例如ExeInfoPE或Die)相比,速度非常慢)

        static bool compare(string[] mask, byte[] buffer, int position)
    {
        var i = 0; // index
        foreach (string x in mask) // loop through the mask
        {
            if (x.Contains("?")) // is current mask position a wildcard?
            {
            }// if so skip comparison
            else if (byte.Parse(x, System.Globalization.NumberStyles.HexNumber) == buffer[position + i]) // else try to compare
            {
            }// succeeded, move onto next byte
            else
                return false; // failed, pattern not found
            ++i; // increment the index.
        }
        return true; // pattern was found
    }

關於如何在保持通配符支持的同時極大地提高速度以使我的工具可以在現實世界中使用的想法?

如果您要匹配多個文件,則應該將掩碼預轉換為byte?[] (或更簡單地說是byte[]加上bool[] isWildcard ,如果有通配符,則為true)。 byte.Parse(x, System.Globalization.NumberStyles.HexNumber)的工作原理是,如果您有1000個文件,將無用地重復1000次。

另一個問題... buffer有多大? 我確實希望您只能讀取每個文件中最多4kb的數據(甚至更少...您可以預先檢查所有掩碼,以查看哪個掩碼最大),並且不要讀取整個文件。

第二件事,您可以嘗試至少為模式的第一個字節為模式編制索引(但請記住,您必須處理以?開頭的模式的情況)。

一些隨機評論:

  • 尚不清楚您真正要做什么。 需要更多信息。 您需要掃描多少個文件? 1或2或很多(10 +,100 +?)?

  • 您的模式從文件中的固定位置開始,或者至少始終存在於文件的某個點(例如exe文件的MZ簽名,即文件的前兩個字符),或者它們可以在任何位置?
    許多程序“作弊”:它們不會加載整個文件。 他們裝載小塊。 例如,例如前4kb和后4kb。 他們“知道”他們的模式必須在那里。 因此,如果加載整個文件,肯定會變慢。

  • 模式的前幾個字節,如何統計分布? 例如,您有1000個模式,一個字節有256個可能的值。 模式的第一個字節平均分配給所有可能的值? 因此,平均而言,有4個模式以一個字節的每個可能值開頭(4個模式以“ A”開頭,4個以“ B”開頭等等),或者存在更多的字節(如果例如,有100個以'A'開頭的模式,因為在第一種情況下,可以按第一個字節索引模式,並快速選擇僅具有第一個字節的模式的小子集,在第二種情況下,則是第一個字節不足以選擇要檢查的模式子集的判別式。

通常,我將有兩種結構:

Dictionary<byte, List<Pattern>> PatternsByFirstByte

List<Pattern> PatternsWithFirstCharacterWildcard

這樣,對於每個字節,您必須從PatternsByFirstByte和所有PatternsByFirstByte檢查少量PatternsWithFirstCharacterWildcard 但是,如果第一個字節足夠有區別,這將起作用。 更高級的方法是創建一個完整的trie結構,以保留/索引模式,和/或以其他方式處理位置零(?? ?? xx yy)的通配符。 顯然,(?? ?? xx yy)等同於起始位置> = 2的(xx yy)。然后,您可以在字典中將模式xx yy放入注釋中,並在該位置必須為> = 2的位置添加注釋。 ,就像在Pattern類本身中那樣:

class Pattern
{
    public readonly byte?[] Bytes;
    public int MinimumStartingPosition;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM