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

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

Содержание


"Вирусы", "Черви", "Драконы" и резиденты на службе прогресса.
Mov ds,dx ; ---+--> ds = 0 ¦
Подобный материал:
1   2   3   4   5   6   7   8   9   ...   16

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


Назад | Далее



Ответы:

------

Инициализирующая часть не остается в памяти резидентно, т.к. она не вхо-

дит в п/п-му обработки прерывания 05, она нужна лишь для посадки резидента в

память и перенаправления вектора прерывания на него. Здесь уместна аналогия с

запуском орбитального спутника: ракета-носитель <инициализирующая часть>, вы-

водит на орбиту спутник-шпион <резидентная часть>. При этом сама ракета-носи-

тель разрушается и на орбиту не попадает.

О порядке следования. Если бы сначала шла инициализирующая часть, а по-

том - резидентная, то мы были бы вынуждены сделать резидентным и инициализи-

рующий кусок, ибо резидентным становится все, начиная от PSP и до того адре-

са, который мы поместим в DX перед генерацией INT 27h. Оставление в резиден-

туре инициализационной части приведет к расходованию лишней памяти (очень

ценного ресурса).

ЗАМЕЧАНИЕ: вот в случае создания резидентного вируса инициализирующая

часть обязана быть резидентной, так как ВИРУСУ ДОЛЖЕН БЫТЬ ДОСТУПЕН ВЕСЬ СОБ-

СТВЕННЫЙ КОД. Лишь при этом условии вирус сможет себя куда-нибудь запихнуть.

Вот зачем появились операторы CLI и STI: в момент, когда мы вручную (при

помощи команд пересылки) заменяем адрес в таблице векторов, может произойти

вызов того самого прерывания, которое мы перехватываем. Если одно слово заме-

нено, а другое - еще нет -- будет маленький Чернобыль (семь бед - один

RESET). На время замены вектора надо временно запретить вызовы прерываний

(команда CLI), после окончания замены -- разрешить вновь (команда STI). Ко-

манда CLI запрещает все прерывания, кроме немаскируемого NMI.

Зачем в начале нашей п/п-мы обработки прерывания 05 торчит PUSH AX, а в

конце -- POP AX? Слушайте СУПЕРПРАВИЛО:

-СУПЕРПРАВИЛО---------------------------------------------------------------¬

¦ Если п/п-ма обработки прерыв-я в процессе работы портит какой-либо ре-¦

¦гистр, то перед окончанием своей работы она обязана вернуть ему прежнее¦

¦значение. Чаще всего это делается так: перед началом работы этот регистр¦

¦роняется в стек, а перед окончанием достается обратно. (Есть и другие спо-¦

¦собы). ¦

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


В заключение главы сварганим еще один резидент, который будет гудеть,

стОит лишь нам запустить какую-либо программу. Сажать его мы будем на обра-

ботку прерывания 21h - "Прерывания DOS" (функция 4Bh) :


коментарии см. ниже

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

¦ пример 6 ¦:

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


TITLE Это - COM. программа N6 для демонстрации посадки резидента

ASSUME CS:CodeSegment

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

CodeSegment SEGMENT PARA

ORG(100h)

Start:

MainProcedure PROC NEAR

;

;

JMP initial ; перепрыгнем через данные

; ; и наш обработчик прер-я 21

; ; на инициализирующую часть

;

;

saved_int21: DD 0 ; данные (хранилище для

; ; адреса стандартного обра-

; ; ботчика прерывания 21 --

; ; -- 2 слова)

;

;-----------наша п/п-а обработки прерывания 21------------------¬

;¦ (она останется резидентной в памяти) ¦

;¦ ;здесь мы можем приколоться как ¦

int21_treater:;¦ ; хотим.. ¦

PUSH AX ; ¦

CMP AH,4Bh ;вызвана ф-я 4Bh прерыв-я 21h ¦

JNE not_beep ; (запуск программы) -- если ¦

MOV AX,0E07h ; нет - гудеть не будем ¦

INT 10h ;давать гудок (печать - символа ¦

not_beep: POP AX ; с кодом 07) ¦

; ;PUSH и POP ОЧЕНЬ важны сами ¦

; ; знаете теперь почему ¦

; ; ¦

JMP dword ptr CS:[saved_int21] ; длин. JMP по адресу, котор. ¦

rezident_end: ;¦ ; находится теперь в хранилище ¦

;¦ ; saved_int21 (возвращаем управ-¦

;¦ ; ление стандартному обработчику¦

;¦ ; прерывания 21) ¦

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

; ;

;-----------инициализирующая часть------------------------------¬

;¦ (здесь мы сажаем резидент, переопределяя адреса) ¦

;¦ ; ¦

initial: XOR DX,DX ; ---¬ ¦

MOV DS,DX ; ---+--> DS = 0 ¦

; ; ¦

MOV AX,DS:[21h*4] ; сохраняем в хранилище saved_

MOV word ptr CS:[saved_int21 ],AX ; int21 адрес стандартного ¦

MOV AX,DS:[21h*4+2] ; обработчика прерывания 21 ¦

MOV word ptr CS:[saved_int21+2],AX ; ( OFFSET и SEGMENT ) ¦

; ; ¦

; ; ¦

CLI ;запрещаем прерывания ¦

MOV AX,OFFSET int21_treater ; ¦

MOV word ptr DS:[21h*4],AX ;кладем в таблицу векторов ¦

PUSH CS ; адрес нашего обработчика ¦

POP AX ; прерывания 21 ¦

MOV word ptr DS:[21h*4+2],AX ; ¦

STI ;разрешаем прерывания ¦

; ; ¦

; ; ¦

MOV DX,OFFSET rezident_end ;DX<--конец резид. части ¦

INT 27h ;закончить программу и ¦

;¦ ; вернуться в DOS, оставив ¦

;¦ ; резидентной п/п-му ¦

;¦ ; int21_treater ¦

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

MainProcedure ENDP

;

CodeSegment ENDS

END Start


коментарии:

-----------

Единственное, что здесь для Вас ново - характер обработки прерыв-я 21h.

Мы подробней изучим его дальше, а здесь отметим лишь, что это прерыв-е содер-

жит офигительное количество функций, т.е. в п/п-ме его обработки содержится

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

ятельствах. Здесь резидент вешается на суб-подпрограмму которая вызывается в

момент запуска на выполнение исполняемой программы (функция 4Bh). Говоря

по-русски, -- как только Вы запустите на выполнение какую-либо программу

(например TETRIS.EXE), будет сгенерировано прерывание 21h, - управление будет

передано соответств. п/п-ме обработки. При этом в регистре AH будет находить-

ся число 4Bh (входной параметр), которое означает, что внутри п/п-мы обработ-

ки прерыв-я 21h, управление, в свою очередь, будет передано суб-подпрограмме,

которая и осуществит запуск файла TETRIS.EXE.

Сущность нашего перехвата прерывания 21h такова: как только возникло

прерывание, и управление перешло к нашему резиденту мы сравниваем значение AH

с 4Bh. Если AH=4Bh (запускается какая-то программа), то мы даем гудок и пере-

даем управление в руки хозяина (функции 4Bh) -- делаем длинный джамп. Если же

вызванная функция -- не 4Bh, то мы возвращаем управление, что называется, без

звука.

Экспериментируя с этим резидентом, мы обнаружим, что при запуске прог-

рамм может раздаваться несколько гудков. Дело в том, что запускаемые нами

программы могут, в свою очередь, запускать свои дочерние процессы. Крайне

часто запускаются Norton и COMMAND.COM.


гл.5 ЧУТЬ-ЧУТЬ О PSP (как и обещали)

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


PSP расшифровывается так: префикс программного сегмента (Programm

Segment Prefix). Где, когда и как он возникает? Каждый раз, когда какая-либо

программа (ЕХЕ- или СОМ-файл) запускается на выполнение, для нее в памяти

создается PSP. Сама программа считывается в память сразу за PSP. Длина PSP

составляет 256 (100h) байт. В PSP содержится много всяких штучек. Мы покажем

Вам лишь те, которые, возможно, понадобятся нам в дальнейшем.


смещение ¦длина ¦

от нача- ¦(в бай-¦ содержимое

ла PSP ¦тах) ¦

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

00 ¦ 2 ¦ код команды INT 20h (CD20h)

¦ ¦

02 ¦ 2 ¦ размер доступной сейчас памяти

¦ ¦ (в параграфах по 10h)

¦ ¦

2Ch ¦ 2 ¦ сегментный адрес среды для хранения

¦ ¦ ASCIIZ-строк

¦ ¦

80h ¦ 20h ¦ область передачи данных DTA


Прерывание INT 20h. Что за фигня? Если в программе дать такое прерыва-

ние, то выполнение ее будет завершено и управление вернется DOS. Совсем как

после команды RET. А как Вы думаете, - как работает команда RET? Команда эта

выполняет действие . А в стеке, сразу после загрузки СОМ-программы на

выполнение, лежит 0. Таким образом после команды RET управление передается по

адресу CS:00, т.е. на начало PSP, т.е. на команду INT 20h.

Обо всех прочих объектах Вы подробнее узнаете позднее.


гл.6 ПЕРВАЯ ПАКОСТЬ (создание ублюдочного резидентного вируса, грохающего за-

ражаемую программу)

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


КОМЕНТАРИЙ К ЗАГЛАВИЮ: этот бездарный вирус показан здесь как анти-при-

мер для подражания и лишь для повышения Вашей образованности на достаточно

простом и наглядном материале. Вообще -- вирусы, необратимо грохающие прог-

раммы, создаются, как правило, либо - человеконенавистниками, либо - програм-

мистами, пока что еще слабо владеющими мастерством, либо - в погоне за рекор-

дом (например - рекордно короткая длина), либо - чтобы реализовать конкретный

алгоритм в условиях сильных внешних ограничений (например вирус должен быть

не длиннее одного сектора - 512 байт). Наш случай (смеем надеяться) не подхо-

дит ни под одну из этих категорий.

Что касается нашего первого вируса, то он будет вот каким: Вирус будет

резидентным. Резидент будет обрабатывать по-своему операции чтения/записи на

HDD. Как только резидент обнаружит, что с HDD читается годный для заражения

файл, он тут же запишет в него свою копию. Причем запишет таким образом, что

при запуске пораженного файла тот создаст новую резидентную копию вируса.

Цикл функционирования вируса замкнется.

Чтобы выполнить задуманное, нам необходимо еще кое-что узнать. Кое-что о

жестком диске PC (HDD, он же - "винчестер") и о гибких дисках (FDD).

Информацию можно читать/писать на HDD только фиксированными порциями -

секторами. Как правило, для HDD длина сектора составляет 512 байт. За один

раз на HDD можно записать/прочитать несколько секторов. Т.о. за каждое обра-

щение к HDD на него можно записать/прочитать количество байт, СТРОГО КРАТНОЕ

512. Нельзя, например, записать/прочитать 1,65,513,1033 байт, но можно --

512,1024,1536,...

Как PC находит нужные ему сектора? Чтение и запись на HDD осуществляется

не совсем так, как на магнитофон. В магнитофоне чтобы найти и считать/запи-

сать информацию нужно задать ее координату от начала ленты -- система ОДНО-

МЕРНА. При этом Вы должны пролистать ВСЮ предшествующую информацию. Скорость

такого процесса весьма мала. Такую фигню называют устройством последователь-

ного доступа. В HDD реализован другой принцип. HDD - это - трехмерное инфор-

мационное пространство и информацию в него писать/читать можно как в ТРЕХМЕР-

НЫЙ массив. Это же круто! Скорость офигительная, износ - минимальный.

Итак, можно представить HDD как трехмерный массив, элементами которого

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

иметь вот какие диапазоны изменения:


индекс-измерение ¦ диапазон изменения

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

сторона (side) ¦ 0,...,N--¬

¦ +--для разных

цилиндр (cylinder) ¦ 0,...,M--+ HDD - разные

¦ ¦ значения

сектор (sector) ¦ 1,...,L---


Измерение "сектор" пока что не смешивайте с элементарной неделимой еде-

ницей читаемой/пишущейся информации, так же именуемой "сектор".

Вот как понял бы приведенное выше описание HDD PASCAL-ист:


Type

Sector = array [1..512] of byte;


Var

HDD : array [0..N, 0..M, 1..L] of Sector;

LT-- LT-- LT--

+-----+-----+--------- для разных HDD

side cylinder sector разный верх. предел


Когда операционная система MS-DOS работает с файлами, она на самом деле

имеет дело с отдельными секторами и группами секторов, в которых размещается

содержимое файла.

Если Вы желаете подробнее познакомиться со структурой HDD, - то прочи-

тайте нижеследующий кусок текста, - нет -- джампуйте через него - информации

у Вас для понимания дальнейшего материала в принципе достаточно.

Если не хотите о HDD подробнее -- следуйте за стрелкой: ==>==============>==¬

V

¦¬ структура дискаг¦ ¦

¦L==(подробнее)===-¦ На физическом уровне HDD состоит из нескольких плоских ¦

L==================- (наверное - жестких) дисков, намертво закрепленных на ¦

общей оси (своего рода - этажерка). Первое измерение этого трехмерного квази- ¦

массива называется "сторона"(side). Верхняя сторона верхнего диска "этажерки"- V

¦

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

¦ рис.5 ¦: ¦

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

¦

ось-¬ -----> side 0 Измерение "сторона" ¦

L---->¦¦ ¦ V

================х================ пределы изменений: 0..N, ¦

диски-T- ¦¦ L----> side 1 где N -- для разных HDD ¦

¦L¬ ¦¦ -----> side 2 -- различно ¦

======¦=========х================ ¦

¦ ¦¦ L----> side 3 ¦

¦ ¦¦ ... ¦

L-¬ ¦¦ -----> side N-1 ¦

================х================ V

¦¦ L----> side N ¦

¦

-- это side 0, а нижняя - side 1; верхняя сторона следующего диска -- side 2, ¦

а нижняя - side 3. И т.д. - см. рис. 5. ¦

Следующее измерение называется "цилиндр" (cylinder) . Надеемся искренне, ¦

что, гдядя на рис. 5, Вы все же сможете ухватить нашу мысль (поясним лишь, ¦

что здесь средствами уголковой графики мы попытались изобразить "двухэтажный" ¦

диск). Цилиндр - пространство на ВСЕХ дисках "этажерки", находящееся на опре- V

деленном расстоянии от мест закреплений дисков на оси. Т.е. это - совокуп- ¦

ность концентрических дорожек одного радиуса на ВСЕХ сторонах HDD. Цилиндры ¦

нумеруются так: 0..M, где M -- для разных HDD -- различно. ¦

¦

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

¦ рис.6 ¦: ¦

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

верхний V

диск --¬ ¦

"этажерки"¦ --------------T-------------¬ ¦

¦ ---------\ ¦ /L--------¬ ¦

¦ ----- \-----------+----------/---¬ L---¬ ¦

----- ---------- \ ¦ / L--------¬ L---¬ ¦

----- ----- --\-------+------/--¬ L---¬ L---¬ ¦

--- ----- ----------- \ ¦ / L---------¬ L--¬ L-¬ ¦

-- ---- ------ \--+¦¦-/-¬ L-----¬ L--¬ L¬ V

¦ --- ---- ------ \¦¦¦ L--¬ L---¬ L¬ ¦ ¦

+---+TTTTT+------------------+--------¦L------+---------------------+----+--+ ¦

¦ L¦+++++TT¬ L----¬ / ¦ \ ---- ----- -- ¦ ¦

L¬ L¦++++++TTTT¬ /---+---\- ------- ---- -- ¦

L-¬ ¦L¦¦¦¦¦¦¦¦+TTTTTTTTT¬ / ¦ \ ----------- ------LT---- ¦

L---¬¦ L++++¦¦¦¦¦¦¦¦¦¦¦-¬гTTTTTT+---------- LT- ----- --+-- ¦

L+--¬ L++++++++-¦/¦¦¦¦¦¦¦¦¦¦ \ ------+---- ----- ¦ ¦

¦ L---¬ ¦ /-¦¦¦¦¦¦+¦¦¦+-----------\ ¦ ----- ¦ V

¦ L-----+--/ ¦ ¦ \---+----- ¦ ¦

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

¦ ¦ ¦ ¦¦¦ ¦ ¦ ¦

сентор 3--- ¦ ¦ ¦¦¦ -------+----¬ -------+----¬ ¦

¦ ¦ ¦ ¦¦¦--¬ ¦ цилиндр 1 ¦ ¦ цилиндр 0 ¦ ¦

¦ ¦ ¦ ¦¦¦ ¦ ¦(стОроны ¦ ¦(стОроны ¦ ¦

¦ сентор 2 ------- ¦ ¦¦¦ ось ¦ 0,1,2,3)¦ ¦ 0,1,2,3)¦ V

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

¦ ¦ сентор 1 ---------- ¦¦¦------------¬ ¦ ¦ ¦

¦ ¦ ¦ ¦¦¦ /L---+----¬ ¦ ¦

¦ ¦ ¦ ¦¦¦---------/---¬ ¦ L---¬ ¦ ¦

¦ ¦ ¦ ¦¦¦ / L--+-----¬ L---¬ ¦ ¦

на цилиндре с номером 1 ¦¦¦-----/--¬ -+¬ L---¬ L-+¬ ¦

(из рис. не просЕчь - на какой стороне)¦¦¦ / L---------¬ L--¬-+L-¬ ¦

¦¦¦-/-¬ L-----¬ L--¬ L-¬ V

¦¦¦ L--¬ L---¬ L¬ ¦ ¦

L¦L------+---------------------+----+--+ ¦

| \ ---- ----- --- ¦ ¦

возможно - сектора нумеруются против \---\- ------- ---- --- ¦

часовой стрелки - нам это как-то | \ ----------- ----- --- ¦

пО фигу /-------\-- ----- ---- ¦

| \ ----------- ----- V

\-----------\ ----- ¦

| \--------- ¦

/-------------- ¦

¦

Третье измерение HDD -- "сектор" -- угловое расстояние от определенной ¦

точки на каком-либо цилиндре какой-либо стороны HDD. Секторы нумеруются по ¦

возрастанию углового расстояния. Нумеруются они так: 1..L (НЕ С 0, КАК ЦИЛИН- V

ДРЫ И СТОРОНЫ!), где L -- для разных HDD -- различно. ¦

Отметим, что пересечение цилиндра со стороной образует дорожку (track) ¦

-- одну окружность на одной из сторон. Так вот, -- дорожка состоит из следу- ¦

ющих друг за другом секторов. ¦

Задав все три координаты, мы однозначно задаем определенное место на ¦

HDD. Вообще говоря, эта фигня сильно напоминает цилиндрические координаты. ¦

г==<===============<===================<=====================<===============<===-

V

Что же касается гибких дисков -- дискет (FDD), то все вышесказанное

справедливо и для них. У FDD всего 2 стороны -- 0 и 1. Больше, пока что, и

добавить нечего.


Теперь вопрос: На что же мы посадим наш резидент? Для этого здесь должно

быть какое-то прерывание. И оно имеется. Прерывание, по которому PC чита-

ет/пишет на HDD и FDD сектор (группу секторов). Прерывание 13h. Опишем его.


¦прерывание 13h¦-----очень-очень важная фенька

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

PC читает и пишет файлы на HDD посекторно. А секторА он читает/пишет при

помощи специального прерывания 13h. Это программное прерывание, генерируемое

Вами (а не аппаратурой) при помощи команды INT 13h. Вот какие у него входные

и выходные параметры:


-- MOV AH, (признак операции: 2-читать,3-писать,и пр.)

¦ MOV AL, сколько секторов читать/писать

¦ MOV CH, цилиндр--¬

входные параметры---+ MOV CL, сектор +-координаты записи

(заполняем перед ¦ MOV DH, сторона---

вызовом INT 13h) ¦ MOV DL, дисковод (0 - A:, 1 - B:, 80h - HDD)

¦ MOV BX, офсет----¬

L- MOV ES, сегмент--+--адрес буфера ввода/вывода


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

¦ INT 13h -- вызов п/п-мы чтения/записи секторов ¦

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


-- CF (флаг переноса) содержит индикацию ошибки

¦ 0 - ошибок не было, 1 - произошла ошибка

¦

¦ в AL - содержится кол-во действительно обработанных

¦ секторов,

выходные параметры-+

(имеем в PC после ¦ в AH - если CF=1 (произошла ошибка) -- код ошибки

вызова INT 13h) ¦

L- по адресу ES:BX -- прочитанный сектор (группа секторов)

-- в случае, если была операция чтения


Вот пример использования INT 13h; здесь мы хотим прочитать в ОЗУ

MBR-"винчестера" (что это такое - объясним позднее) предположим, для како-

го-то исследования: