SFT's and Their Usage
By Dark Angel
Phalcon/Skism

           A powerful though seldom-used technique in virus writing is the use of
      the system file table, an internal DOS structure similar in some respects to
      FCBs, albeit vastly more powerful.  The system file table holds the critical
      information on the state of an open file, including the current pointer
      location, the open mode, and the file size.  Manipulation of the system file
      tables can often replace calls to corresponding DOS interrupt routines and
      therefore, when combined with other techniques, reduces the effectiveness of
      a TSR virus monitor and decreases code size.

           Each open file has a corresponding system file table.  The following
      tables come from Ralf Brown's interrupt listing.

       Format of DOS 2.x system file tables:
       Offset  Size    Description
        00h    DWORD   pointer to next file table
        04h    WORD    number of files in this table
        06h  28h bytes per file
           Offset  Size    Description
            00h    BYTE    number of file handles referring to this file
            01h    BYTE    file open mode (see AH=3Dh)
            02h    BYTE    file attribute
            03h    BYTE    drive (0 = character device, 1 = A, 2 = B, etc)
            04h 11 BYTEs   filename in FCB format (no path, no period,
                              blank-padded)
            0Fh    WORD    ???
            11h    WORD    ???
            13h    DWORD   file size???
            17h    WORD    file date in packed format (see AX=5700h)
            19h    WORD    file time in packed format (see AX=5700h)
            1Bh    BYTE    device attribute (see AX=4400h)
           ---character device---
            1Ch    DWORD   pointer to device driver
           ---block device---
            1Ch    WORD    starting cluster of file
            1Eh    WORD    relative cluster in file of last cluster accessed
           ------
            20h    WORD    absolute cluster number of current cluster
            22h    WORD    ???
            24h    DWORD   current file position???

       Format of DOS 3.x system file tables and FCB tables:
       Offset  Size    Description
        00h    DWORD   pointer to next file table
        04h    WORD    number of files in this table
        06h  35h bytes per file
           Offset  Size    Description
            00h    WORD    number of file handles referring to this file
            02h    WORD    file open mode (see AH=3Dh)
                   bit 15 set if this file opened via FCB
            04h    BYTE    file attribute
            05h    WORD    device info word (see AX=4400h)
            07h    DWORD   pointer to device driver header if character device
                   else pointer to DOS Drive Parameter Block (see AH=32h)
            0Bh    WORD    starting cluster of file
            0Dh    WORD    file time in packed format (see AX=5700h)
            0Fh    WORD    file date in packed format (see AX=5700h)
            11h    DWORD   file size
            15h    DWORD   current offset in file
            19h    WORD    relative cluster within file of last cluster accessed
            1Bh    WORD    absolute cluster number of last cluster accessed
                   0000h if file never read or written???
            1Dh    WORD    number of sector containing directory entry
            1Fh    BYTE    number of dir entry within sector (byte offset/32)
            20h 11 BYTEs   filename in FCB format (no path/period, blank-padded)
            2Bh    DWORD   (SHARE.EXE) pointer to previous SFT sharing same file
            2Fh    WORD    (SHARE.EXE) network machine number which opened file
            31h    WORD    PSP segment of file's owner (see AH=26h)
            33h    WORD    offset within SHARE.EXE code segment of
                   sharing record (see below)  0000h = none

       Format of DOS 4+ system file tables and FCB tables:
       Offset  Size    Description
        00h    DWORD   pointer to next file table
        04h    WORD    number of files in this table
        06h  3Bh bytes per file
           Offset  Size    Description
            00h    WORD    number of file handles referring to this file
            02h    WORD    file open mode (see AH=3Dh)
                   bit 15 set if this file opened via FCB
            04h    BYTE    file attribute
            05h    WORD    device info word (see AX=4400h)
                   bit 15 set if remote file
                   bit 14 set means do not set file date/time on closing
            07h    DWORD   pointer to device driver header if character device
                   else pointer to DOS Drive Parameter Block (see AH=32h)
                   or REDIR data
            0Bh    WORD    starting cluster of file
            0Dh    WORD    file time in packed format (see AX=5700h)
            0Fh    WORD    file date in packed format (see AX=5700h)
            11h    DWORD   file size
            15h    DWORD   current offset in file
           ---local file---
            19h    WORD    relative cluster within file of last cluster accessed
            1Bh    DWORD   number of sector containing directory entry
            1Fh    BYTE    number of dir entry within sector (byte offset/32)
           ---network redirector---
            19h    DWORD   pointer to REDIRIFS record
            1Dh  3 BYTEs   ???
           ------
            20h 11 BYTEs   filename in FCB format (no path/period, blank-padded)
            2Bh    DWORD   (SHARE.EXE) pointer to previous SFT sharing same file
            2Fh    WORD    (SHARE.EXE) network machine number which opened file
            31h    WORD    PSP segment of file's owner (see AH=26h)
            33h    WORD    offset within SHARE.EXE code segment of
                   sharing record (see below)  0000h = none
            35h    WORD    (local) absolute cluster number of last clustr
                     accessed (redirector) ???
            37h    DWORD   pointer to IFS driver for file, 0000000h if native DOS

           In order to exploit this nifty structure in DOS, the virus must first
      find the location of the appropriate system file table.  This may be easily
      accomplished with a few undocumented DOS calls.  Given the file handle in
      bx, the following code will return the address of the corresponding system
      file table:

           mov  ax,1220h  ; Get job file table entry to ES:DI
           int  2fh       ; DOS 3+ only

           mov  bl,es:di  ; get number of the SFT for the file handle
                          ; -1 = handle not open
           mov  ax,1216h  ; get address of the system file table
           int  2fh       ; entry number bx
           ; ES:DI now points to the system file table entry

           Now that the system file table entry address is known, it is a trivial
      matter to alter the various bytes of the entry to fit your particular needs.
      Most viruses must first clear a file's attributes in order to open the file
      in read/write mode, since it would otherwise not be able to write to a read-
      only file.  This handicap is easily overcome by opening the file in read-
      only mode (al = 0) and changing the byte (or word) referring to the file's
      open mode to 2.  This has the added benefit of bypassing some resident
      alarms, which generally do not go off if a file is opened in read only mode.
      It is also possible to set a file's pointer by altering the double word at
      offset 15h (in DOS 3+).  So a quick and easy way to reset the file pointer
      is:
           mov  es:di+15h,0
           mov  es:di+17h,0

           It is acceptable to ignore the DOS 2.X system file table format.  DOS
      2.X is not in common use today and many programs simply refuse to run under
      such primitive versions.  Most of the useful offsets are constant in DOS
      3.X+, which simplifies the code tremendously.

           This is only a surface treatment of a topic which warrants further
      investigation.  Numerous opportunities exist for the enterprising virus
      author to exploit the power of the system file tables.  But the only way to
      find these opportunities is to experiment.  Have fun!