157 lines
8.0 KiB
Plaintext
157 lines
8.0 KiB
Plaintext
|
|
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
|
|
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!
|
|
|