<?xml version="1.0" encoding="windows-1251"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<atom:link href="https://razrabotka.f-rpg.me/export.php?type=rss" rel="self" type="application/rss+xml" />
		<title>Разработка C# , C++ и прочие</title>
		<link>https://razrabotka.f-rpg.me/</link>
		<description>Разработка C# , C++ и прочие</description>
		<language>ru-ru</language>
		<lastBuildDate>Thu, 25 Jul 2013 23:24:26 +0400</lastBuildDate>
		<generator>MyBB/mybb.ru</generator>
		<item>
			<title>[Обязательно к прочтению] Правильный вирустотал, и как не попасться на</title>
			<link>https://razrabotka.f-rpg.me/viewtopic.php?pid=16#p16</link>
			<description>&lt;p&gt;спасибо полезная информация :D&lt;/p&gt;</description>
			<author>mybb@mybb.ru (waryagqw)</author>
			<pubDate>Thu, 25 Jul 2013 23:24:26 +0400</pubDate>
			<guid>https://razrabotka.f-rpg.me/viewtopic.php?pid=16#p16</guid>
		</item>
		<item>
			<title>Как правильно создавать темы и оформлять их?ОБЯЗАТЕЛЬНО К ПРОЧТЕНИЮ!</title>
			<link>https://razrabotka.f-rpg.me/viewtopic.php?pid=14#p14</link>
			<description>&lt;p&gt;Итак,я думаю у каждого человека есть свои секреты,и читы,которих нет на форуме,чтобы развивать наш форум нужны пользователи,и потому, в этой теме я научу вас,как правильно оформлять темы&lt;/p&gt;
						&lt;p&gt;Есле вы хотите создать тему,в левом углу сверху,есть кнопка:&lt;br /&gt;,,Создать новую тему,,&lt;br /&gt;-Жмём туда&lt;br /&gt;Префикс &lt;br /&gt;= Undetected &lt;br /&gt;(чит не спалили и он работает)&lt;/p&gt;
						&lt;p&gt;=Detected&lt;br /&gt;(чит профиксили,и он не работает)&lt;/p&gt;
						&lt;p&gt;=Use at own risk &lt;/p&gt;
						&lt;p&gt;(Используйте на свой риск,он работает например,&lt;br /&gt;но могут быть трудности)&lt;/p&gt;
						&lt;p&gt;Заголовок: &lt;br /&gt;,,Писать название чита,без лишниш знаков,,&lt;/p&gt;
						&lt;p&gt;ТЕМА ДОЛЖНА ИМЕТЬ : :nea:&lt;/p&gt;
						&lt;p&gt;-ФУНКЦИИ ЧИТА или Програмы&lt;br /&gt;-ИНСТРУКЦИЯ&lt;br /&gt;-СКРИНШОТ ИЛИ ВИДЕО С ИГРЫ&lt;br /&gt;&lt;a href=&quot;http://www.radikal.ru/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;http://www.radikal.ru/&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://pixic.ru/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;http://pixic.ru/&lt;/a&gt;&lt;/p&gt;
						&lt;p&gt;ЧТОБЫ ВСТАВИТЬ СКРИН,ЗАЛИВАЕМ НА ФОТОХОСТИНГ,ССЫЛКИСВЕРХУ,К ОПИРУЕМ ССЫЛКУ НА СКРИН,ЖМЁМ СВЕРХУ НА ФОТКУ ( 3 ЗНАК ПОСЛЕ ПЛАНЕТКИ) И ВСТАВЛЯЕМ НАШУ ССЫЛКУ&lt;/p&gt;
						&lt;p&gt;-ССЫЛКА НА СКАЧКУ: &lt;br /&gt;&lt;a href=&quot;http://zalil.ru/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;http://zalil.ru/&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://rghost.ru/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;http://rghost.ru/&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://ffiles.ru/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;http://ffiles.ru/&lt;/a&gt;&lt;br /&gt;Админы и модераторы - могут заливать на платные ФО&lt;br /&gt;- ВИРУС ТОТАЛ или ВИРУС СКАН&lt;br /&gt;&lt;a href=&quot;https://www.virustotal.com/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://www.virustotal.com/&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://virusscan.jotti.org/ru&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;http://virusscan.jotti.org/ru&lt;/a&gt;&lt;/p&gt;
						&lt;p&gt;КАК ВСТАВИТЬ ССЫЛКУ?&lt;br /&gt;1)ЗАЛИВАЕМ НА ФО.&lt;br /&gt;2)КОПИРУЕМ ССЫЛКУ&lt;br /&gt;3)ЖМЁМ НА ПЛАНЕТКУ И ВСТАВЛЯЕМ ССЫКУ&lt;br /&gt;4)ГОТОВО&lt;/p&gt;
						&lt;p&gt;МЕТКИ: :ohmy:&lt;br /&gt;Можно вставить метку (название чита например,или функции какие имеет)&lt;/p&gt;
						&lt;p&gt;Иконки: &lt;br /&gt;Вставляем подходящую иконку=)&lt;/p&gt;
						&lt;p&gt;СМЕЛО ЖМЁМ СОЗДАТЬ ТЕМУ !!!! ЕСЛЕ БУДУТ НЕДОРАБОТКИ СООБЩИТЕ В КОМЕНТАРИЯХ,Я ИСПРАВЛЮ!&lt;br /&gt;ПО ВОПРОСАМ В ЛС: КУРАТОРАМ,МОДЕРАТОРАМ,АДМИ НУ&lt;br /&gt;ЕСЛЕ ТЕМА БУДТ ОФОРМЛЕНА ПО ВСЕМ ПРАВИЛАМ ЖДИТЕ ОТ МЕНЯ + И СПС!&lt;/p&gt;
						&lt;p&gt;В противных случаях ,т.е тема без:&lt;/p&gt;
						&lt;p&gt;-Скриншотов &lt;br /&gt;-Без инстукции&lt;br /&gt;-Без ссылки на бесплатный фо&lt;br /&gt;-Без Вирус Сканера&lt;/p&gt;
						&lt;p&gt;Будет закрываться мною или модераторами и ставится под статус детектед!&lt;/p&gt;
						&lt;p&gt;СПАСИБО ЗА ВНИМАНИЕ!!!!&lt;/p&gt;</description>
			<author>mybb@mybb.ru (Hrom)</author>
			<pubDate>Thu, 25 Jul 2013 21:34:52 +0400</pubDate>
			<guid>https://razrabotka.f-rpg.me/viewtopic.php?pid=14#p14</guid>
		</item>
		<item>
			<title>Как Добавить видео с Yotube на форум [для новичков]</title>
			<link>https://razrabotka.f-rpg.me/viewtopic.php?pid=13#p13</link>
			<description>&lt;p&gt;&lt;/p&gt;</description>
			<author>mybb@mybb.ru (Hrom)</author>
			<pubDate>Thu, 25 Jul 2013 20:51:33 +0400</pubDate>
			<guid>https://razrabotka.f-rpg.me/viewtopic.php?pid=13#p13</guid>
		</item>
		<item>
			<title>Набор модераторов</title>
			<link>https://razrabotka.f-rpg.me/viewtopic.php?pid=12#p12</link>
			<description>&lt;p&gt;Для подачи своей кандидатуры от вас нужно предоставить в данной теме такие данные:&lt;br /&gt;1 Имя &lt;br /&gt;2 сколько лет&lt;br /&gt;3 Категории на форуме в которых вы хотите быть модератором &lt;br /&gt;4 сколько будеш уделять времени форуму &lt;br /&gt;5 стаж игры crossfire , сколько играеш с читами &lt;/p&gt;
						&lt;p&gt;С уважением, Администрация&lt;/p&gt;</description>
			<author>mybb@mybb.ru (Hrom)</author>
			<pubDate>Thu, 25 Jul 2013 20:26:33 +0400</pubDate>
			<guid>https://razrabotka.f-rpg.me/viewtopic.php?pid=12#p12</guid>
		</item>
		<item>
			<title>Создаем музыкальный плеер</title>
			<link>https://razrabotka.f-rpg.me/viewtopic.php?pid=3#p3</link>
			<description>&lt;p&gt;Привет всем сегодня я вам раскажу как создать музыкальный плеер в программе PHP Devil Studio.&lt;br /&gt;И так начнем&lt;br /&gt;Создаем три спид кнопки и называем их: выбрать песню,стоп,Пауза/Далее&lt;br /&gt;Диалог открытия&lt;br /&gt;И SQUALL плеер&lt;/p&gt;
						&lt;p&gt;Потом делаем так&lt;br /&gt;Нажимаем Диалог открытия,к параметру &amp;quot;Фильтр&amp;quot; пишем Музыка |*.mp3;*.wav&lt;br /&gt;Чтобы можно было выбирать только музыкальные файлы делаем так&lt;/p&gt;
						&lt;p&gt;К первой кнопке Выбрать песню создаём событие на клик и в редактор PHP кода пишем:&lt;/p&gt;
						&lt;p&gt;Нажмите здесь для просмотра полного текста&lt;br /&gt;Код:&lt;br /&gt;$dialog = c(&amp;quot;openDlg1&amp;quot;)-&amp;gt;execute();&lt;br /&gt;c(&amp;quot;sqPlayer1&amp;quot;)-&amp;gt;open(c(&amp;quot;openDlg1&amp;quot;)-&amp;gt;fileName);&lt;br /&gt;c(&amp;quot;sqPlayer1&amp;quot;)-&amp;gt;play();&lt;/p&gt;
						&lt;p&gt;Ко второй кнопке Стоп тоже создаём событие на клик а редактор PHP кода вставляем это:&lt;br /&gt;Код:&lt;br /&gt;Нажмите здесь для просмотра полного текста&lt;br /&gt;Код:&lt;br /&gt;c(&amp;quot;sqPlayer1&amp;quot;)-&amp;gt;stop();&lt;br /&gt;К третей кнопке так же но в редактор PHP кода пишем вот такое:&lt;br /&gt;code:&lt;br /&gt;c(&amp;quot;sqPlayer1&amp;quot;)-&amp;gt;pause();&lt;/p&gt;
						&lt;p&gt;Жмем F9 чтобы проверить&lt;br /&gt;Потом сохраняем програму&lt;br /&gt;Сохраняем исходник програму&lt;br /&gt;Включаем и наслаждаемся музыкой&lt;/p&gt;</description>
			<author>mybb@mybb.ru (Hrom)</author>
			<pubDate>Wed, 24 Jul 2013 16:43:19 +0400</pubDate>
			<guid>https://razrabotka.f-rpg.me/viewtopic.php?pid=3#p3</guid>
		</item>
		<item>
			<title>Простой антивирус на С++</title>
			<link>https://razrabotka.f-rpg.me/viewtopic.php?pid=2#p2</link>
			<description>&lt;p&gt;В статье рассматривается процесс написания простого антивирусного сканера.&lt;br /&gt;Задача статьи состоит в объяснении базовых принципов работы антивирусных программ, использующих сигнатуры для обнаружения вредоносного кода.&lt;br /&gt;Помимо самого сканера мы также напишем программку для создания базы сигнатур.&lt;/p&gt;
						&lt;p&gt;В силу простоты алгоритма проверки наш сканер сможет обнаруживать только вредоносные программы, распространяющиеся цельным файлом, т.е. не заражающие другие файлы, как PE-Вирусы, и не изменяющие свое тело в процессе деятельности, как полиморфные вирусы.&lt;br /&gt;Впрочем, это относится к большинству вирусов, червей и практически ко всем троянам, поэтому написанный нами сканер имеет право на жизнь :)&lt;/p&gt;
						&lt;p&gt;Что такое сигнатура&lt;br /&gt;Сигнатура в простом представлении является уникальной частью (последовательностью байт) в файле.&lt;br /&gt;Однако эта часть должна максимально однозначно выделять файл среди множества других файлов.&lt;br /&gt;Это значит, что выбранная последовательность должна присутствовать только в одном файле, которому она принадлежит, и ни в каких других.&lt;/p&gt;
						&lt;p&gt;На практике помимо самой последовательности применяются ещё дополнительные параметры, позволяющие максимально однозначно сопоставлять сигнатуру файлу.&lt;br /&gt;Введение дополнительных параметров также направлено на ускорение поиска сигнатуры в файле.&lt;br /&gt;Такими параметрами, например, могут являться размер файла, смещение последовательности байт, тип файла, специальные маски (отражение того, как примерно должен выглядеть файл, чтобы в нём могла содержаться искомая сигнатура) и многие другие.&lt;/p&gt;
						&lt;p&gt;В нашем сканере в качестве дополнительного параметра мы будем использовать смещение последовательности в файле относительно начала.&lt;br /&gt;Данный метод довольно универсален в том плане, что подходит абсолютно для любых файлов независимо от типа.&lt;br /&gt;Однако у использования смещения есть один очень значимый минус: чтобы &amp;quot;обмануть&amp;quot; сканер, достаточно слегка &amp;quot;передвинуть&amp;quot; последовательность байт в файле, т.е. изменить смещение последовательности (например, перекомпилировав вирус или добавив символ в случае скрипт-вируса).&lt;/p&gt;
						&lt;p&gt;Для экономии памяти и повышения скорости обнаружения на практике обычно используется контрольная сумма (хэш) последовательности.&lt;br /&gt;Таким образом перед добавлением сигнатуры в базу считается контрольная сумма выбранного участка файла. Это также помогает не обнаруживать вредоносный код в собственных базах :)&lt;/p&gt;
						&lt;p&gt;Антивирусная база&lt;br /&gt;Антивирусная база представляет собой один или несколько файлов, содержащих записи о всех известных сканеру вирусах.&lt;br /&gt;Каждая запись обязательно содержит имя вируса (пользователь же должен знать,что за зверь поселился у него в системе), также в записи обязательно присутствует сигнатура, по которой выполняется поиск.&lt;br /&gt;Помимо имени и сигнатуры запись может содержать некоторую дополнительную информацию, например, инструкции по лечению.&lt;/p&gt;
						&lt;p&gt;Алгоритм работы сканера&lt;br /&gt;Алгоритм работы сканера, использующего сигнатуры, можно свести к нескольким пунктам:&lt;br /&gt;1. Загрузка базы сигнатур&lt;br /&gt;2. Открытие проверяемого файла&lt;br /&gt;3. Поиск сигнатуры в открытом файле&lt;br /&gt;4. Если сигнатура найдена &lt;br /&gt;- принятие соответствующих мер&lt;br /&gt;5. Если ни одна сигнатура из базы не найдена&lt;br /&gt;- закрытие файла и переход к проверке следующего&lt;/p&gt;
						&lt;p&gt;Как видите, общий принцип работы сканера весьма прост.&lt;/p&gt;
						&lt;p&gt;Впрочем, достаточно теории. Переходим к практике.&lt;br /&gt;Все дополнительные моменты будут разобраны в процессе написания сканера.&lt;/p&gt;
						&lt;p&gt;Подготовка к реализации&lt;br /&gt;Прежде чем начинать писать код, стоит определить все составные части сканера и то, как они будут взаимодействовать.&lt;/p&gt;
						&lt;p&gt;Итак, для обнаружения вредоносных файлов нам необходим непосредственно сам сканер.&lt;br /&gt;Сканеру для работы необходимы сигнатуры, которые хранятся в антивирусной базе.&lt;br /&gt;База создается и наполняется специальной программой.&lt;br /&gt;В итоге получается следующая зависимость:&lt;/p&gt;
						&lt;p&gt;Программа создания базы -&amp;gt; База -&amp;gt; Сканер&lt;/p&gt;
						&lt;p&gt;Однако прежде чем создавать базу, необходимо определиться с её форматом, который в свою очередь зависит от хранимой информации.&lt;/p&gt;
						&lt;p&gt;Информация сигнатуры&lt;/p&gt;
						&lt;p&gt;Сигнатура будет состоять из:&lt;br /&gt;- Смещения последовательности в файле&lt;br /&gt;- Размера последовательности&lt;br /&gt;- Хэша последовательности&lt;/p&gt;
						&lt;p&gt;Для хэширования будем использовать алгоритм MD5.&lt;br /&gt;Каждый MD5-хэш состоит из 16 байт, или 4 двойных слов.&lt;br /&gt;Для хранения смещения и размера последовательности отведём по 4 байта для каждого.&lt;/p&gt;
						&lt;p&gt;Таким образом сигнатуру можно описать следующей структурой:&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;[Offset	* 4 ]&lt;br /&gt;[Lenght	* 4 ]&lt;br /&gt;[Hash	* 16 ]&lt;/p&gt;
						&lt;p&gt;Запись антивирусной базы&lt;/p&gt;
						&lt;p&gt;Запись будет содержать:&lt;br /&gt;- Сигнатуру&lt;br /&gt;- Размер имени файла&lt;br /&gt;- Имя файла&lt;/p&gt;
						&lt;p&gt;Под размер имени файла выделим 1 байт. Этого более чем достаточно, плюс экономия места =)&lt;br /&gt;Имя файла может быть произвольного размера до 255 символов включительно.&lt;/p&gt;
						&lt;p&gt;Получается следующая структура:&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;[Signature]&lt;br /&gt;[NameLen	* 1 ]&lt;br /&gt;[Name	 ... ]&lt;br /&gt;После раскрытия структуры сигнатуры получается вот такая запись:&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;[Offset	 * 4 ]&lt;br /&gt;[Lenght	 * 4 ]&lt;br /&gt;[Hash	 * 16]&lt;br /&gt;[NameLen	* 1 ]&lt;br /&gt;[Name	 ... ]&lt;br /&gt;Именно в таком виде одна за другой в файле будут лежать записи для всех известных сканеру зловредов.&lt;/p&gt;
						&lt;p&gt;Помимо самих записей в файле базы должен быть заголовок, в котором будет содержаться число записей в базе и сигнатура файла &amp;quot;AVB&amp;quot; (не антивирусная :) ). Назначение сигнатуры – удостовериться, что это именно файл базы.&lt;/p&gt;
						&lt;p&gt;Таким образом файл базы будет иметь структуру вида:&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;[Sign	 * 3 ]&lt;br /&gt;[RecordCount* 4 ]&lt;br /&gt;[Records]&lt;br /&gt;Переходим к написанию кода.&lt;/p&gt;
						&lt;p&gt;Реализация&lt;br /&gt;Базовые структуры&lt;br /&gt;Структур немного, всего 2.&lt;br /&gt;Данные структуры будут использоваться как сканером, так и программой создания антивирусной базы.&lt;br /&gt;Во-первых, необходимо объявить все нужные нам структуры.&lt;/p&gt;
						&lt;p&gt;Первой структурой будет структура сигнатуры SAVSignature.&lt;br /&gt;Следующей структурой будет структура записи SAVRecord, объединяющая сигнатуру с именем.&lt;br /&gt;Данная структура для удобства также содержит функцию выделения памяти под имя зловреда (allocName).&lt;/p&gt;
						&lt;p&gt;Все структуры будут находиться в заголовочном файле avrecord.h&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;#ifndef _AVRECORD_H__INCLUDED_&lt;br /&gt;#define _AVRECORD_H__INCLUDED_&lt;br /&gt;#include &amp;lt;windows.h&amp;gt;&lt;br /&gt; &lt;/p&gt;
						&lt;p&gt;//! Структура сигнатуры&lt;br /&gt;typedef struct SAVSignature{&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; SAVSignature(){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; this-&amp;gt;Offset = 0;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; this-&amp;gt;Lenght = 0;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; memset(this-&amp;gt;Hash, 0, sizeof(this-&amp;gt;Hash));&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; DWORD&amp;#160; &amp;#160;Offset;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;// - Смещение&amp;#160; файле&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; DWORD&amp;#160; &amp;#160;Hash[4];&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - MD5 хэш&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; DWORD&amp;#160; &amp;#160;Lenght;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;// - Размер данных&lt;br /&gt;} * PSAVSignature;&lt;/p&gt;
						&lt;p&gt;//! Структура записи о зловреде&lt;br /&gt;typedef struct SAVRecord{&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; SAVRecord(){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; this-&amp;gt;Name&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;= NULL;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; this-&amp;gt;NameLen&amp;#160; &amp;#160; &amp;#160; &amp;#160; = 0;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; ~SAVRecord(){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(this-&amp;gt;Name != NULL)&amp;#160; this-&amp;gt;Name;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; //! Выделение памяти под имя&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; void&amp;#160; &amp;#160; allocName(BYTE NameLen){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(this-&amp;gt;Name == NULL){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; this-&amp;gt;NameLen&amp;#160; &amp;#160; &amp;#160; &amp;#160; = NameLen;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; this-&amp;gt;Name&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;= new CHAR[this-&amp;gt;NameLen + 1];&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; memset(this-&amp;gt;Name, 0, this-&amp;gt;NameLen + 1);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; PSTR&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; Name;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;// - Имя&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; BYTE&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; NameLen;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Размер имени&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; SAVSignature&amp;#160; &amp;#160; Signature;&amp;#160; &amp;#160; &amp;#160; // - Сигнатура&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;br /&gt;} * PSAVRecord;&lt;/p&gt;
						&lt;p&gt;#endif&lt;br /&gt;Класс работы с файлом базы&lt;br /&gt;Теперь необходимо написать класс для работы с файлом антивирусной базы.&lt;br /&gt;Если точнее, то классов будет несколько:&lt;br /&gt;- Базовый класс файла &amp;quot;CAVBFile&amp;quot;&lt;br /&gt;- Класс чтения файла &amp;quot;CAVBFileReader&amp;quot;&lt;br /&gt;- Класс добавления записи &amp;quot;CAVBFileWriter&amp;quot;&lt;/p&gt;
						&lt;p&gt;Объявления всех этих классов находятся в файле CAVBFile.h&lt;br /&gt;Вот его содержимое:&lt;br /&gt;Код:&lt;br /&gt;#ifndef _AVBFILE_H__INCLUDED_&lt;br /&gt;#define _AVBFILE_H__INCLUDED_&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;#include &amp;lt;windows.h&amp;gt;&lt;br /&gt;#include &amp;quot;avrecord.h&amp;quot;&lt;br /&gt;using namespace std;&lt;br /&gt; &lt;/p&gt;
						&lt;p&gt;/*&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; Формат файла антивирусной базы&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; [AVB]&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;// - Сигнатура&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; [RecordCount&amp;#160; &amp;#160; * 4 ]&amp;#160; &amp;#160;// - Число записей&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; [Records&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; ... ]&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; Record:&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; [Offset&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;* 4 ]&amp;#160; &amp;#160;// - Смещение&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; [Lenght&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;* 4 ]&amp;#160; &amp;#160;// - Размер&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; [Hash&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;* 16 ]&amp;#160; // - Контрольная сумма&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; [NameLen&amp;#160; &amp;#160; &amp;#160; &amp;#160; * 1 ]&amp;#160; &amp;#160;// - Размер имени&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; [Name&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;... ]&amp;#160; &amp;#160;// - Имя зловреда&lt;/p&gt;
						&lt;p&gt;*/&lt;br /&gt; &lt;/p&gt;
						&lt;p&gt;//! Класс Файла антивирусной базы&lt;br /&gt;typedef class CAVBFile{&lt;br /&gt;protected:&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; fstream&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;hFile;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Объект потока файла&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; DWORD&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;RecordCount;&amp;#160; &amp;#160; // - Число записей&lt;br /&gt;public:&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; CAVBFile();&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; //! Закрытие файла&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; virtual void close();&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; //! Проверка состояния файла&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; virtual bool is_open();&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; //! Получение числа записей&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; virtual DWORD getRecordCount();&lt;br /&gt;} * PCAVBFile;&lt;br /&gt; &lt;/p&gt;
						&lt;p&gt;//! Класс для записи файла&lt;br /&gt;typedef class CAVBFileWriter : public CAVBFile{&lt;br /&gt;public:&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; CAVBFileWriter() : CAVBFile(){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; //! Открытие файла&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; bool&amp;#160; &amp;#160; open(PCSTR FileName);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; //! Добавление записи в файл &lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; bool&amp;#160; &amp;#160; addRecord(PSAVRecord&amp;#160; &amp;#160; Record);&lt;/p&gt;
						&lt;p&gt;} * PCAVBFileWriter;&lt;/p&gt;
						&lt;p&gt;//! Класс для чтения файла&lt;br /&gt;typedef class CAVBFileReader : public CAVBFile{&lt;br /&gt;public:&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; CAVBFileReader() : CAVBFile(){&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; //! Открытие файла&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; bool&amp;#160; &amp;#160; open(PCSTR FileName);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; //! Чтение записи&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; bool&amp;#160; &amp;#160; readNextRecord(PSAVRecord Record);&lt;/p&gt;
						&lt;p&gt;} * PCAVBFileReader;&lt;br /&gt; &lt;/p&gt;
						&lt;p&gt;#endif&lt;/p&gt;
						&lt;p&gt;Теперь перейдем к реализации объявленных классов.&lt;br /&gt;Их реализация будет находиться в файле AVBFile.cpp&lt;br /&gt;Естественно, помним, что необходимо подключить заголовочный файл AVBFile.h&lt;/p&gt;
						&lt;p&gt;В некоторых функциях нам понадобится проверка существования файла, поэтому сначала напишем именно её.&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;//! Проверка существования файла&lt;br /&gt;bool&amp;#160; &amp;#160; isFileExist(PCSTR FileName){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; return GetFileAttributesA(FileName) != DWORD(-1);&lt;br /&gt;};&lt;br /&gt;Данный способ проверки существования файла является самым быстрым и используется в большинстве примеров в MSDN, так что его можно считать стандартом для Windows.&lt;br /&gt;Функция GetFileAttributes возвращает атрибуты файла или 0xffffffff в случае, если файл не найден.&lt;/p&gt;
						&lt;p&gt;Переходим к реализации функций базового класса.&lt;/p&gt;
						&lt;p&gt;Код:&lt;/p&gt;
						&lt;p&gt;CAVBFile::CAVBFile(){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; this-&amp;gt;RecordCount = 0;&lt;br /&gt;}&lt;br /&gt;//! Закрытие файла&lt;br /&gt;void CAVBFile::close(){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(hFile.is_open())&amp;#160; &amp;#160; &amp;#160;hFile.close();&lt;br /&gt;}&lt;br /&gt;//! Проверка состояния файла&lt;br /&gt;bool CAVBFile::is_open(){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; return hFile.is_open();&lt;br /&gt;}&lt;br /&gt;//! Получение числа файлов&lt;br /&gt;DWORD&amp;#160; &amp;#160;CAVBFile::getRecordCount(){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; return this-&amp;gt;RecordCount;&lt;br /&gt;}&lt;br /&gt;Здесь всё просто и в комментариях не нуждается.&lt;/p&gt;
						&lt;p&gt;Теперь реализуем функции класса для записи файла&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt; &lt;/p&gt;
						&lt;p&gt;// &lt;br /&gt;// - CAVBFileWriter&lt;br /&gt;// &lt;/p&gt;
						&lt;p&gt;//! Открытие файла&lt;br /&gt;bool CAVBFileWriter::open(PCSTR FileName){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(FileName == NULL) return false;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Если файл не найден то создаем его прототип&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!isFileExist(FileName)){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.open(FileName, ios::out | ios::binary);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!hFile.is_open()) return false;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.write(&amp;quot;AVB&amp;quot;, 3);&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Сигнатура файла&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.write((PCSTR)&amp;amp;this-&amp;gt;RecordCount, sizeof(DWORD));&amp;#160; &amp;#160;// - Число записей&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Иначе открываем и проверяем валидность&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }else{&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.open(FileName, ios::in | ios::out | ios::binary);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!hFile.is_open()) return false;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Проверка сигнатуры&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; CHAR&amp;#160; &amp;#160; Sign[3];&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.read((PSTR)Sign, 3);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(memcmp(Sign, &amp;quot;AVB&amp;quot;, 3)){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.close();&amp;#160; // - Это чужой файл&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return false;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Читаем число записей&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.read((PSTR)&amp;amp;this-&amp;gt;RecordCount, sizeof(DWORD));&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; return true;&lt;br /&gt;}&lt;/p&gt;
						&lt;p&gt;bool CAVBFileWriter::addRecord(PSAVRecord Record){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(Record == NULL || !hFile.is_open()) return false;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Перемещаемся в конец файла&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.seekp(0, ios::end);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Добавляем запись&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.write((PSTR)&amp;amp;Record-&amp;gt;Signature.Offset,&amp;#160; &amp;#160; &amp;#160;sizeof(DWORD)); // - Смещение сигнатуры&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.write((PSTR)&amp;amp;Record-&amp;gt;Signature.Lenght,&amp;#160; &amp;#160; &amp;#160;sizeof(DWORD)); // - Размер сигнатуры&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.write((PSTR)&amp;amp;Record-&amp;gt;Signature.Hash,&amp;#160; 4 *&amp;#160; sizeof(DWORD)); // - Контрольная сумма&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.write((PSTR)&amp;amp;Record-&amp;gt;NameLen, sizeof(BYTE));&amp;#160; &amp;#160; &amp;#160; &amp;#160;// - Размер имени&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.write((PSTR)Record-&amp;gt;Name, Record-&amp;gt;NameLen); // - Имя&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Смещаемся к числу записей&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.seekp(3, ios::beg);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Увеличиваем счётчик записей&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; this-&amp;gt;RecordCount++;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.write((PSTR)&amp;amp;this-&amp;gt;RecordCount, sizeof(DWORD));&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; return true;&lt;br /&gt;}&lt;/p&gt;
						&lt;p&gt;При открытии файла, если файл не найден, создается новый файл, и в него записывается заголовок файла (сигнатура и число записей).&lt;br /&gt;Если же файл существует, то происходит проверка сигнатуры файла и чтение числа записей.&lt;/p&gt;
						&lt;p&gt;Функция addRecord в качестве параметра принимает ссылку на структуру добавляемой записи.&lt;br /&gt;Сначала происходит перемещение в конец файла (новые записи дописываются в конец файла).&lt;br /&gt;Затем происходит запись данных в файл согласно оговорённому выше формату.&lt;br /&gt;После записи происходит увеличение счётчика записей.&lt;/p&gt;
						&lt;p&gt;Класс чтения записей немного проще.&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;// &lt;br /&gt;// - CAVBFileReader&lt;br /&gt;// &lt;br /&gt;bool&amp;#160; &amp;#160; CAVBFileReader::open(PCSTR FileName){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(FileName == NULL) return false;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Если файл не найден, то создаем его прототип&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(isFileExist(FileName)){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.open(FileName, ios::in | ios::out | ios::binary);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!hFile.is_open()) return false;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Проверка сигнатуры&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; CHAR&amp;#160; &amp;#160; Sign[3];&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.read((PSTR)Sign, 3);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(memcmp(Sign, &amp;quot;AVB&amp;quot;, 3)){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.close();&amp;#160; // - Это чужой файл&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return false;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Читаем число записей&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.read((PSTR)&amp;amp;this-&amp;gt;RecordCount, sizeof(DWORD));&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }else{ return false; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; return true;&lt;br /&gt;}&lt;/p&gt;
						&lt;p&gt;bool&amp;#160; &amp;#160; CAVBFileReader::readNextRecord(PSAVRecord Record){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(Record == NULL || !hFile.is_open()) return false;&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.read((PSTR)&amp;amp;Record-&amp;gt;Signature.Offset,&amp;#160; &amp;#160; &amp;#160; sizeof(DWORD)); // - Смещение сигнатуры&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.read((PSTR)&amp;amp;Record-&amp;gt;Signature.Lenght,&amp;#160; &amp;#160; &amp;#160; sizeof(DWORD)); // - Размер сигнатуры&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.read((PSTR)&amp;amp;Record-&amp;gt;Signature.Hash,&amp;#160; 4 *&amp;#160; &amp;#160;sizeof(DWORD)); // - Контрольная сумма&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.read((PSTR)&amp;amp;Record-&amp;gt;NameLen, sizeof(BYTE));&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Размер имени&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; Record-&amp;gt;allocName(Record-&amp;gt;NameLen);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hFile.read((PSTR)Record-&amp;gt;Name, Record-&amp;gt;NameLen);&amp;#160; // - Имя&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; return true;&lt;br /&gt;}&lt;br /&gt;В данном случае, если при попытке открытия файла выясняется, что файл не существует, функция вернет значение false, свидетельствующее об ошибке.&lt;br /&gt;Чтение записей происходит последовательно и обеспечивается функцией readNextRecord, которая в качестве параметра принимает ссылку на структуру записи, в которую будут прочитаны данные из файла.&lt;br /&gt;&lt;/p&gt;
						&lt;p&gt;На этом написание общего кода закончено.&lt;br /&gt;Пора переходить к реализации программы создания записей и сканера.&lt;/p&gt;
						&lt;p&gt;Реализация программы для создания базы&lt;/p&gt;
						&lt;p&gt;Как было выяснено выше, сканнер без сигнатур не имеет смысла. Именно поэтому первым делом будет реализована программа для создания базы.&lt;/p&gt;
						&lt;p&gt;В качестве параметров программа будет принимать путь до файла зловреда, путь до файла базы, смещение последовательности в файле зловреда, размер последовательности и, наконец, имя зловреда.&lt;br /&gt;Аргументы передаются формате -A[Value], где A — это соответствующий ключ, а Value – значение.&lt;br /&gt;Обозначим все аргументы:&lt;br /&gt;-s	= Путь до файла зловреда&lt;br /&gt;-d	= Путь до файла базы&lt;br /&gt;-o	= Смещение последовательности&lt;br /&gt;-l	= Размер последовательности&lt;br /&gt;-n	= Имя файла&lt;/p&gt;
						&lt;p&gt;Алгоритм работы программы следующий:&lt;br /&gt;1. Открыть файл зловреда&lt;br /&gt;2. Перейти по указанному смещению&lt;br /&gt;3. Расчитать MD5-хэш последовательности байт&lt;br /&gt;4. Добавить запись в базу&lt;/p&gt;
						&lt;p&gt;Реализация алгоритма здесь приводиться не будет, т.к. не относится к теме статьи, но её можно найти в файле md5hash.cpp&lt;br /&gt;Здесь же мы просто объявим соответствующую функцию getMD5, которая принимает указатель на данные, их размер и указатель на буфер из 16 байт, куда будет записан хэш.&lt;/p&gt;
						&lt;p&gt;Код программы находится в файле avrec.cpp&lt;/p&gt;
						&lt;p&gt;Сначала подключим все необходимые заголовочные файлы и объявим функцию подсчёта MD5, а также напишем вспомогательную функцию, которая понадобится при разборе аргументов программы.&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;// - Необходимые включения&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;#include &amp;lt;windows.h&amp;gt;&lt;br /&gt;#include &amp;lt;avrecord.h&amp;gt;&lt;br /&gt;#include &amp;lt;AVBFile.h&amp;gt;&lt;/p&gt;
						&lt;p&gt;using namespace std;&lt;br /&gt; &lt;/p&gt;
						&lt;p&gt;//! Копирование аргумента&lt;br /&gt;bool copyArg(PCSTR Arg, DWORD Offset, PSTR Buffer, DWORD Size){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; int ArgLen = strlen(Arg) - Offset;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(ArgLen &amp;gt; Size - 1 || ArgLen &amp;lt;= 0) return false;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; memcpy(Buffer, (void*)((DWORD)Arg + Offset), ArgLen);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; Buffer[ArgLen] = 0x00;&lt;br /&gt;}&lt;/p&gt;
						&lt;p&gt;void getMD5(const void* pData, size_t nDataSize, PDWORD RetHash);&lt;br /&gt;Рассмотрим по частям главную функцию main, весь полезный код находится в ней.&lt;/p&gt;
						&lt;p&gt;Сначала происходит разбор аргументов. Вот он:&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;&amp;#160; cout &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Проверка числа аргументов&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(argc &amp;lt; 2){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;ttAvRec v1.0 by Av-School.ru&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;#160; &amp;#160; Usage:&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;#160; &amp;#160; &amp;#160; &amp;#160; avrec.exe [OPTIONS...]&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;#160; &amp;#160; Options:&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;#160; &amp;#160; &amp;#160; &amp;#160; -s[PATH]&amp;#160; &amp;#160; Source infected file&amp;quot;&amp;#160; &amp;#160; &amp;#160; &amp;lt;&amp;lt; endl &amp;lt;&amp;lt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;quot;&amp;#160; &amp;#160; &amp;#160; &amp;#160; -d[PATH]&amp;#160; &amp;#160; Output database file&amp;quot;&amp;#160; &amp;#160; &amp;lt;&amp;lt; endl &amp;lt;&amp;lt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;quot;&amp;#160; &amp;#160; &amp;#160; &amp;#160; -o[NUM]&amp;#160; &amp;#160; &amp;#160;Signature offset&amp;quot;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;lt;&amp;lt; endl &amp;lt;&amp;lt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;quot;&amp;#160; &amp;#160; &amp;#160; &amp;#160; -l[NUM]&amp;#160; &amp;#160; &amp;#160;Signature size&amp;quot;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;lt;&amp;lt; endl &amp;lt;&amp;lt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;quot;&amp;#160; &amp;#160; &amp;#160; &amp;#160; -n[NAME]&amp;#160; &amp;#160; Record name&amp;quot;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;&amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return 0;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Объект новой записи&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; SAVRecord&amp;#160; &amp;#160; &amp;#160; &amp;#160;Record;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; CHAR&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; SrcFile[256];&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; CHAR&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; DstFile[256];&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Разбор аргументов&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; for(int ArgID = 1; ArgID &amp;lt; argc; ArgID++){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Исходный путь&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!memcmp(argv[ArgID], &amp;quot;-s&amp;quot;, 2)){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!copyArg(argv[ArgID], 2, SrcFile, sizeof(SrcFile))){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;gt; Error in -s argument. Stop&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return 0;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Файл базы&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }else if(!memcmp(argv[ArgID], &amp;quot;-d&amp;quot;, 2)){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!copyArg(argv[ArgID], 2, DstFile, sizeof(SrcFile))){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;gt; Error in -d argument. Stop&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return 0;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Смещение сигнатуры&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }else if(!memcmp(argv[ArgID], &amp;quot;-o&amp;quot;, 2)){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; Record.Signature.Offset = atoi((PCSTR)((DWORD)argv[ArgID] + 2));&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Размер сигнатуры&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }else if(!memcmp(argv[ArgID], &amp;quot;-l&amp;quot;, 2)){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; Record.Signature.Lenght = atoi((PCSTR)((DWORD)argv[ArgID] + 2));&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Имя&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }else if(!memcmp(argv[ArgID], &amp;quot;-n&amp;quot;, 2)){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; int NameLen = strlen(argv[ArgID]) - 2;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(NameLen &amp;lt;= 0){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;gt; Error in -n argument. Stop&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return 0;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; Record.allocName(NameLen);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; copyArg(argv[ArgID], 2, Record.Name, NameLen + 1);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;Если задано слишком мало аргументов, то будет выведено сообщение об использовании программы, иначе происходит их &amp;quot;опознание&amp;quot;.&lt;br /&gt;Функция copyArg копирует в указанное место значение аргумента без ключа.&lt;/p&gt;
						&lt;p&gt;После того, как данные о записи получены, можно приступать к расчёту контрольной суммы сигнатуры.&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // &lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Открытие исходного файла&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; ifstream&amp;#160; &amp;#160; &amp;#160; &amp;#160; hSrcFile;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hSrcFile.open(SrcFile, ios::in | ios::binary);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!hSrcFile.is_open()){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;gt; Can&#039;t open source file. Stop.&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return 0;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Чтение данных для расчёта контрольной суммы&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; PBYTE&amp;#160; &amp;#160;Buffer = new BYTE[Record.Signature.Lenght];&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(Buffer == NULL){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;gt; Can&#039;t alloc memory for sign data. Stop.&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hSrcFile.close();&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return 0;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hSrcFile.seekg(Record.Signature.Offset, ios::beg);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hSrcFile.read((PSTR)Buffer, Record.Signature.Lenght);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Закрытие исходного файла&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hSrcFile.close();&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Расчёт хэша сигнатуры&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; getMD5(Buffer, Record.Signature.Lenght, Record.Signature.Hash);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Очистка буфера&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;Buffer;&lt;br /&gt;Сначала открываем файл, затем переходим к указанному смещению и вычисляем хэш.&lt;br /&gt;Всё просто.&lt;/p&gt;
						&lt;p&gt;И наконец, добавляем запись в файл базы, попутно выводя информацию в консоль.&lt;br /&gt;Для добавления используется класс CAVBFileWriter.&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // -&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Добавление сигнатуры&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;Record info:&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; printf( &amp;quot;&amp;#160; &amp;#160; Name:&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;%sn&amp;quot;, Record.Name);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; printf( &amp;quot;&amp;#160; &amp;#160; Offset:&amp;#160; &amp;#160; &amp;#160; &amp;#160;0x%x (%d)n&amp;quot;, Record.Signature.Offset, Record.Signature.Offset);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; printf( &amp;quot;&amp;#160; &amp;#160; Lenght:&amp;#160; &amp;#160; &amp;#160; &amp;#160;0x%x (%d)n&amp;quot;, Record.Signature.Lenght, Record.Signature.Lenght);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; printf( &amp;quot;&amp;#160; &amp;#160; CheckSumm:&amp;#160; &amp;#160; 0x%x%x%x%xn&amp;quot;, Record.Signature.Hash[0], Record.Signature.Hash[1], Record.Signature.Hash[2], Record.Signature.Hash[3]);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; CAVBFileWriter&amp;#160; hAVBFile;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hAVBFile.open(DstFile);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!hAVBFile.is_open()){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;gt; Can&#039;t open database file. Stop.&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return 0;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hAVBFile.addRecord(&amp;amp;Record);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; hAVBFile.close();&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;Record added.&amp;quot; &amp;lt;&amp;lt; endl;&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; return 0;&lt;br /&gt;На этом всё, программа готова. Можно компилировать :)&lt;br /&gt;А пока она компилируется, переходим к написанию самого сканера!&lt;/p&gt;
						&lt;p&gt;Реализация сканера&lt;/p&gt;
						&lt;p&gt;Наконец-то добрались и до главной цели — сканера.&lt;br /&gt;Сканер пока будет просто проверять, является ли файл вредоносным или нет.&lt;br /&gt;Лечение, удаление, карантин оставим на потом.&lt;br /&gt;Файл с базой должен находиться в одной папке со сканером и называться avbase.avb&lt;br /&gt;Программа принимает один-единственный параметр — путь до папки, в которой необходимо провести проверку.&lt;br /&gt;Кода в сканере будет немного больше, но в целом всё так же просто.&lt;/p&gt;
						&lt;p&gt;Алгоритм работы следующий:&lt;br /&gt;1. Загрузка файла базы&lt;br /&gt;2. Получение списка файлов в указанной папке&lt;br /&gt;3. Если это файл — проверяем. Если папка — рекурсивно переходим к пункту 2.&lt;/p&gt;
						&lt;p&gt;Загрузка файла базы будет происходить в специальную структуру SAVRecordCollection, которую мы объявим, несмотря на то, что можно было использовать стандартный vector или другой контейнер.&lt;/p&gt;
						&lt;p&gt;Проверка файла сводится к простому перебору всех сигнатур.&lt;br /&gt;Если сигнатура присутствует, то сообщаем, что файл злой, в противном случае сообщаем, что всё хорошо.&lt;/p&gt;
						&lt;p&gt;А теперь ближе к коду :)&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;#include &amp;lt;windows.h&amp;gt;&lt;/p&gt;
						&lt;p&gt;#include &amp;lt;avrecord.h&amp;gt;&lt;br /&gt;#include &amp;lt;AVBFile.h&amp;gt;&lt;br /&gt; &lt;/p&gt;
						&lt;p&gt;using namespace std;&lt;/p&gt;
						&lt;p&gt;//! Коллекция записей&lt;br /&gt;typedef struct SAVRecordCollection{&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; SAVRecordCollection(DWORD RecordCount){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; this-&amp;gt;RecordCount&amp;#160; &amp;#160; = RecordCount;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; this-&amp;gt;Record&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;= new SAVRecord[this-&amp;gt;RecordCount];&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; ~SAVRecordCollection(){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; []&amp;#160; &amp;#160; &amp;#160; this-&amp;gt;Record;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; DWORD&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;RecordCount;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; PSAVRecord&amp;#160; &amp;#160; &amp;#160; Record;&lt;br /&gt;} * PSAVRecordCollection;&lt;/p&gt;
						&lt;p&gt;// - Коллекция записей&lt;br /&gt;PSAVRecordCollection&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; AVRCollection&amp;#160; &amp;#160;= NULL;&lt;/p&gt;
						&lt;p&gt;void&amp;#160; &amp;#160; processPath(PCSTR Path);&lt;br /&gt;void getMD5(const void* pData, size_t nDataSize, PDWORD RetHash);&lt;/p&gt;
						&lt;p&gt;функция processPath будет рассмотрена ниже.&lt;br /&gt;Итак, вначале стандартный разбор аргументов, а также получение пути для&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(argc &amp;lt; 2){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;ttAVScan v1.0&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;#160; &amp;#160; Usage:&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;#160; &amp;#160; &amp;#160; &amp;#160; avscan.exe [Path]&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;#160; &amp;#160; Arguments:&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;#160; &amp;#160; &amp;#160; &amp;#160; Path&amp;#160; &amp;#160; - Dirrectory to scan&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return 0;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; PCSTR&amp;#160; &amp;#160;SrcPath = argv[1];&amp;#160; &amp;#160; &amp;#160; // - Путь для сканирования&lt;br /&gt; &lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Получение пути до файла с базой&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; CHAR&amp;#160; &amp;#160; AVBPath[MAX_PATH];&amp;#160; &amp;#160; &amp;#160; // - Путь до папки с программой&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; memset(AVBPath, 0, MAX_PATH);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; PCHAR&amp;#160; &amp;#160;NamePtr;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; GetFullPathNameA(argv[0], MAX_PATH, AVBPath, &amp;amp;NamePtr);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; *NamePtr = 0x00;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; strcat_s(AVBPath, MAX_PATH, &amp;quot;avbase.avb&amp;quot;);&lt;br /&gt;Функция GetFullPathName в третьем параметре возвращает указатель на имя исполняемого файла, в начало которого мы ставим нуль-терминатор. Таким образом отрезая его и оставляя только путь до папки, в которой расположен исполняемый файл.&lt;/p&gt;
						&lt;p&gt;Следующий шаг — загрузка базы.&lt;/p&gt;
						&lt;p&gt;Код:&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Загрузка записей&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;Loading bases...&amp;quot;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; CAVBFileReader&amp;#160; hAVBFile;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!hAVBFile.open(AVBPath)){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;Can&#039;t open AV Bases file. Stop.&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return 0;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(hAVBFile.getRecordCount() &amp;gt; 0){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Создание коллекции&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; AVRCollection = new SAVRecordCollection(hAVBFile.getRecordCount());&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; for(DWORD RecID = 0; RecID &amp;lt; AVRCollection-&amp;gt;RecordCount; RecID++){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!hAVBFile.readNextRecord(&amp;amp;AVRCollection-&amp;gt;Record[RecID])){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;gt; Error loading record #&amp;quot; &amp;lt;&amp;lt; RecID &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hAVBFile.close();&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }else{&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; hAVBFile.close();&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;&amp;gt; Empty AV Base. Stop.&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return 0;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;t&amp;quot; &amp;lt;&amp;lt; AVRCollection-&amp;gt;RecordCount &amp;lt;&amp;lt; &amp;quot; records loaded.&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // &lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;Starting scan for viruses&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; endl;&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; processPath(SrcPath);&lt;br /&gt;Открываем файл, выделяем память под записи, после чего читаем в них информацию из файла.&lt;br /&gt;Если всё прошло хорошо, то будет вызвана функция processPath, которая выполняет рекурсивную проверку по указанному пути.&lt;/p&gt;
						&lt;p&gt;Вот так выглядит эта функция:&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt; &lt;/p&gt;
						&lt;p&gt;void&amp;#160; &amp;#160; processPath(PCSTR Path){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; string&amp;#160; SrcPath = Path;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; string&amp;#160; File;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; File&amp;#160; &amp;#160; = Path;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; File&amp;#160; &amp;#160; += &amp;quot;*.*&amp;quot;;&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; WIN32_FIND_DATAA&amp;#160; &amp;#160; &amp;#160; &amp;#160; FindData;&amp;#160; &amp;#160; &amp;#160; &amp;#160;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; HANDLE hFind = FindFirstFileA(File.c_str(), &amp;amp;FindData);&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; do{&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Пропускаем папки . и ..&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!strcmp(FindData.cFileName, &amp;quot;.&amp;quot;) || !strcmp(FindData.cFileName, &amp;quot;..&amp;quot;)) continue;&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; File = Path;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; File += &amp;quot;&amp;quot;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; File += FindData.cFileName;&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Если папка, то сканируем рекурсивно&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if((FindData.dwFileAttributes &amp;amp; FILE_ATTRIBUTE_DIRECTORY)){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; processPath(File.c_str());&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Иначе проверяем на вирусы&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }else{&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; checkFile(File.c_str());&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; } while(FindNextFileA(hFind, &amp;amp;FindData));&lt;br /&gt; &lt;/p&gt;
						&lt;p&gt;}&lt;br /&gt;Получаем список файлов и папок (за исключением папок &amp;quot;.&amp;quot; и &amp;quot;..&amp;quot;), при этом если нам попалась папка, то проводим рекурсивный просмотр, а если файл — проверяем его функцией checkFile.&lt;/p&gt;
						&lt;p&gt;Ниже приведён листинг функции checkFile&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt; &lt;/p&gt;
						&lt;p&gt;void&amp;#160; &amp;#160; checkFile(PCSTR FileName){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; FileName &amp;lt;&amp;lt; &amp;quot;t&amp;quot;;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Открываем файл&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; HANDLE&amp;#160; hFile = CreateFileA(FileName, FILE_READ_ACCESS, NULL, NULL, OPEN_EXISTING, NULL, NULL);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(hFile == INVALID_HANDLE_VALUE){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;Error&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Получаем размер файла&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; DWORD FileSize = GetFileSize(hFile, NULL);&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Отображаем файл в память&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; HANDLE&amp;#160; hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, NULL, FileSize, NULL);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(hFile == INVALID_HANDLE_VALUE){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;Error&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; CloseHandle(hFile);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; LPVOID&amp;#160; File = MapViewOfFile(hMap, FILE_MAP_READ, NULL, NULL, FileSize);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(File == NULL){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot;Error&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; CloseHandle(hMap);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; CloseHandle(hFile);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; return;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Поиск по сигнатурам&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; bool&amp;#160; &amp;#160; Detected = false;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; for(DWORD RecID = 0; RecID &amp;lt; AVRCollection-&amp;gt;RecordCount; RecID++){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; PSAVRecord&amp;#160; &amp;#160; &amp;#160; Record = &amp;amp;AVRCollection-&amp;gt;Record[RecID];&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Если файл слишком маленький, то пропускам запись&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(FileSize &amp;lt; (Record-&amp;gt;Signature.Offset + Record-&amp;gt;Signature.Lenght)) continue;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Переходим вычисляем контрольную сумму для сигнатуры&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; DWORD&amp;#160; &amp;#160;Hash[4];&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; getMD5((PBYTE)((DWORD)File + Record-&amp;gt;Signature.Offset), Record-&amp;gt;Signature.Lenght, Hash);&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; // - Детектим&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!memcmp(Hash, Record-&amp;gt;Signature.Hash, 4 * sizeof(DWORD))){&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; cout &amp;lt;&amp;lt; &amp;quot; DETECTEDt&amp;quot; &amp;lt;&amp;lt; Record-&amp;gt;Name &amp;lt;&amp;lt; endl;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; Detected = true;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; break;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; }&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; UnmapViewOfFile(File);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; CloseHandle(hMap);&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; CloseHandle(hFile);&lt;/p&gt;
						&lt;p&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; if(!Detected)&amp;#160; &amp;#160;cout &amp;lt;&amp;lt; &amp;quot;OK&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;Рассмотрим её подробнее.&lt;br /&gt;Во-первых, в функции вместо чтения файла использовано его отображение в память, при котором файл помещается в адресное пространство процесса, и для доступа к нему не требуется производить операции чтения или записи. Доступ осуществляется, как к обычному массиву.&lt;br /&gt;Данный подход выбран по той причине, что при проверке сигнатур требуется постоянно перемещаться по файлу согласно смещению сигнатуры.&lt;br /&gt;Перемещение по массиву намного быстрее перемещения по файлу. Также для расчёта хэша достаточно просто передать указатель на начало последовательности.&lt;br /&gt;При стандартном подходе потребовалось бы каждый раз считывать информацию из файла, что не только долго, но и просто неудобно.&lt;/p&gt;
						&lt;p&gt;Функция MapViewOfFile возвращает адрес, начиная с которого отображен файл.&lt;br /&gt;Этот адрес и является началом файла, или если представить файл как массив, то данный адрес будет началом массива.&lt;/p&gt;
						&lt;p&gt;Поиск сигнатуры выполняется следующим образом:&lt;br /&gt;В цикле перебираются все записи из коллекции.&lt;br /&gt;Если для записи сумма смещения сигнатуры и её размера меньше, чем размер файла (т.е. сигнатура помещается в файл), то производится хэширование последовательности данных.&lt;br /&gt;После этого производится сравнение полученного хэша с хэшем из сигнатуры.&lt;br /&gt;Если они совпадают, то это значит, что файл известен как опасный (или ложное срабатывание =) )&lt;/p&gt;
						&lt;p&gt;Осталось только скомпилировать и протестировать.&lt;/p&gt;
						&lt;p&gt;Код:&lt;br /&gt;avrec.exe -sVirus.vbs -davbase.avb -o253 -l280 -nVirus.VBS.Baby&lt;br /&gt;Проверяем:&lt;/p&gt;
						&lt;p&gt;Файл действительно детектируется.&lt;/p&gt;</description>
			<author>mybb@mybb.ru (Hrom)</author>
			<pubDate>Wed, 24 Jul 2013 16:41:34 +0400</pubDate>
			<guid>https://razrabotka.f-rpg.me/viewtopic.php?pid=2#p2</guid>
		</item>
	</channel>
</rss>
