Эвристические анализаторы кода
Эвристическим анализатором кода называется набор подпрограмм, ана- Основные термины: Событие - это совокупность кода или вызов определенной функ- Цепочка связных событий - это набор событий, которые должны Цепочка несвязных событий - это набор событий, которые должны Эвристическая маска - набор действий, выявленных при проверке Эвристическое число - порядковый номер первой из совпавших эв- События распознаются при помощи подпрограмм выявления событий, Эмулятор кода работает в режиме просмотра, то есть его основная зада- if (Events[EventNumber]==0) Events[EventNumber]=++CountEvents; где: Events - массив событий; EventNumber - номер регистрируемого события; CountEvents - порядковый номер зарегистрированного события.
Таким образом, в ячейку массива Events записывается порядковый но- действия, выбирая данные из массива событий и цепочек связных for(i=0;i<CountMaskEvrnrs;i++) { for(j=2;j<MaskEvents[i][1 ];]++) " else if(Events[MaskEvents[i][j]]==0 II Events[MaskEvents[i][j]]<e) goto nextMask; else e=Events[MaskEvents[i][j]]; } nextMask:; } где: CountMaskEvents - число масок цепочек событий; MaskEvents - двумерный массив цепочек связных и несвязных Actions - массив действия. Затем выполняется второй преобразователь, который выбирает дан- for(i=0;i<CountMaskHeurist;i++) { if(Actions[MaskHeurist[i][j]]==0) goto nextMaskI; NumberHeurist=i+1; break; nextMaskI: } где: CountMaskHeurist - число эвристических масок; MaskHeurist - двумерный массив с эвристическими масками; NumberHeurist - эвристическое число. Блокировщик вируса Рассмотрим пример. В дисплейном классе ВУЗа эпидемия, часть машин очередь для обслуживающих класс сотрудников). Ситуация усугубляет- Выход - написать антивирус-блокировщик. Практически все резидентные
Разумеется, надо попытаться запустить блокировщик раньше всех ос- install c:\util\stopsvc.com Но если вирус успел заразить command.com или стартует из загрузочно- Листинг программы, блокирующей распространение вируса SVC-1740: ;; Резидентный блокировщик вируса SVC-1740 assume cs:cseg, ds:cseg, ss:cseg org 100h Переходим к инициализации программы jmp Install ;0бработчик прерывания INT 21 h. [Проверим номер функции, если 83h - cmp ah, 83h jnz Skip21 ;0тветим, что вирус присутствует ;3апускаем оригинальный обработчик прерывания db OEAh;Код команды JMP Инициализируем программу .Проверим, не инсталлирована ли уже эта программа. Если mov ah,83h int 21 h cmp dx, 1990h jz Already .Считаем оригинальный вектор прерывания INT 21 h .Установим наш вектор прерывания INT 21h [Выведем сообщение об успешной инсталляции программы в памяти mov dx, offset OkMes .Выйдем из программы, оставив обработчик резидентным ;Выведем сообщение о том, что вирус mov ah, 9 mov dx, offset BadMes int 21 h .Сообщения программы OkMes db "Yeah! STOPSVC installed now!",13,10 db "(c) KostyaSoft, Samara 1997$" Пример антивируса Итак, нужно написать некую программу, которая будет сканировать ка- Важный момент - поиск и лечение должны производиться после заг-
В качестве языка программирования выбран С. Приоритетным призна- Основу программы составляет алгоритм обхода дерева каталогов и по- В тот момент, когда обнаружен очередной потенциально зараженный В случае положительного результата на заражение вызывается функция Если требуется написать программу для лечения для какого-либо другого Итак, как же узнать, заражена программа или нет? В прошлых главах В основе общепризнанного метода лежит принцип выделения сигнату- Разумеется, неправильно было бы использовать для детектирования
Вообще говоря, сигнатура - это множество N пар <Pi,Bi>, i=l.N, где Какой должна быть длина сигнатуры? Вообще говоря, чем больше - Итак, в качестве сигнатуры вируса SVC-1740 выберем 6 байт вируса, Итак, сигнатура OB4h 83h OCDh 21h 5Eh 56h длиной б байт расположена Теперь рассмотрим вопрос лечения программы. Фрагменты заражен- Напомним, что вирус SVC-1740, заражая программу, дописывается в ее Но с методической точки зрения, следуя стратегии заражения, необхо- Поэтому для функции cure() предусмотрен именно второй алгоритм Итак, для СОМ-файла считываем 3 байта, с 80-го по 78-й, если считать
Таблица 6.1. Таблица перемещений для ЕХЕ- файла
Демонстрационный антивирус-фаг для вируса SVC-1740. "**"***************"**"**"*"*******"*"*"**^ #include <stdio.h> ^include <dir.h> ^include <str.h> ^include <process.h> ^include <errno.h> ^include <bios.h> ^include <io.h> #include <fcntl.h> ^define F_FOUND 0 #define PATH_LEN 128 #define BAD 1 #define DBG /* Строка имени текущего подкаталога */ /* Строка имени начального места расположения */ /* Строка имени требуемого устройства 7 /* Пустая строка */ int /* Количество отсканированных каталогов 7 /* Количество исследованных файлов 7 /* Количество больных и исцеленных файлов 7 int /* Длина имени файла */ /* Временный индекс */ ' 1 ^include "antilib.c" /* Рекурсивная процедура обхода дерева каталогов */ { struct find_t buf; /* Поиск каталогов */ while (found_d =- F_FOUND) { if ((buf.name[0]!= ".") && (buf.attrib & _A_SUBDIR)) { walk(); chdir(".."); } /* К этому моменту не отсканированных нижележащих каталогов n_dir++; getcwd(path, PATH_LEN); /* Поиск файлов */ while (foundJ == F_FOUND) { if (((buf.name[l-3]=="C")&& (buf.name[l-1]=="M"))ll ( printf("%c%s",13,blank); printf("%c%s\\%s ",13,path,buf.name); /* Нашли новый файл - надо проверить, инфицирован ли он. if (infected(buf.name)==BAD) cure(buf.name); } } main(int argc, char *argv[]) { if (argc < 2) if(((toupper(argv[1][0]))>"Z")ll((toupper(argv[1][0]))<"A")) drive[0]=argv[1][0]; drive[1 ]=":"; drive[3]="\0'; for (i=0;i<BLANK_LEN;i++) blank[i]=" ";blank[BI_ANK_LEN-1]="\0"; n_dir=0; n_fil=0; getcwd(old_path, PATHJ-EN); drive[2]="\0"; system(drive); drive[2]=^\"; chdir(drive); /* Запускаем рекурсивный обход дерева каталогов old_path[2]="0"; system(old_path); old_path[2]='\\"; chdir(old_path); printf("\nKaTanoroB: %с1\пфайлов: %Ь\пОбнаружено больных if (nJII) exit(1); else exit(O); Файл "ANTILIB.C", включаемый в предыдущий: Процедуры обнаружения и лечения /* Сигнатура */ (char) 0х83, (char) OxCD, (char) 0х21, (char) Ox5E, (char) 0х56, "\0"); int infected(char *fn) I int r,q; char buf[7]; /* Буфер под сигнатуру */ /* Открываем файл */ if (r) { printf(" - ошибка открытия!"); return GOOD; } /* Читаем 6 байт */ r=_dos_read(f, buf, 6, &q); buf[6]="\0"; if ((r)ll(q!=6)) {printf(" - ошибка чтения!"); _dos_close(f); return GOOD; /* Закрываем файл */ /* Сравниваем байты с сигнатурой 7 (printf(" - был болен и..."); n_ill++; return BAD; } /* Болен!!! */ /* Годен к в/службе. П/пк мед. службы Орлов:-) */ cure(char *fn) i int mz; int r,q; char buf[24]; /* Буфер под байты */ /* Открываем файл */ if (r) { printf(" - ошибка открытия!"); return; } /* Читаем первые два байта для определения типа программы */ if ((r)ll(q!=2)) {printf(" - ошибка чтения!"); _dos_close(f); return; } /* Читаем сохраненные вирусом 24 байта старого начала */ r=_dos_read(f, buf, 24, &q); if ((r)ll(q!=24)) (printf(" - ошибка чтения!"); _dos_close(f); return; } /* Определяем тип программы 7 /* Пишем правильные PartPag и PageCnt 7 r=_dos_write(f, &buf[2], 4, &q); if ((r)ll(q!=4)) {printf(" - ошибка записи!"); _dos_close(f); return; } /* Пишем правильные ReloSS и ExeSP 7 r=_dos_write(f, &buf[14], 4, &q); if ((r)ll(q!=4)) {printf(" - ошибка записи!"); _dos_close(f); return; } /* Пишем правильные ReloCS и ExelP */ r=_dos_write(f, &buf[20], 4, &q); if ((r)ll(q!=4)) {printf(" - ошибка записи!"); _dos_close(f); return; } ) else /* Восстанавливаем сохраненные З первые байта программы */ r=_dos_write(f, &buf[0], 3, &q); if ((r)ll(q!=3)) {printf(" - ошибка записи!"); _dos_close(f); return; } /* Усекаем файл (переходим на начало вируса r=_dos_write(f, buf, 0, &q); /* Закрываем файл 7 printf("Tenepb исцелен!\п"); return; }
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|