CSCI 373 System Administration — Finding a file II

Picking up

It is assumed that you have followed part I and that you have the following files in your directory.

You will also need to know the following parameters discovered by following part I to search the BIOS Parameter Block. You’ll only need a few of these and you can copy them as needed.

…$ BPB_BytsPerSec=512
…$ BPB_SecPerClus=16
…$ BPB_NumFATs=2
…$ BPB_RootEntCnt=512
…$ TotSec=122880
…$ FATSz=32
…$ BPB_RsvdSecCnt=1
…$ BPB_ResvdSecCnt=$BPB_RsvdSecCnt
…$ FirstDataSector=97
…$ rootDirStart=$(( $BPB_RsvdSecCnt + $BPB_NumFATs * $FATSz ))
…$ RootDirSectors=32
…$ TotSec=114688
…$ FATSz=32

Copying the root directory and the file allocation table

Be sure you have a copy of the root directory.

…$ dd if=boot.img of=boot.rootdir.img bs=512 count=$RootDirSectors skip=$rootDirStart

Also, copy the file allocation table.

…$ dd if=boot.img of=boot.fat.img bs=512 skip=$BPB_RsvdSecCnt count=$FATSz

A quick look at the root directory

The directory entries are 32 bytes long. Take a look at the first twenty entries.

…$ od -A d -t a -N 320 boot.rootdir.img 

It will start with something like the following.

0000000   b   o   o   t  sp  sp  sp  sp  sp  sp  sp  bs nul nul   C   E
0000016   r   H   r   H nul nul   C   E   r   H nul nul nul nul nul nul
0000032   A   o nul   v nul   e nul   r nul   l nul  si nul   G   a nul
0000048   y nul   s nul nul nul del del del del nul nul del del del del
0000064   O   V   E   R   L   A   Y   S  sp  sp  sp dle nul nul   7 can
0000080   S   J   S   J nul nul   7 can   S   J  gs nul nul nul nul nul

A new directory entry starts every 32 bytes. (That’s every four lines.) However, files with long names have multiple entries: one for the short name and one or more for the long name. In the above example, the first set of two lines is a short entry for the name of the volume, boot. The next set of two is a long entry for the long name overlays. Read every other byte to find overlays. overlays is considered a long file name because it contains lower-case letters. The third set of two lines is the short entry for overlays, spelled in all capitals as its abbreviated name.

The eleventh (numbered from zero) byte of a directory entry is special. Use the following command to take a look at the directory entry as hex.

…$ od -t -A d a -N 320 boot.rootdir.img 

Search for the eleventh byte of each entry. You should find some of the following: 08 for a volume label, 0f for a long file name, 10 for a directory, and 20 for an unarchived file.

A quick look at the file allocation table

Open up a link to Wikipedia’s discussion of the file allocation table. It’s nothing more than a collection of linked lists.

Each entry in the file allocation table occupies two bytes and corresponds to a cluster of the file system. Display the first 20 entries.

…$ od -A d -t d2 -N 40 boot.fat.img 

The long consecutive sequences of increasing integers map files that are stored consecutively on the disk. In this case you find that the i’th entry (number from 0) of the file allocation table is i+1. -1 indicates the last cluster of file.

Here’s a useful dd command for displaying the next “link” for cluster 50. (100 is 2*50.) Expect to see 51.

…$ od -A d -t d2 -j 100 -N 2 boot.fat.img 

Or you could try this.

…$ od -A d -t d2 -j $(( 2 * 50 )) -N 2 boot.fat.img 

Finding the file

The /boot directory of your Pi should contain the files issue.txt and COPYING.linux. Use the following command to search for the (short) directory entries for these two files. Don’t whine about having to do a sequential search. That’s also what the operating system does. (On the other hand you could let grep do the search for you.)

…$od -A d -t a boot.rootdir.img | more

Once you have found the offsets of the appropriate short, not long, 32-byte directory entries, copy them using commands similar to the following:

…$dd if=boot.rootdir.img of=filename.direntry.txt bs=1 skip=offset count=32

For example, since the offset for issue.txt is byte 672, you can copy it with the following command. (Gave that one away.)

…$dd if=boot.rootdir.img of=issue.txt.direntry.txt bs=1 skip=672 count=32

This should be give you two files containing directory entries:

Now determine the starting cluster, at offset 26, and file size, at offset 28, of each file. Here is what worked for me for issue.txt .

…$od -A d -j 26 -N 2 -t d2 issue.txt.direntry.txt
…$od -A d -j 28 -N 4 -t d4 issue.txt.direntry.txt

You better write these numbers down The two file size numbers should be close to 103 for issue.txt and to 18693 for COPYING.linux. Since clusters are 8192 bytes long, a 18693 byte file would be stored in three cluster.

Reading a cluster

Even through clusters are (on this file system) 8192 bytes long, the are not stored on 8192-byte boundaries. The Microsoft EFI FAT32 File System Specification contains the following formula for finding the starting sector for a cluster N.
    FirstSectorofCluster = ((N – 2) * BPB_SecPerClus) + FirstDataSector

Since you are only doing this a four (or maybe two) times, the easiest way to perform this operation would be the use a calculator or some useful Linux program such as bc, python or even nodejs. But, if you are really determined, you could use the following bash shell function. (Be sure to define BPB_SecPerClus and FirstDataSector first.)

function DataSector2Cluster()
   local result=$(( ( ( $1 - 2 ) * $BPB_SecPerClus ) + $FirstDataSector ))
   echo "$result"

In any case, assume that your have gone through this procedure and have discovered issue_txt_sector, the starting sector address of the file issue.txt, and that your result has been verified by at least one other person. Now execute that one command needed to copy the cluster containing issue.txt and an additional 8000 or more null charaters. Remember, the block size must be 512, the sector size, and that you must copy 16 sectors to read the entire 8192 byte cluster.

Homework 11

You really should try to do this one in the lab today. It is also very similar to the last half of a lab used in the Spring 2015 System Administration course.

Copy the three clusters for the file COPYING.linux and concatenate them into a single file. Next use dd to remove all the extra null characters from the three-cluster file.

Use the history to save a copy of the dd commands you used in this low-level creation of COPYING.linux. Download a copy of these commands to the Homework 11 moodle page by 11:00 PM on Saturday, 29 April.