Показать полную графическую версию : Получение контрольных сумм файлов (MD5, и т.д.) и их проверка в Online-сервисах
Браузер отправляет запрос на http://www.virustotal.com/search.html (POST запрос chain=md5). Дальше происходит редирект на результат.
какую версию Builder'a используете? »При написании использую
Borland C++ Builder 6.0 Enterprise SuiteДело в том, что собственно программу я написал давно, там 2 500 строк, и переписывать программу для CodeGear C++ Builder 2009 уже попросту нереально. Вот и хочу сделать дополнительный детект по контрольной сумме, тем более что в логах, анализируемых программой MD5 уже есть.Какую версию Indy используете? »Версия Indy в билдере 6.0 такая - 8.0.25
Попробуйте потестить в CodeGear C++ Builder 2009. »Да, там всё без проблем, получаю результат контрольной суммы, версия Indy - 10.2.5
Скачал новую Indy10 пробовал установить по инструкции (http://psvlab.blogspot.com/2010/04/ssl-indy-10-open-ssl.html), правда, ничего с установкой компонентов не получилось :( Как её правильно установить? Я удалил старую Indy, запустил файл .bpk, компиляция нормально - Install в ошибку.
Я устанавливал по этой (http://forum.vingrad.ru/forum/topic-247406/0.html) инструкции. Эту инструкцию можно выполнять с 3-его пункта, но перед этим нада удалить старые Indy компоненты.
но перед этим нада удалить старые Indy компоненты. »Так и сделал, потом снёс билдер и заново установил без Indy
Установил Indy по инструкции, палитра компонентов появилась, но даже простой вызов
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Label1->Caption = IdHTTP1->Version;
}
//---------------------------------------------------------------------------Выпадает в ошибку
[Linker Error] Unresolved external '__fastcall Idbasecomponent::TIdBaseComponent::GetVersion()' referenced from C:\PROGRAM FILES\BORLAND\CBUILDER6\PROJECTS\UNIT1.OBJ
А вы указали пути ко всем нужным файлам?
Попробуйте скомпилировать в release версии.
А вы указали пути ко всем нужным файлам? »Всё сделал по инструкции
5. Запустил батник "C:\indy10\Lib\Fullc6.bat".
6. Создается папка "C:\indy10\C6", идёт компилирование Indy 10...
7. Дальше распихиваю по папкам:
*.hpp -> "C:\Program files\Borland\CBuilder6\Include"
*.lib, *.bpi -> "C:\Program files\Borland\CBuilder6\Lib"
*.dcp, *.lsp, *.bpl -> "C:\Program files\Borland\CBuilder6\Bin"
8. Добавляю dclIndyCore60.bpl и dclIndyProtocols60.bpl в палитру компонентов ("Component" -> "Install packages.." -> "Add")Попробуйте скомпилировать в release версии. »Без разницы.
Так. Установил Indy, версия 10.2.3 параллельно пришлось ещё вручную закинуть в папку Bin файлы indy60.bpl и dclindy60.bpl. Проект собрал. Собирается только при релиз версии. Без этого вылетает окно отладчика.
Правда ожидаемого результата почему-то нет.
Запустил я exe'шник и он мне выдал HTTP/1.0 303 See Other. Это означает, что происходит редирект, но метод OnRedirect у HTTPQuery не назначен. Во вкладке Events (события) класса HTTPQuery назначил событию OnRedirect функцию:
void __fastcall TForm1::HTTPQueryRedirect(TObject *Sender,
AnsiString &dest, int &NumRedirect, bool &Handled,
AnsiString &VMethod)
Скомпилил и всё заработало.
ganselo, Точно, совсем уже я мозги потерял, удалял старую версию компонента, а видимо нужно было переназначить метод на новую. Заработало всё как надо. :up:
Только мне бы хотелось, чтобы во время работы не выскакивали лишние MessageBox
catch(EIdSocketError &se)
{
ShowMessage(se.Message);
}
catch(Exception &e)
{
ShowMessage(e.Message);
}
ShowMessage(response->DataString);Чтобы запрос был "тихий", запросили, и вернули ответ, если ответа нет, чтобы вернулся ноль. И ещё, мне вывод классикации различными антивирусами тоже не нужен, но его убрать не проблема, мне нужно число в самом результате Result: 32 /40 (80.0%) выделил его красным. Я хочу сделать ComboBox с выбором значений: 20,30,...,80 и выше, при выборе значения из списка, должно происходить сравнение с проверкой результатов, и на этом основании, файл будет помещаться в команду карантина и удаления.
Только мне бы хотелось, чтобы во время работы не выскакивали лишние MessageBox »
Ну ошибки в любом случае нужно ловить.
не нужно число в самом результате Result: 32 /40 (80.0%) выделил его красным. Я хочу сделать ComboBox с выбором значений: 20,30,...,80 и выше, при выборе значения из списка, должно происходить сравнение с проверкой результатов, и на этом основании, файл будет помещаться в команду карантина и удаления. »
Это легко сделать:
В обработчике события OnRedirect после того как распарсили результат вставляем это:
int antivirus_count = result.size();
int true_res = 0;
int procent;
for(TResult::iterator i = result.begin(); i != result.end(); i++)
{
if(i->result != "-")
{
true_res ++;
}
}
procent = true_res*100/antivirus_count; //получили процент
if(ComboBox->Text.ToInt() == procent) { //поместить в карантин }
else { //вирусов нет}
ganselo, О, отлично. :up: Допустим мне теперь нужно проверить не один MD5 а несколько, заранее не известно сколько, но предположим несколько, я придумал так
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TStringList *post = new TStringList;
TStringStream *response = new TStringStream("");
TStringList *lHash = new TStringList;
// Просто для примера наполнили список контрольными суммами,
// в идеале так и будет, проверка файлов которые
// Имеют контрольную сумму и которые не прошли по остальным базам
lHash->Add("0045BCBD3047391E47F3B56DC7C7F2F2");
lHash->Add("00636A27AF20104CC13E8DDE7DEE64E7");
lHash->Add("012995DAD105ACEFBF05591271CD2F54");
for(int i = 0; i < lHash->Count; i++){
post->Clear();
post->Add("chain=" + lHash->Strings[i]);
try{
HTTPQuery->Post("http://www.virustotal.com/search.html", post, response);
}
catch(EIdSocketError &se){
ShowMessage(se.Message);
}
catch(Exception &e){
ShowMessage(e.Message);
}
}
delete HTTPQuery, post, response, lHash;
}
//---------------------------------------------И вот такой ещё вопросик, когда идёт первая проверка, то MD5 проверяются без проблем, а когданажать второй раз кнопку Проверить, то появляется окошко с сообщением EAccessViolation - столько раз, сколько содержиржится записей в списке lHash. Как бы сделать, чтобы можно было повторно проверять?
Ну ошибки в любом случае нужно ловить. »Просто если проверяемых файлов будет 10-15, нажимать каждый чтобы закрыть окошко, неудобно. :)
Проблема в этой строчке:
delete HTTPQuery, post, response, lHash;
Мы удаляем HTTPQuery и при повторном нажатии кнопки обращаемся к пустому указателю.
Нужно так:
delete post, response, lHash;
P.S Не помешало бы проверку на вирусы засунуть в отдельный поток, а то TIdHTTP (как и все Indy компоненты) работает в синхронном режиме и по этому во время проверки форма не активна.
P.S Не помешало бы проверку на вирусы засунуть в отдельный поток, а то TIdHTTP »Я планировал делать так.
Проверяем файлы по уже имеющимся спискам (Malware, Hash) и если по имеющимся спискам найдены вредные файлы, то проверку такого файла не делать на VT, а если по спискам не найдено, и у файла есть MD5 - то добавить файл с MD5 в список(HashVT) для дальнейшей проверки. В итоге, после прогона, получается список уже явно удаляемых(MalwareDelete) по имеющимся спискам и список подготовленых к проверке на VT. Вот теперь проверяем этот список HashVT на VT и если он удовлетворяется по условию процента, то файл добавляется в список подготовленых к удалению MalwareDelete. И теперь как бы ждём вердикта VT, правда вы говорите что форма неактивна, да, действительно неактивна, я только что проверил, сначала не обратил внимание.
А как делать в отдельном потоке?
//добавляем новую функцию. Здесь и будет обращение к серверу
DWORD WINAPI QueryThread(LPVOID lpParam)
{
TStringList *post = new TStringList;
TStringStream *response = new TStringStream("");
TStringList *lHash = new TStringList;
lHash->Add("0045BCBD3047391E47F3B56DC7C7F2F2");
lHash->Add("00636A27AF20104CC13E8DDE7DEE64E7");
lHash->Add("012995DAD105ACEFBF05591271CD2F54");
for(int i = 0; i < lHash->Count; i++){
post->Clear();
post->Add("chain=" + lHash->Strings[i]);
try{
Form1->HTTPQuery->Post("http://www.virustotal.com/search.html", post, response);
}
catch(EIdSocketError &se){
MessageBox(0, se.Message.c_str(), 0, 0);
}
catch(Exception &e){
MessageBox(0, e.Message.c_str(), 0, 0);
}
Form1->HTTPQuery->Disconnect();
}
delete post, response, lHash;
}
В обработчике кнопки создаём поток:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HANDLE hThread;
hThread = CreateThread(0, 0, QueryThread, 0, 0, 0);
if(hThread == INVALID_HANDLE_VALUE) {
ShowMessage("Can't create thread");
return;
}
CloseHandle(hThread);
}
Есть в Indy компонент TIdAntiFreeze. Можно попробовать его кинуть на форму и по идеи форма не должна зависать, но у меня, когда я ложу на форму и компилю выскакивает AccessViolation. Мб у вас заработает.
но у меня, когда я ложу на форму и компилю выскакивает AccessViolation. Мб у вас заработает »Точно такой же результат - AccessViolation
Ещё, если знаете, такой вопрос. Это выходной лог, всё работает
Удаляем файл =
-----------
http://www.virustotal.com/file-scan/report.html?id=e979fcf20233baff3e9c8c27921bd4a215a45236856bf32b2a01ceae988900dc-1265219152
80
-----------
Удаляем файл =
-----------
http://www.virustotal.com/file-scan/report.html?id=b570351e7bc3ca00ba47bd8b5e0d2c63814d1aefd786546bd22ad6e8524efc74-1266477769
92
-----------
Вируса нет =
-----------
http://www.virustotal.com/file-scan/report.html?id=2bac20016422c9a2ea82aac7386c0147bd0ee96ccf3db3af3127a64348754787-1217825795
8
-----------Но почему тогда выдаёт окошко с ошибкой после каждого прохода с сообщением, не знаете?
HTTP/1.0 200 OK
try{
Form1->HTTPQuery->Post("http://www.virustotal.com/search.html", post, response);
}
catch(EIdHTTPProtocolException &se)
{
switch(se.ErrorCode)
{
case 200: //всё ок
break;
case 303:
break; //редирект
case 404: //404 not found
break;
}
}
catch(EIdSocketError &se){
MessageBox(0, se.Message.c_str(), 0, 0);
}
ganselo, Ещё неучтённый нюанс, всплыл при тестировании, допустим результата проверки нет, вот, к примеру такая контрольная сумма
564dfacf47f4d215b76a5eb3770a83d4Если проверять на сайте, то адрес странички становится таким
http://www.virustotal.com/search.html?notfound=1
Добавляем в список для проверки и имитируем проверку
...
lHash->Add("564dfacf47f4d215b76a5eb3770a83d4");
...Программа жёстко вылетает в ошибку и закрывается. Как с этим бороться? Хотелось бы такесли ответа\результата нет, чтобы вернулся ноль »
Вставить в начало функции TForm1::HTTPQueryRedirect проверку:
if(dest == "http://www.virustotal.com/search.html?notfound=1")
{
MessageBox(0, "Вирусов нет!", 0, 0);
return;
}
ganselo, В общем, всё отлично, только не пойму как в отдельный поток передавать список lHash с отобраными на проверку MD5если по спискам не найдено, и у файла есть MD5 - то добавить файл с MD5 в список(HashVT) для дальнейшей проверки и в итоге в конце проверки лога, у нас формируется список lHash содержащий MD5 подготовленых к проверке на VT»
В функции создающей отдельный поток в качестве тестирования я создавал список в самой функции, но в реальности нужно передавать список в котором уже будут отобраны все необходимые для проверки, MD5.
//добавляем новую функцию. Здесь и будет обращение к серверу
DWORD WINAPI QueryThread(LPVOID lpParam)
{
TStringList *post = new TStringList;
TStringStream *response = new TStringStream("");
TStringList *lHash = new TStringList;
lHash->Add("564dfacf47f4d215b76a5eb3770a83d4");
lHash->Add("0045BCBD3047391E47F3B56DC7C7F2F2");
lHash->Add("00636A27AF20104CC13E8DDE7DEE64E7");
lHash->Add("012995DAD105ACEFBF05591271CD2F54");
...
Хотелось бы чтобы было
...
for(int i = 0; i < GlobalList->Count; i++){
// Здесь разная проверка отсеивания и в итоге присваивание MD5 суммы
MD5 = GlobalList->Strings[i]; // Присваивание контрольной сумы от файла переменной. Можно и сразу в список, но пока так
}
lHash->Add(MD5); // Добавление контрольной суммы в список
...
// В итоге после прохода списка GlobalList
// список lHash будет содержать некое количество отобраных MD5 на проверку
...
Как передать функции QueryThread список lHash? Или какой можно придумать выход ещё?
HANDLE hThread;
//тут подготавливаем lHash
hThread = CreateThread(0, 0, QueryThread, lHash, 0, 0); //тут передаём его в поток
if(hThread == INVALID_HANDLE_VALUE) {
ShowMessage("Can't create thread");
return;
}
CloseHandle(hThread);
а теперь получаем данные из потока
DWORD WINAPI QueryThread(LPVOID lpParam)
{
TStringList *lHash = (TStringList *)lpParam;
return 0;
}
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.