VirusTotal: проверяем файлы на вирусы в один клик

26280b114b444879b550b6ff5dacacc1.png

Может быть множество причин, почему на том или ином компьютере вы не поставите антивирусное программное обеспечение: слабое железо или простое нежелание делить его с постоянно жрущим ресурсы антивирусом, уверенность в своих действиях на компьютере или дороговизна, особенно для серверных версий операционных систем. С последним, кстати, постоянно сталкиваются пользователи виртуальных серверов (так называемых VPS / VDS), конфигураций большинства которых едва хватает для нормальной работы современного браузера, а провайдер предоставляет исключительно серверную версию Windows.

Будучи одним из таких пользователей, где далеко не везде установлен полноценный антивирус, постоянно приходится залазить на онлайн ресурсы для проверки тех или иных файлов. Оптимизировать этот процесс я сегодня и решил.

Наиболее простым и популярным среди таких ресурсов (и приятный лично мне) является virustotal.com, у которого есть открытое API и использование его от вас ничего не требует, кроме регистрации на сайте.
Идеальным вариантом для меня стала бы реализация с дополнительной кнопкой в контекстном меню Windows, которое появляется при клике правой кнопкой мыши по любому файлу.

94b4205200c444d2af05760d2b72ef9b.png

Именно так мы и сделаем, в чём собственно нам поможет редактор реестра Windows.
Открываем путь

HKEY_CLASSES_ROOT\*\shell


И создаём новый раздел с желаемым названием кнопки, например, «Проверить на VirusTotal»

28dcd28bdcbf4d589ea30014389d2165.png

В этом разделе можно указать иконку для нашей кнопки. Её я взял непосредственно с сайта virustotal и сохранил по пути, который вы видите на картинке выше.
Далее создаём раздел «command», где в поле по умолчанию указываем путь к нашему приложению, которое и будет обрабатывать клик по кнопке в контекстном меню.

f3517afe8a304f03b7c5bffe455c2ebd.png

У меня получился путь

D:\Check_On_VirusTotal\check.exe 1990854a5b8b30998b8cb1ae1840d0a90c8adda12a53cdffca55d1e3c5d16a88 %1


Здесь через пробел указаны 3 значения:

  1. Адрес исполняемого файла
  2. Мой ключ API для virustotal, который я решил не вшивать жёстко в код приложения
  3. %1 — будет при передаче на наше приложение полным путём до проверяемого файла

После того, как контекстное меню настроено можно переходить ко второму шагу — создание программы обработчика.
Я сделал её на обычном Windows Forms, где весь код засунул в метод Form_Load. Изначально была мысль сделать консольным приложением, однако при вызове оно бы мелькало до завершения работы, а мне этого не хотелось. В свойствах фомы на WinForm можно легко задать такие параметры как ShowInTaskbar: false, ShowIcon: false и Opacity:0%
Код получился такой:

private void Form1_Load(object sender, EventArgs e){
    string[] args = Environment.GetCommandLineArgs();//берём массив переданных параметров
    if (args != null && args.Length >= 3){

        string apiKey = args[1].Trim(), //получаем из аргументов ключ API для virustotal.com
                fileName = string.Join(" ", args, 2, args.Length - 2);//получаем путь к проверяемому файлу

        if (string.IsNullOrEmpty(apiKey)) MessageBox.Show("Пустой ключ API");
        else if (!File.Exists(fileName)) MessageBox.Show("Файл не найден");
        else if (new FileInfo(fileName).Length > 128 * 1024 * 1024) MessageBox.Show("Размер файла превышает 128 МБ");
        else{

//простая функция для получения значения параметра из строки в формате JSON
Func getJsonValue = delegate(string source, string key){
    int from = source.IndexOf(key + "\":"), to = from > 0 ? source.IndexOf(",", from) : -1;
    if (from > 0 && to > 0)
        return source.Substring(from + (key + "\":").Length, to - from - (key + "\":").Length).Replace("\"", "").Trim();
    return null;
};

var nvc = new NameValueCollection();
nvc.Add("apikey", apiKey);
using (var webClient = new WebClient() { QueryString = nvc }){
    webClient.Headers.Add("Content-type", "binary/octet-stream");
    //загружаем выбранный файл на сервер virustotal
    string uploadResult =
        Encoding.Default.GetString(webClient.UploadFile("https://www.virustotal.com/vtapi/v2/file/scan", "post", fileName));
    //получаем в результате уникальный для данного файла ID (он же SHA256)
    string resourceId = getJsonValue(uploadResult, "resource");
    if (!string.IsNullOrEmpty(resourceId)){
        nvc = new NameValueCollection();
        nvc.Add("resource", resourceId);
        //проверяем нет ли уже сразу результатов для данного файла на случай если он проверялся кем-то ранее
        string checkResult =
            Encoding.Default.GetString(webClient.UploadValues("https://www.virustotal.com/vtapi/v2/file/report", nvc));
        string response_code = getJsonValue(checkResult, "response_code");
        //запускаем процесс браузера, используемого по умолчанию
        System.Diagnostics.Process.Start(response_code == "1" ?
                //если кто-то этот файл уже проверял, то просто открываем страницу с результатами
                "https://www.virustotal.com/file/" + resourceId + "/analysis/" :
                //если файл до этого не проверялся, то открываем страницу и ждём уже на ней проверки файла
                getJsonValue(uploadResult, "permalink")
            );
    }
}

        }
    }
    this.Close();//закрываем приложение
}


Если будете пробовать, используйте свой ключ API, они не безлимитные и имеют ограничение по умолчанию в 4 запроса в минуту.

© Habrahabr.ru