[英]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。 他們“知道”他們的模式必須在那里。 因此,如果加載整個文件,肯定會變慢。
通常,我將有兩種結構:
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.