Поиск 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;
    }

Теперь вы можете выполнять быстрый поиск по шаблону с помощью алгоритма типа Бойера-Мура.

Другие вопросы по тегам