Рейтинг@Mail.ru

Безопасность: Инспектор файлов.


В этой статье мы немного углубимся в дебри компьютерной безопасности. И на повестке дня повис вопрос, как вы уже догадались — «Инспектор файлов». Что это и для чего он нужен я расскажу по мере чтения вами этой статьи, но замечу сразу, что испокон веков компьютерной эры, с тех самых времен, когда операционная система содрогнулась от вирусной эпидемии, на стражу ваших и системных файлов встал гроза контроля и целостности — «Инспектор». Прошу прощение за эпическое отступление ;).

Так вот, помимо установленных антивирусов и прочих специальных программ, которые выполняют кучу всяких полезностей, порой даже абсолютно не нужных в данный момент и только лишь отнимают наше драгоценное время. А мы то знаем, что время — деньги!
Что же меня побудило написать статью на эту тему? Во-первых, я считаю, и вам даю на заметку, что пользоваться готовым софтом — это утеха юзеров и прочих бездельников. Каждый уважающий себя программист должен иметь в своем арсенале собственноручно написанный инструментарий отвечающий его задачам и требованием, и не одной команды лишней. Да и кроме того вы сами знаете, что делает ваша программа, и в любой момент можете вспороть ее и что то подправить, добавить или удалить, в отличие от чужих программулек. Во-вторых, зная, а кто не знал запомните, что ни один антивирус не может вас защитить на 100% от свеженькой вредоносной информационной субстанции, то бишь вирус и прочая нечисть, так как антивирусная индустрия всегда позади на шаг впереди идущих создателей этой дряни. Поэтому вашу безопасность можете обеспечить только вы сами и одним из средств обеспечения в этом деле является «Инспектор файлов», который непоколебимо несет свою службу на полях информационного пространства и «своих» знает в «лицо».

После недолгих эпических отступлений, вы уж простите меня, без лишних слов приступаем к реализации нашего стражника «Инспектора». В первую очередь нам необходимо поставить задачу. Ей будет:
- реализовать поиск файлов
- проверку файлов на наличие их в банке данных, по соответствующим признакам(путь к файлу, дата создания, изменения и контрольная сумма)
- добавление в новых кандидатов на прописку в банк данных
- реализация интерфейса, связывающего предыдущие описанные задачи и действия пользователя.

В целом, получается вот такое тех. задание. А теперь от слов к делу. Для начала определимся с дизайном формы. Здесь я полагаюсь на ваш вкус, но потребуется нам две кнопки и поле вывода информации(Memo или ListBox).
Однуиз кнопок определим под выбор папки — «Обзор», и для нее напишем следующий код

Delphi
procedure TForm1.Button1Click(Sender: TObject); begin   Path := GetPath('Выберите папку');   if Path <> ''      then Label4.Caption := Path; end;

А теперь опишем используемую функцию GetPath():

Delphi
function GetPath(mes: string):string; var   Root: string;      // корневой каталог   pwRoot : PWideChar;   Dir: string; begin   Root := ''; // по умолчанию корневой каталог - рабочий стол   GetMem(pwRoot, (Length(Root)+1) * 2);   pwRoot := StringToWideChar(Root,pwRoot,MAX_PATH*2);   if SelectDirectory(mes, pwRoot, Dir)      then           if length(Dir) = 2  // пользователь выбрал корневой каталог               then GetPath := Dir+'\'               else GetPath := Dir      else           GetPath := ''; end;

Итак, процедура выбора каталога для проверки реализована. Теперь приступим к реализации проверки файлов. Но сначала для второй кнопки опишем следующий код:

Delphi
procedure TForm1.Button2Click(Sender: TObject); begin   Form1.ListBox1.Items.Add(TimeToStr(Time)+' :> Сканирование началось.');   ListFiles.Clear;   FindF(Path);   Scan_File;   Form1.ListBox1.Items.Add('===================================================');   Form1.ListBox1.Items.Add(TimeToStr(Time)+' :> Сканирование завершено.'); end;

А теперь последовательно опишем используемые функции и первой будет процедура FindF(). Эта процедура осуществляет рекурсивный поиск файлов относительно выбранного корневого каталога и добавляет их в список для проверки. Смотрим листинг:

Delphi
procedure FindF(path_f:string); begin //Инициируем поиск   if(FindFirst(path_f+'\*.*',faAnyFile,SearchRec) = 0) then   begin     repeat       if not((SearchRec.name = '.')or(SearchRec.name = '..')) then       begin         if SearchRec.Attr <> faDirectory then         begin           ListFiles.Add(path_f+'\'+SearchRec.Name); //если файл, добавляем в список           Inc(Count_file);         end         else           FindF(path_f+'\'+SearchRec.Name); //если папка, запускаем рекурсию       end;     until (FindNext(SearchRec)<>0);     FindClose(SearchRec);   end; end;

Далее рассмотрим процедуру Scan_File(). Ее задача проверить каждый найденный файл на наличие в своей базе данных, сверить контрольную сумму, дату создания и дату последнего изменения файла. В случае если будут обнаружены какие-либо несоответсвия, немедля бьет тревогу. Смотрим:

Delphi
procedure Scan_File; var   crc32T,dataCT,dataMT:Cardinal;   i:integer;   f: THandle;   SearchF:TWIN32FindData;   temp:boolean; begin   i:=0; //проверка на первый запуск, а точнее была база только что создана или нет.   if newBase = true then   //если да, то заносим список найденых файлов с их   //параметрами(путь, контрольная сумма, дата создания, дата изменения) в базу     while i <= Count_file-1 do     begin       WriteIB(ListFiles.Strings[i]);       Inc(i);     end; //далее производим проверку   i:=0;   while i <= Count_file-1 do   begin     try         //проверяем наличие файла       FS:=TFileStream.Create(ListFiles.Strings[i],fmOpenRead or fmShareDenyNone);     except       on Exception do       begin         Form1.ListBox1.Items.Add('не открывается '+ListFiles.Strings[i]);         break;       end;     end;         //Вычисляем контрольную сумму     crc32T:=CRC32Stream(FS,0);     FS.Free;     f:=FindFirstFile(PChar(ListFiles.Strings[i]),SearchF);     if f <> INVALID_HANDLE_VALUE then     begin         //определяем дату создания и дату изменения файла       dataCT:=SearchF.ftCreationTime.dwLowDateTime;       dataMT:=SearchF.ftLastWriteTime.dwLowDateTime;     end;         //запускаем процедуру поиска файла с найденными параметрами         //по базе     temp:=FindIB(ListFiles.Strings[i],crc32T,dataCT,dataMT);     if (Not temp and (FindFlagB=0)) then     begin         //если файл отсутсвует то выводим тревожное сообщение       Form1.ListBox1.Items.Add('ВНИМАНИЕ! Данный файл в базе отсутствует: '+ListFiles.Strings[i]);     end;         //Если файл в наличии то выводим результат проверки     if temp and (FindFlagB=1) then       Form1.ListBox1.Items.Add(ListFiles.Strings[i]+' - файл проверен. ОК.')     else       if (not temp) and (FindFlagB=1) then       Form1.ListBox1.Items.Add(ListFiles.Strings[i]+' - файл был изменен.');     Inc(i);     Form1.Update;   end; end;

Далее опишем функции для работы с базой. И первая функция FindIB(). Она осуществляет проверку наличия интересующего файла в базе и сверку переданных параметров искомого файла с теми, что соответствуют ему.

Delphi
function FindIB(strS:string;crc32,dataC,dataM:Cardinal):Boolean; var   fileS:TextFile;   nameD,fn:string;   crc32D,dataCD,dataMD:Cardinal;   i,it:integer; begin   FindFlagB:=0;   AssignFile(fileS,'IFdb.db');   Reset(fileS);   While Not EOF(fileS) do   begin   //считываем данные из базы     ReadLn(fileS,nameD);   // получаем имя файла     it:=Pos('$',nameD);     fn:=copy(nameD,1,it-1);     Delete(nameD,1,it);   //получаем контрольную сумму     it:=Pos('$',nameD);     crc32D:=StrToInt64(copy(nameD,1,it-1));     Delete(nameD,1,it);   //получаем дату создания файла     it:=Pos('$',nameD);     dataCD:=StrToInt64(copy(nameD,1,it-1));     Delete(nameD,1,it);   //получаем дату последнего изменения     dataMD:=StrToInt64(copy(nameD,1,length(nameD)));     if strS = fn then     begin       FindFlagB:=1;         if crc32 = crc32D then           if dataC = dataCD then             if dataM = dataMD then             begin               FindIB:=true;               CloseFile(fileS);               exit;             end;     end;   end;   FindIB:=false;   CloseFile(fileS); end;

Теперь рассмотрим функцию WriteIB(). Которая заносит в базу путь к файлу, его контрольную сумму, дату создания и дату последнего изменения.

Delphi
procedure WriteIB(name:string); var   dbf:TextFile;   i:Cardinal;   s:string;   f: THandle;   SearchF:TWIN32FindData; begin //открываем базу   AssignFile(dbf,'IFdb.db');   Append(dbf);   //инициализируем переменные   s:=name+'$';   try   //проверяем наличие добавляемого файла     FS:=TFileStream.Create(name,fmOpenRead or fmShareDenyNone);   except     on Exception do     begin       Form1.ListBox1.Items.Add('не открывается '+name);       exit;     end;   end;   //вычисляем контрольную сумму   i:=CRC32Stream(FS,0);   s:=s+IntToStr(i);   f:=FindFirstFile(PChar(name),SearchF);   if f <> INVALID_HANDLE_VALUE then    //определяем дату создания и дату изменения файла s:=s+'$'+IntToStr(SearchF.ftCreationTime.dwLowDateTime)+'$'+IntToStr(SearchF.ftLastWriteTime.dwLowDateTime);   writeln(dbf,s);   CloseFile(dbf);   FS.Free; end;

Далее надо объявить необходимые глобальные переменные:

Delphi
var   SearchRec: TSearchRec;   Count_file,FindFlagB,step: integer;   Path: string;   ListFiles: TStrings;   FS:TFileStream;   newBase:boolean;

Теперь необходимо для события onCreate написать следующее:

Delphi
procedure TForm1.FormCreate(Sender: TObject); var   f: THandle;   SearchF:TWIN32FindData; begin   SendMessage(ListBox1.Handle,LB_SetHorizontalExtent,1000,0);   newBase:= false;   ListFiles:=TStringList.Create;   Path:='*.*';   f:=FindFirstFile('IFdb.db',SearchF);   if f = INVALID_HANDLE_VALUE then   begin     f:=CreateFile('IFdb.db', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_WRITE or FILE_SHARE_READ, nil, CREATE_NEW, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED, 0);     if f <> INVALID_HANDLE_VALUE then     begin       CloseHandle(f);       newBase:= true;     end;   end; end;

На этом статью заканчиваю. Надеюсь статья и программный код описал максимально понятно. Но замечу, что код требует оптимизации, так как был написан таким образом, чтобы был понятен читателю. Пример может быть расширен, в него можно добавить кучу дополнительных возможностей. Все это зависит от вашей фантазии. Все вопросы и замечания высказываем на форуме.

Необходимые файлы:
- модуль для вычисления CRC32. Скачать

Рабочий пример скачать здесь.

Программирование, системное ,

Пожалуйста, оцените полезность и качество данной статьи. Одна звезда - плохо, 5 - хорошо.
1 звезда2 звезды3 звезды4 звезды5 звёзд (2 голосов, средний: 5,00 из 5)
Loading ... Loading ...

  1. Пока что нет комментариев.
  1. Пока что нет уведомлений.
*