Поиск ReadAllBytes для конкретных значений
Я пишу программу, которая читает файлы.exe и сохраняет их шестнадцатеричные значения в массиве байтов для сравнения с массивом, содержащим ряд значений. (как очень простой сканер вирусов)
byte[] buffer = File.ReadAllBytes(currentDirectoryContents[j]);
Затем я использовал BitConverter, чтобы создать одну строку из этих значений
string hex = BitConverter.ToString(buffer);
Следующим шагом является поиск в этой строке ряда значений (определений) и возврат положительного значения для совпадения. Здесь я сталкиваюсь с проблемами. Мои определения являются шестнадцатеричными значениями, но созданы и сохранены в блокноте как Defintions.xyz
string[] definitions = File.ReadAllLines(@"C:\definitions.xyz");
Я пытался прочитать их в массив строк и сравнить элементы определения массива со строкой hex
bool[] test = new bool[currentDirectoryContents.Length];
test[j] = hex.Contains(definitions[i]);
Это раздел из домашней работы, поэтому я не публикую весь код программы. Я не использовал C# до прошлой пятницы, поэтому я, скорее всего, делаю глупые ошибки на этом этапе.
Любой совет высоко ценится:)
2 ответа
Я ожидаю, что вы понимаете, что это очень неэффективный способ сделать это. Но кроме этого, вы должны просто сделать что-то вроде этого:
bool[] test = new bool[currentDirectoryContents.Length];
for(int i=0;i<test.Length;i++){
byte[] buffer = File.ReadAllBytes(currentDirectoryContents[j]);
string hex = BitConverter.ToString(buffer);
test[i] = ContainsAny(hex, definitions);
}
bool ContainsAny(string s, string[] values){
foreach(string value in values){
if(s.Contains(value){
return true;
}
}
return false;
}
Если вы можете использовать LINQ, вы можете сделать это так:
var test = currentDirectoryContents.Select(
file=>definitions.Any(
definition =>
BitConverter.ToString(
File.ReadAllBytes(file)
).Contains(definition)
)
).ToArray();
Кроме того, убедитесь, что ваш файл определений отформатирован так, чтобы соответствовать выводу BitConverter.ToString()
: верхний регистр с тире, разделяющими каждый закодированный байт:
12-AB-F0-34
54-AC-FF-01-02
Довольно непонятно, в каком именно формате вы используете определения. Base64 - хорошая кодировка для byte[], вы можете быстро конвертировать туда и обратно с помощью Convert.ToBase64String и Convert.FromBase64String(). Но ваш вопрос предполагает, что байты закодированы в шестнадцатеричном виде. Предположим, это выглядит как "01020304" для нового байта [] { 1, 2, 3, 4}. Затем эта вспомогательная функция преобразует такую строку обратно в byte[]:
static byte[] Hex2Bytes(string hex) {
if (hex.Length % 2 != 0) throw new ArgumentException();
var retval = new byte[hex.Length / 2];
for (int ix = 0; ix < hex.Length; ix += 2) {
retval[ix / 2] = byte.Parse(hex.Substring(ix, 2), System.Globalization.NumberStyles.HexNumber);
}
return retval;
}
Теперь вы можете выполнять быстрый поиск по шаблону с помощью алгоритма типа Бойера-Мура.