Может быть множество причин, почему на том или ином компьютере вы не поставите антивирусное программное обеспечение: слабое железо или простое нежелание делить его с постоянно жрущим ресурсы антивирусом, уверенность в своих действиях на компьютере или дороговизна, особенно для серверных версий операционных систем. С последним, кстати, постоянно сталкиваются пользователи виртуальных серверов (так называемых VPS / VDS), конфигураций большинства которых едва хватает для нормальной работы современного браузера, а провайдер предоставляет исключительно серверную версию Windows.
Будучи одним из таких пользователей, где далеко не везде установлен полноценный антивирус, постоянно приходится залазить на онлайн ресурсы для проверки тех или иных файлов. Оптимизировать этот процесс я сегодня и решил.
Наиболее простым и популярным среди таких ресурсов (и приятный лично мне) является virustotal.com, у которого есть открытое API и использование его от вас ничего не требует, кроме регистрации на сайте.
Идеальным вариантом для меня стала бы реализация с дополнительной кнопкой в контекстном меню Windows, которое появляется при клике правой кнопкой мыши по любому файлу.
Именно так мы и сделаем, в чём собственно нам поможет редактор реестра Windows.
Открываем путь
HKEY_CLASSES_ROOT\*\shell
И создаём новый раздел с желаемым названием кнопки, например, «Проверить на VirusTotal»
В этом разделе можно указать иконку для нашей кнопки. Её я взял непосредственно с сайта virustotal и сохранил по пути, который вы видите на картинке выше.
Далее создаём раздел «command», где в поле по умолчанию указываем путь к нашему приложению, которое и будет обрабатывать клик по кнопке в контекстном меню.
У меня получился путь
D:\Check_On_VirusTotal\check.exe 1990854a5b8b30998b8cb1ae1840d0a90c8adda12a53cdffca55d1e3c5d16a88 %1
Здесь через пробел указаны 3 значения:
- Адрес исполняемого файла
- Мой ключ API для virustotal, который я решил не вшивать жёстко в код приложения
- %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)
PahanMenski
24.05.2016 17:46+4Кстати, очень легко можно создать и безоконное приложение. Проще всего для этого создать в студии консольное приложение, после чего зайти в настройки проекта и поменять Output Type с Console Application на Windows Application.
XNoNAME
25.05.2016 08:43Надо было начинать с кода программы, а то я подумал, что это реализуется только правкой реестра и уже полез его править.
viktorzin
25.05.2016 15:43+1Рекомендую параметр %1 в реестре взять в кавычки, чтобы не было проблем с именами файлов, в которых имеются пробелы.
AlexeyKh
25.05.2016 15:44Спасибо, проблема действительно была, решил её таким образом
string fileName = string.Join(" ", args, 2, args.Length — 2)
Но с кавчками, однозначно, лучше… особенно если будет несколько пробелов )
Protos
26.05.2016 15:59а есть такой обработчик: перетягиваешь файл на иконку в трее и получается тоже в 1 клик?
Mr_Floppy
Вы переизобрели VirusTotal Windows Uploader
rub_ak
Самое интересное что с 2013 года никто инсталятор VirusTotal Windows Uploader никто не проверял на VirusTotal
AlexeyKh
Похоже на то, но поиграться с API и реестром Windows в очередной раз было приятно )