Создание антивируса своими руками

Недавно я прочитал статью Криса Касперски, посвященную VirusTotal’у, и всерьез загорелся идеей созданием такого сервиса. Почему бы и нет? Проблема малвари сейчас стоит довольно остро, а необходимость проверки одного, но весьма подозрительного файла появляется у пользователей с завидным постоянством.

Материалы и методы

Итак, что же нам нужно? Рассмотрим по пунктам.

  • Выделенный сервер. Не VDS, а именно Dedicated. Я успел отхватить себе сервак с Core Duo, 2 Гб RAM и безлимитным трафиком (10 Мб/с) за $100 в месяц. Средние же расценки сейчас заметно выше :).
  • Опыт работы с Linux — в качестве платформы я выбрал именно эту ОС, поскольку виндовый (особенно — высоконагруженный) сервер кажется мне не очень хорошей идеей. Лично я выбрал Ubuntu Server 10.04.
  • Знание C++/Qt. Писать мы будем именно на нем, поскольку для линукса приплюснутый Си вполне логичен, а Qt я выбрал, потому что в нем есть очень удобные классы для взаимодействия с процессами.
  • Знание PHP + AJAX. Ну а как иначе?
  • Умение верстать/рисовать, либо человек, который это сделает. Без хорошего дизайна сервис долго не проживет.
  • Установочные пакеты антивирусов и дипломатические навыки для общения с антивирусными компаниями.

Перейдем к практике

Набросаем небольшой план. Что должна делать наша софтина? Она запускает консольный сканер антивируса, читает и парсит его stdout. Чтобы понять стиль поведения антивируса, запустим его с параметром —help, внимательно вкурим в результат, а затем скормим ему здоровый и зараженный (поочередно, естественно) файлы и сравним вывод антивируса. Как это будет реализовано в софте?

Как тебе уже известно (если ты читал мою статью в майском ][ ), в Qt есть очень полезный класс QProcess, который служит для запуска внешних программ. Он умеет запускать программу, получать ее вывод и сообщать нам о завершении программы. Но нам этого недостаточно, поэтому мы немного допишем класс. Что будет в новом классе? Он должен собирать выведенный в консоль текст по мере его поступления и генерировать сигнал с этим самым выводом и именем процесса при его завершении. Сказано — сделано:

Как видишь, класс наследуется от QProcess. Рассмотрим
методы и слоты этого класса:

Как нетрудно догадаться, этот метод служит для запуска программы и сохранения имени процесса перед запуском. Код, заключенный в слот onReadyRead, просто аппендит прочитанный вывод к уже имеющемуся, а слот onFinished() генерирует сигнал emit onAvFinished(this, avName, avBuffer, exitCode). Все тривиально, поэтому я предлагаю двигаться дальше, к главному классу:

Разберем код по порядку. За запуск антивирусов у нас отвечает функция startCheck():

В параметр fName, как нетрудно догадаться, передается имя файла, который мы будем проверять. В данной статье я буду показывать взаимодействие только с одним антивирусом — дальше ты сможешь продолжить сам.

Кстати говоря, знаешь, почему параметр передается в таком странном виде (const QString &fName)? Дело в том, что при передаче параметра по значению (то есть, например, просто QString fName) в стек переменная будет копироваться целиком, и это совсем не гуд, а при передаче по указателю (QString fName) в стек будет копироваться только адрес переменной. Минус в том, что мы будем вынуждены работать с ней как с указателем. Ну а передача по константной ссылке — const QString &fName — это комбинация двух предыдущих методов. В итоге в стек копируется только указатель на переменную (то есть sizeof(void*)), и работаем мы с ней, как с обычной переменной.

Не обошлось, конечно же, и без ложки дегтя — мы не можем изменять переменную в нашей функции. А оно нам надо? В данном случае — нет, ну а если понадобится, то можно завести переменную в самой функции и скопировать ее туда. «Некрасиво», — скажешь ты. Может быть, зато очень эффективно — функция будет вызываться намного быстрее, если все переменные влезут в регистры (при условии юзанья фастколла).

Ладно, лирику в сторону, поехали дальше.
Наверное, ты обратил внимание на qDebug(). Что это? Это поток для вывода отладочной информации в Qt (очень удобная вещь, между прочим).
Далее мы создаем процесс и привязываем его к имеющимся слотам с помощью функции createProcess(). Она абсолютно тривиальна:

Как только процесс завершается, начинает свою работу слот onAvFinished().
И снова введу тебя в курс дела: avs — это QMap из typedef QPair<QString, QString > QResultPair;
Он содержит пары «имя процесса; название антивируса» для простого распознавания завершившегося процесса.

Одна из важнейших функций в нашей софтине — parseOutput(). Как видно из названия, она парсит вывод антивируса при его завершении и выдает результат сканирования. Выглядит она так:

Тут происходит самый обыкновенный разбор строки. Если мы не находим какого-то ключевого слова — значит, ошибка. Если находим слово, соответствующее отрицательному результату (то есть, файл не заражен) — возвращаем ОК. Иначе — копируем вывод антивируса и возвращаем его.

Вернемся к слоту onAvFinished(). После парсинга вывода мы пишем
результат в файл в виде HTML-таблицы для удобного вывода в браузер. Все! Костяк сервиса создан. Встает вопрос: «А как на этом можно заработать»? На мой взгляд, есть два варианта:

  1. «Приватная» версия сервиса. Не отправлять на проверку файлы за небольшую денежку. У меня — 1 цент за 1 антивирус. Как реализовать? Iptables тебе в руки!
  2. Реклама. Можно размещать баннеры тематических форумов/сервисов и/или контекстную рекламу от того же гугла.
  3. Продажа лицензионных версий антивирусов.

Заключение

Как показала практика, самый напряжный момент в разработке — создание сайта. Ненавижу PHP! После понятного и логичного C++ разработка на PHP + Ajax подобна пытке, но в итоге использование в качестве Ajax-библиотеки Sajax, а SQL-базы SQLite решило все мои проблемы.

На этом позволь свернуть мое краткое повествование и пожелать тебе удачной разработки. А будут вопросы — пиши. Мыла не указываю, поскольку настоящий хакер всегда и так сможет меня найти :)..

«Слот» onAvFinished()

Покажи эту статью друзьям:
Источник: https://xakep.ru/2011/01/12/54473/

Предыдущая статья: пескоблоки своими руками состав

Следущая статья: букет своими руками в вазу

Лучшие статьи: