码迷,mamicode.com
首页 > 其他好文 > 详细

使用hexdump工具追踪EXT4文件系统中的一个文件

时间:2016-08-04 19:06:31      阅读:329      评论:0      收藏:0      [点我收藏+]

标签:

  昨天追踪EXT4文件系统的过程中出了点问题,就是找不到文件,于是试了一下追踪FAT32文件系统的,成功之后有了点信心,今天继续嗑EXT4文件系统,终于找到啦,记录一下。

  • 操作系统:linux(centos 6.5)
  • 文件系统:EXT4
  • 工具:hexdump,windows自带计算器
  • 参考书目:《数据重现-文件系统原理精解与数据恢复最佳实践》(马林 著),题为《Ext4文件系统架构分析》的系列博客,不知道原作是谁了。

EXT4文件系统架构:

  技术分享

补充说明:EXT4文件系统中只有0号块组的超级块和块组描述符表的位置是固定的,其他都不固定。其中,超级块总是开始于偏移位置1024(字节),占据1024个字节,块组描述符表紧随超级块后面,占用的大小是不定。

步骤:

1、查看文件系统基本情况,新建子目录和文件

  技术分享

可以看到挂载在/boot目录下的文件系统类型是EXT4,因此在改目录下新建子目录及文件:

技术分享

文件内容为:“This test is belong to Boot folder!”文件基本信息如下:

技术分享

2、查看超级块,找到0号块组起始块号、块大小、每块组所含块数、每块组i节点数、第一个非保留i节点、每个i节点大小。

命令:hexdump -s 1024 -n 1024 -C /dev/sda1

查看结果:

技术分享

首先可以看到0x38-0x39是EXT系列文件系统的签名标志:“53 ef”

0x14-0x17是0号块组起始块号:0x01,说明超级块前面有一个块为保留块,用来存储引导程序。

0x18-0x1b是块大小:0x00,这里的值指的是将1024字节左移的位数,移动0位也就是1024字节,移动一位相当于乘以2,就是2048字节。

0x20-0x23是每块组所含块数:0x2000(十进制8192)

0x28-0x2b是每块组所含i节点数:0x07f0(十进制2032)

0x54-0x57是第一个非保留i节点号:0x0b(11),一般为lost+found目录

0x58-0x59是每个i节点结构的大小:0x80(十进制128),也就是每个i节点表项占用128个字节。

3、查看块组描述符表,找到块位图块、i节点位图块、i节点表起始块号、块组目录数。

命令:hexdump -s 2048 -n 1024 -C /dev/sda1

查看结果:

技术分享

块组描述符表中每个块组使用32个字节来描述,因此第一个32字节描述的就是0号块组。

0x00-0x04是块位图块起始块号:0x0104

0x05-0x07是i节点位图块起始块号:0x0114

0x08-0x0b是i节点表起始块号:0x0124

0x10-0x11是该块组的目录数:0x02

这里获取的起始块号是逻辑块号(将文件系统所有的块从0开始递增编号),因此在计算偏移量时可以直接乘以每块字节数(0x400,也就是十进制的1024)

3、从根目录中找到子目录

  第一步我们提到了第一个非保留i节点号为11,那么前面的10个保留i节点的作用是什么呢(i节点号从1开始编号),这里只说明2号节点是存储的是根目录i节点号,因此我们读取i节点表的2号表项值就可以找到根目录所在块号了。

  计算i节点表项的偏移量涉及到了块组描述符表中的i节点表起始块号:0x0124。

  某i节点表项起始字节=i节点起始块号*每块所占字节数+(该i节点号-1)*每个i节点表项所占字节数

   0x0124*0x400+(0x02-0x01)*0x80=0x49080

下面就可以读取根目录i节点表项值了。

命令:hexdump -s 0x49080 -n 128 -C /dev/sda1

查看结果:

技术分享

0xa8-0xd7是12个直接块指针,其中四个字节为一个单位,表示一个块号。

图中可以看出根目录只占用了一个块,块号为:0x1104

  根目录的起始偏移字节为=根目录所在块号*每块所占字节数

则根目录的起始偏移字节:0x1104*0x400=0x441000

使用命令:hexdump -s 0x441000 -n 1024 -C /dev/sda1 查看根目录内容:

技术分享

查看/boot目录下的文件:

技术分享

可以看到两者的内容是相符的,说明我们找的没有错。根目录中BOOTDIR的目录项用黑色底纹标注。

0x6c-0x6f是该文件内容所在i节点号:0x7f01

0x70-0x71是本目录项长度:0x10(16字节)

0x72是本目录项名字长度0x07(7个字节)

0x73是本文件类型:0x02(表示目录)

0x74开始是文件名的ASCCI码:“42 4f 4f 54 44 49 52 00”

在这一步中与FAT32文件系统的区别有两个:

  一是怎么寻找根目录。FAT32中根目录在数据区的开头,因此我们可以直接去数据区读取;而EXT4文件系统中,我们需要通过2号i节点表找到根目录所在的块号,才能看到根目录内容,这里就可以看出EXT4文件系统将目录也看作文件了,因为他的读取方式和普通文件是一样的,只不过普通文件需要从目录中得到i节点号,而根目录是一开始就定好了i节点号。

  二是目录的大小。FAT32中目录的大小是固定的(短文件名目录占32字节,长文件名目录占多个32字节),所以当文件名过长时,使用了长文件名机制来解决,而EXT4文件系统的目录项大小是在目录项中灵活定的。比如这一步中我们查看到的根目录结果中,开始的12个字节是本目录项,紧接着12个字节是根目录项,而我们要找的目标目录项的长度是16个字节,其中说明部分(i节点号,本目录项长度字节数,名字长度,文件类型)占用都是一样的,差就差在文件名部分。但我们也看到文件名后面总有“00”补齐,这是因为目录项的长度总要是4的倍数,因此不够时会用0补齐。

4、从i节点表中找到子目录所在块号

第三步中我们找到指向子目录的i节点号为0x7f01,也是逻辑i节点号,因此我们要先找到0x7f01在哪个块组中:

  某i节点所在块组=该i节点号/每块组i节点个数

  0x7f01/0x7f0=0x10(十进制16)

  某i节点所在i节点表号=该i节点号%每块组i节点个数

  0x7f01%0x7f0=0x01

因此0x7f01在16号块组的i节点表中,在改i节点表的1号表项中。

接下来我们要从块组描述符表中找到16号块组的i节点表起始块号,以便找到子目录所在块号。

  某块组在块组描述符表中偏移字节=块组描述符表起始字节+块组号*每块组描述符表项字节数

  2048+16*32=2560字节

我们读取2560偏移字节开始的32字节:

技术分享

可以看到:0x08-0x0b为i节点表起始块号:0x020021

读取16号块组i节点表的1号i节点表项值:

技术分享

从0x28-0x57是12个直接块指针,以4个字节为单位读取,其中有的指向超级块(0x01)。0x21002指向的块存储的是子目录内容。

该块的偏移字节:0x8400800

5、从子目录对应的i节点号得到目标文件块号

查看结果第4步中子目录块内容:

技术分享

加黑色底纹的是本目录(“.”)和根目录(“..”)接下来就是目标文件:BOOTTEXT.txt,他的i节点号为:0x7f04

 查看i节点表,找到目标文件的块号:

  改i节点表项的偏移字节为:0x020021*0x400+(0x7f04%0x7f0-1)*0x80=0x8008580

读取该偏移字节处开始的128字节内容:

技术分享

得到的目标文件所在块号为0x024005(偏移字节为0x9001400),接下来读取该块内容:

技术分享

找到啦!和第一步中使用cat命令查看的文件内容一致。

 

使用hexdump工具追踪EXT4文件系统中的一个文件

标签:

原文地址:http://www.cnblogs.com/jiangcsu/p/5737659.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!