软件开发领域都关心。
分类:
2005-12-07 15:01:34
据说NTFS是很复杂的文件系统, 想要解析一下, 看了很多资料, 但是也不是官方的.
为了备忘记了一下.第一部分:从MBR到NTFS
基于古老的bios的PC, 硬盘的第一个扇区是MBR. 基于新的EFI的有所不同, 还没有仔细研究.
I386结构也就是下x86支持四个基本分区, 在MBR的offset 0x1bE, 0x1cE, 0x1DE, 0x1EE.
每个分区的数据结构如下:
struct partition_dos {
unsigned char boot_ind; /* 0x80 - active */
unsigned char head; /* starting head */
unsigned char sector; /* starting sector */
unsigned char cyl; /* starting cylinder */
unsigned char sys_ind; /* What partition type */
unsigned char end_head; /* end head */
unsigned char end_sector; /* end sector */
unsigned char end_cyl; /* end cylinder */
uint32_t dwRelativeSector; /* starting sector counting from 0 */
uint32_t dwNumberSectors; /* nr of sectors in partition */
};
从这个数据结构就可以得到每个分区的起始和结束扇区数. 到了扇区的位置, 就可以得到某个分区的数据. 分区里的数据根据不同的文件系统有不同的组织方式. 一个sector描述了文件系统的属性.
一种文件系统和另一种文件系统的初始区别就在boot sector. 一个分区的boot sector描述了这个分区使用什么样的文件系统. 所有的boot sector都是512字节,有一些字节的定义是类似的, 有些是不同的.对于NTFS的定义如下:
struct ntfs_boot_sector {
uint8_t ignored[3]; /* 0x00 Boot strap short or near jump */
int8_t system_id[8]; /* 0x03 Name : NTFS */
uint16_t sector_size; /* 0x0B bytes per logical sector */
uint8_t sectors_per_cluster; /* 0x0D sectors/cluster */
uint16_t reserved; /* 0x0E reserved sectors = 0 */
uint8_t fats; /* 0x10 number of FATs = 0 */
uint8_t dir_entries[2]; /* 0x11 root directory entries = 0 */
uint8_t sectors[2]; /* 0x13 number of sectors = 0 */
uint8_t media; /* 0x15 media code (unused) */
uint16_t fat_length; /* 0x16 sectors/FAT = 0 */
uint16_t secs_track; /* 0x18 sectors per track */
uint16_t heads; /* 0x1A number of heads */
uint32_t hidden; /* 0x1C hidden sectors (unused) */
uint32_t total_sect; /* 0x20 number of sectors = 0 */
uint8_t physical_drive; /* 0x24 physical drive number */
uint8_t unused; /* 0x25 */
uint16_t reserved2; /* 0x26 usually 0x80 */
uint64_t sectors_nbr; /* 0x28 total sectors nbr */
uint64_t mft_lcn; /* 0x30 Cluster location of mft data.*/
uint64_t mftmirr_lcn; /* 0x38 Cluster location of copy of mft.*/
int8_t clusters_per_mft_record; /* 0x40 */
uint8_t reserved0[3]; /* zero */
int8_t clusters_per_index_record; /* 0x44 clusters per index block */
uint8_t reserved1[3]; /* zero */
uint64_t volume_serial_number; /* 0x48 Irrelevant (serial number). */
uint32_t checksum; /* 0x50 Boot sector checksum. */
uint8_t bootstrap[426]; /* 0x54 Irrelevant (boot up code). */
uint16_t marker; /* 0x1FE */
} __attribute__ ((__packed__));
从这些512字节可以得到一些关键的信息. 例如每个sector的字节数, 每个cluster的sector数. 一共多少sector, mft的位置sector.
有了这些信息就可以去解析MFT了.
参考代码: TestDisk----GNU Project
Udelete ----Code Project