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

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

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




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

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



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



У меня получился путь
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<string, string, string> 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 запроса в минуту.
Поделиться с друзьями
-->

Комментарии (17)


  1. Mr_Floppy
    24.05.2016 17:12
    +11

    Вы переизобрели VirusTotal Windows Uploader


    1. rub_ak
      24.05.2016 17:40

      Самое интересное что с 2013 года никто инсталятор VirusTotal Windows Uploader никто не проверял на VirusTotal


    1. AlexeyKh
      24.05.2016 17:45
      +2

      Похоже на то, но поиграться с API и реестром Windows в очередной раз было приятно )


  1. burrdarr
    24.05.2016 17:40
    +2

    Извиняюсь за буквоедство, но это два клика, а не один…


    1. AlexeyKh
      24.05.2016 17:42
      +3

      Спасибо за замечание )


    1. nidalee
      25.05.2016 15:44
      -1

      Зашел ради этого комментария! Жаль, что опередили. Хотя я бы удивился, если бы никто этого не написал.


  1. PahanMenski
    24.05.2016 17:46
    +4

    Кстати, очень легко можно создать и безоконное приложение. Проще всего для этого создать в студии консольное приложение, после чего зайти в настройки проекта и поменять Output Type с Console Application на Windows Application.


    1. AlexeyKh
      24.05.2016 17:46

      Спасибо!


    1. chelaxe
      25.05.2016 08:02

      Я обычно создаю Windows Application и правлю Program.cs


  1. g000phy
    24.05.2016 19:26

    Спасибо за подсказку. Погуглил и нашел для mac. Даже не думал, что есть…


  1. XNoNAME
    25.05.2016 08:43

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


  1. viktorzin
    25.05.2016 15:43
    +1

    Рекомендую параметр %1 в реестре взять в кавычки, чтобы не было проблем с именами файлов, в которых имеются пробелы.


    1. AlexeyKh
      25.05.2016 15:44

      Спасибо, проблема действительно была, решил её таким образом
      string fileName = string.Join(" ", args, 2, args.Length — 2)
      Но с кавчками, однозначно, лучше… особенно если будет несколько пробелов )


  1. AikoKirino
    26.05.2016 15:39

    Можно было просто написать POSH script.


  1. Protos
    26.05.2016 15:56

    а если перетягивать файл на иконку в трее, то будет тоже в 1 клик. Или нет обработчика на такое событие?


    1. AlexeyKh
      26.05.2016 16:32

      Думаю, менее удобно что-то куда-то перетягивать…
      Но с одним кликом вы правы, будет так.


  1. Protos
    26.05.2016 15:59

    а есть такой обработчик: перетягиваешь файл на иконку в трее и получается тоже в 1 клик?