2012-02-06 4 views
0

Я пишу программу, которая читает файлы .exe и сохраняет их шестнадцатеричные значения в массиве байтов для сравнения с массивом, содержащим ряд значений. (Как очень простой антивирусу)Поиск ReadAllBytes для определенных значений

byte[] buffer = File.ReadAllBytes(currentDirectoryContents[j]); 

я тогда использовал BitConverter для создания одной строки из этих значений

string hex = BitConverter.ToString(buffer); 

Следующим шагом является поиск этой строки для ряда значений (определений) и положительный результат для матча. Здесь я столкнулся с проблемами. Мои определения шестнадцатиричного значение, но создан и сохранен в качестве блокнота defintions.xyz

string[] definitions = File.ReadAllLines(@"C:\definitions.xyz"); 

Я пытался читать их в массив строк и сравнить элементы определения массива со строкой шестнадцатеричного

bool[] test = new bool[currentDirectoryContents.Length]; 

test[j] = hex.Contains(definitions[i]); 

Это раздел из урока домашней работы, поэтому я не размещаю весь свой код для программы. Я не использовал C# до прошлой пятницы, поэтому, скорее всего, делаю глупые ошибки на этом этапе.

Любой совет высоко ценится :)

+1

Можете ли вы разместить содержание или раздел своего файла определений, пожалуйста. –

+0

И в чем проблема? – GazTheDestroyer

+3

Что вы думаете? Еще одна важная вещь: преобразование байтового массива в строку для дальнейшего шестнадцатеричного сравнения действительно неэффективно. Вы должны сравнивать байты с байтами и ** не ** использовать строки здесь. – ken2k

ответ

0

Я ожидаю, что вы понимаете, что это очень неэффективный способ сделать это. Но для этого, кроме, вы должны просто сделать что-то вроде этого:

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 
+0

Я понимаю неэффективность кода, но я не опытный кодер и доволен написанием рабочего кода, прежде чем смотреть на улучшения. Я понял, что весь мой код работает, но код, содержащийся в файле exe, который я читал, уже был на HEX. Поэтому мой код просто преобразовывал каждый байт в другое значение HEX. Теперь разрешено. Спасибо всем за ваш вклад и предложения! –

1

Это довольно неясно, какой именно формат вы используете определения s. Base64 - хорошая кодировка для байта [], вы можете быстро конвертировать туда и обратно с Convert.ToBase64String и Convert.FromBase64String(). Но ваш вопрос предполагает, что байты кодируются в шестнадцатеричном виде. Предположим, что он выглядит как «01020304» для нового байта [] {1, 2, 3, 4}. Тогда эта вспомогательная функция преобразует такую ​​строку обратно в байт []:

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; 
    } 

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

+0

Определенный формат для определений в файле отсутствует. Я решил, чтобы каждое определение представляло собой последовательность бит (в шестнадцатеричной форме). Это от исследования методов сканирования вирусов и принятия решений о подписях. На данный момент, чтобы начать свой файл подписи имеет одно определение в: A6 7C FD 1B 45 82 90 1D 6F 3C 8А 96 18 A4 C3 4F FF 0F 1D один .exe в папке будет содержать эту серию байтов, потому что он будет создан в блокноте и просто сохранен как exe. Для файла определений нет определенного формата файла. Я только что использовал случайное расширение. –

+0

Ну, наличие определенного формата весьма важно. Код, который я написал, должен быть близок, ожидайте, что вам нужно использовать 3 вместо 2 из-за пробелов. –

+0

Решили теперь, спасибо за ваше время, чтобы посоветовать мне о возможном решении! –