Эвристические анализаторы кода
Эвристическим анализатором кода называется набор подпрограмм, ана-
лизирующих код исполняемых файлов, памяти или загрузочных секторов
для обнаружения в нем разных типов компьютерных вирусов. Рассмот-
рим универсальную схему такого кодоанализатора. Действуя в соответ-
ствии с этой схемой, кодоанализатор способен максимально эффективно
задействовать всю информацию, собранную для тестируемого объекта.
Основные термины:
Событие - это совокупность кода или вызов определенной функ-
ции операционной системы, направленные на преобразование сис-
темных данных, работу с файлами или часто используемые вирус-
ные конструкции.
Цепочка связных событий - это набор событий, которые должны
быть выявлены в порядке их следования.
Цепочка несвязных событий - это набор событий, которые должны
быть выявлены, но не обязательно в строгом порядке.
Действия - набор цепочек связных или несвязных событий, для ко-
торых выполнены все условия.
Эвристическая маска - набор действий, выявленных при проверке
файла.
Эвристическое число - порядковый номер первой из совпавших эв-
ристических масок.
События распознаются при помощи подпрограмм выявления событий,
в которых могут использоваться также таблицы с данными. Остальные
данные просто хранятся в массивах и не анализируются. Рассмотрим
функциональную схему эвристического анализатора (рис. 6.1.).
Эмулятор кода работает в режиме просмотра, то есть его основная зада-
ча - не эмулировать код, а выявлять в нем всевозможные события. Со-
бытия сохраняются в таблице событий по алгоритму:
if (Events[EventNumber]==0) Events[EventNumber]=++CountEvents;
где: Events - массив событий;
EventNumber - номер регистрируемого события;
CountEvents - порядковый номер зарегистрированного события.
Таким образом, в ячейку массива Events записывается порядковый но-
мер для выявленного события. CountEvents при инициализации равен 0.
После того, как эмулятор завершит свою работу, последовательно запус-
каются два преобразователя. Первый преобразователь заполняет массив
действия, выбирая данные из массива событий и цепочек связных
и несвязных событий по следующему алгоритму:
for(i=0;i<CountMaskEvrnrs;i++) {
if (MaskEvents[i][0]==0) {
for(j=2;j<MaskEvents[i][1 ];]++)
if(Events[MaskEvents[i][j]]==0) goto nextMask;
"
else
for(e=0,j=2;j<MaskEvents[i][1];j++) {
if(Events[MaskEvents[i][j]]==0 II Events[MaskEvents[i][j]]<e)
goto nextMask;
else e=Events[MaskEvents[i][j]];
}
Actions[i]=1;
nextMask:;
}
где: CountMaskEvents - число масок цепочек событий;
MaskEvents - двумерный массив цепочек связных и несвязных
событий;
Actions - массив действия.
Затем выполняется второй преобразователь, который выбирает дан-
ные из массива действия и цепочек эвристических масок и вычис-
ляет эвристическое число по следующему алгоритму:
for(i=0;i<CountMaskHeurist;i++) {
for(j=1;j<MaskHeurist[i][0];j++)
if(Actions[MaskHeurist[i][j]]==0) goto nextMaskI;
NumberHeurist=i+1;
break;
nextMaskI:
}
где: CountMaskHeurist - число эвристических масок;
MaskHeurist - двумерный массив с эвристическими масками;
NumberHeurist - эвристическое число.