Для выявления вредоносного кода некоторым антивирусом применяется только сигнатурный метод анализа, позволяющий выполнять поиск известных сигнатур в файле путем побайтового сравнения. Файл считается вредоносным при наличии в нем участка данных, точно совпадающего с одной из сигнатур. Реализация поиска сигнатур описана в функции CheckFile(), которая возвращает TRUE при отсутствии сигнатур в файле и FALSE в противном случае.
Си |
Паскаль |
/* ВХОДНЫЕ ПАРАМЕТРЫ: * FNAME - имя анализируемого файла * SIGNATURE - сигнатура (массив байтов) * SIZE - размер сигнатуры в байтах * * ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: * TRUE - файл не содержит сигнатуры * FALSE - файл содержит хотя бы одну
*/ bool CheckFile(char* fname,
{ FILE *fin=NULL; char *buf=NULL; int read, check_count=0; buf=new char[size]; fin=fopen(fname, "rb"); if (!fin) return false; while(!feof(fin)) { read=fread(buf, 1, size, fin); if(read!=size) break; check_count=0; for (int j=0; j<size; j++) { if (buf[j]==signature[j]) check_count++; else break; } if (check_count==size) return false; } return true; } |
/* ВХОДНЫЕ ПАРАМЕТРЫ: * FNAME - имя анализируемого файла * SIGNATURE - сигнатура (массив байтов) * SIZE - размер сигнатуры в байтах * * ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: * TRUE - файл не содержит сигнатуры * FALSE - файл содержит хотя бы одну
*/ function CheckFile (fname,
var fin: file; ch: char; count_read, check_count, i: integer; buf: string; begin assign(fin, fname); reset(fin); while true do begin buf:=''; count_read:=0; for i:=1 to size do begin if (not eof(fin)) then begin read(fin, ch); buf:=buf+ch; count_read:=count_read+1; end; end; if count_read <> size then break; check_count:=0; for i:=1 to size do begin if(buf[i]=signature[i]) then check_count:=check_count+1 else break; end; if check_count=size then begin CheckFile:=false; Exit; end; end; close(fin); CheckFile:=true; end; |
База сигнатур содержит две записи:
0x313132
0x3132
Проверка файла осуществляется последовательным вызовом функции CheckFile() для каждой сигнатуры из базы.
Какое количество файлов размером 7 байт, состоящих только из цифр от 0 (код 0x30) до 9 (код 0x39) включительно, может содержать хотя бы одну из указанных сигнатур хотя бы один раз, но успешно проходить проверку имеющимся антивирусом? Ответ обоснуйте.
Из анализа функции CheckFile()видно, что антивирус анализирует файл, начиная с нулевого байта, блоками данных размером по 3 байта, без пересечений. Поэтому, если начало сигнатуры в одном блоке, а конец – в другом, то она не будет обнаружена.
Для оптимизации процесса подсчета количества файлов можно написать программу, которая реализует корректный поиск сигнатур с использованием функции, полученной из CheckFile()добавлением строки
fseek(fin, -(read - 1), SEEK_CUR);
в конец цикла while.
Разница между числом файлов, проходящих проверку антивирусами на основе функции CheckFile()и ее исправленной версии, – искомое количество файлов.
283.130