Си |
Паскаль |
/* ВХОДНЫЕ ПАРАМЕТРЫ: * 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; |
Какое количество файлов размером 7 байт, состоящих только из цифр от 0 (код 0x30) до 9 (код 0x39) включительно, может содержать трех-байтовую сигнатуру «0x313231» хотя бы один раз, но успешно проходить проверку антивирусом? Ответ обоснуйте.
Из анализа функции CheckFile()видно, что антивирус анализирует файл, начиная с нулевого байта, блоками данных размером по 3 байта, без пересечений. Поэтому, если начало сигнатуры в одном блоке, а конец – в другом, то она не будет обнаружена.
Возможные варианты размещения сигнатуры в файлах размером 7 байт, содержащих допустимые ASCII-символы (где X – любая цифра от 0 до 9):
X12 1XX X – X12 121 X
XX1 21X X – 121 21X X
XXX X12 1 – X12 112 1 – 121 X12 1 – XX1 212 1 + 121 212 1 (т.к. этот файл исключен дважды в вариантах 121 X12 1 и XX1 212 1)
Для оптимизации процесса подсчета количества файлов можно написать программу, которая реализует корректный поиск сигнатур с использованием функции, полученной из CheckFile(), например, добавлением строки
fseek(fin, -(read - 1), SEEK_CUR);
в конец цикла while.
Разница между числом файлов, проходящих проверку антивирусами на основе функции CheckFile()и ее исправленной версии, – ответ к задаче.
29681