EXT2文件文件定位过程模拟实验(无理论版) 版权: GNU 作者信息: Alin Fang(Fang Yunlin) MSN: cst05001@hotmail.com G Talk: [email=cst05001锛爂mail.com]cst05001@[/email] [email=cst05001锛爂mail.com]gmail.com[/email] blog: http://www.alinblog.cn 修改日期: 6 Aug, 2008 实验的目的: 做这次笔记的目的 1.是为了防忘 2.是为了和大家分享 理论: 硬盘就像一个大房间。数据就像是一坨书。 怎样把这些书摆放到房间里面,是你的自由。 但是当你要找你要的书,要找多久,你后果自负(-__-) 你要用多少时间找到你要的书,很大因素上取决于你摆放书的方法吧。至少多数人应该是这么认为的。 比如,我可以有这么几种摆书的方法: 把书一本本整齐的堆放在房子里 买个柜子,把书本分类放到柜子里 买几个柜子堆书,再做一个图书馆那样的索引卡,放在房间里,如果你需要哪方面的书,可以先通过索引卡确定书大概放在哪个位置 硬盘,好比就是这个堆书的房间。 文件系统,就是你管理这些书的方式。 下面解释一下一些概念: block(块): ext2文件系统数据区域存储数据的最小单位。 在创建文件系统时指定。 我这里一个block有1024byte inode: 每个inode有0x80个byte 里面记录的信息包括: 文件在分区里面的位置(以block为单位)。 记录这个位置在inode的第41-44byte。 Inode结构图图下: screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://docs.google.com/File?id=dhkp88bm_50ghfxh9kn_b');}" onmousewheel="return imgzoom(this);" alt="" /> 此图引用自:http://homepage.smc.edu/morgan_david/cs40/analyze-ext2.htm directory(目录): 目录是一种特殊的文件,里面记录了该目录下的文件的inode、类型、文件名长度、文件名 普通文件记录的是普通数据。 一些定义: 分区的最顶级目录的inode号是2 0x80(16) == 128(10) 0x400(16) == 1024(10) 0x800(16) == 2048(10) Group Descriptors: 组描述符。具体内容见下表: 4 1 4 Block number of block bitmap 4 5 8 Block number of inode bitmap 4 9 12 Block number of first inode table block 2 13 14 Number of free blocks in the group 2 15 16 Number of free inodes in the group 2 17 18 Number of directories in the group 2 19 20 Alignment to word 4 21 24 Nulls to pad out 24 bytes 注:这个表格抄袭自quner的实验笔记。 Group Descriptors的第9-12个字节记录了第一个inode表的在文件系统上的绝对位置(以block为单位) 文件定位流程: screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://docs.google.com/File?id=dhkp88bm_51d5pg8xk7_b');}" onmousewheel="return imgzoom(this);" alt="" /> 找到Group Descriptors,获取inode table的位置 => 找到inode table位置,确定最顶级目录inode,确定该目录数据区的位置 => 找到顶级目录,确定要定位的的。 实验步骤: 虚拟出一个文件系统: root@alin:/root# dd if=/dev/zero of=disk.img bs=1M count=1 1 0 records in 1 0 records out 1048576 bytes (1.0 MB) copied, 0.00320471 s, 327 MB/s root@alin:/root# mkfs.ext2 disk.img mke2fs 1.40.8 (13-Mar-2008) disk.img is not a block special device. Proceed anyway? (y,n) y Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) 128 inodes, 1024 blocks 51 blocks (4.98%) reserved for the super user First data block=1 Maximum filesystem blocks=1048576 1 block group 8192 blocks per group, 8192 fragments per group 128 inodes per group Writing inode tables: done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 24 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override. root@alin:/root# mkdir mnt root@alin:/root# mount -o loop disk.img mnt/ root@alin:/root# mkdir mnt/dir1/ root@alin:/root# echo FangYunlin > mnt/dir1/name root@alin:/root# echo 15011424628 > mnt/phone root@alin:/root# umount mnt/ root@alin:/root# 让我们看下这个文件系统的一些属性: root@alin:/root# tune2fs -l disk.img tune2fs 1.40.8 (13-Mar-2008) Filesystem volume name: Last mounted on: Filesystem UUID: f9211136-1617-4fe1-9336-ae637a1bc057 Filesystem magic number: 0xEF53 Filesystem revision #: 1 (dynamic) Filesystem features: ext_attr resize_inode dir_index filetype sparse_super Filesystem flags: signed_directory_hash Default mount options: (none) Filesystem state: clean Errors behavior: Continue Filesystem OS type: Linux Inode count: 128 Block count: 1024 Reserved block count: 51 Free blocks: 983 Free inodes: 114 First block: 1 Block size: 1024 Fragment size: 1024 Reserved GDT blocks: 3 Blocks per group: 8192 Fragments per group: 8192 Inodes per group: 128 Inode blocks per group: 16 Filesystem created: Sat Sep 6 14:18:15 2008 Last mount time: Sat Sep 6 14:19:21 2008 Last write time: Sat Sep 6 14:20:35 2008 Mount count: 1 Maximum mount count: 24 Last checked: Sat Sep 6 14:18:15 2008 Check interval: 15552000 (6 months) Next check after: Thu Mar 5 14:18:15 2009 Reserved blocks uid: 0 (user root) Reserved blocks gid: 0 (group root) First inode: 11 Inode size: 128 Default directory hash: tea Directory Hash Seed: 8847abf9-9ae7-4eeb-bfb9-92df433c42a7 root@alin:/root# root@alin:/root# 我们发现这个ext2文件系统的Block size是1024(10)byte。即0x400(16) 重新梳理一下: 一个inode大小是0x80 一个block size大小是0x400 OK,那么开始模拟文件定位。 我们用16进制编辑器打开我们做出来的带有ext2文件系统的镜像。 这里推荐三个16进制编辑器: khexedit ghex hexdump 我自己使用khexedit。 root@alin:/root# khexedit disk.img & [1] 21238 root@alin:/root# 我们跳到0x800位置,即Group descriptor的位置。其中第9-12byte记录了第一个inode table的位置。 我这里是0x08。 所以第一个inode的位置在第0x8个block的位置。 0x08 X 0x400 = 0x2000 screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://docs.google.com/File?id=dhkp88bm_52dt4k2jdm_b');}" onmousewheel="return imgzoom(this);" alt="" /> 那么我们追踪到inode table的位置0x2000: 我们已经知道: 一个文件系统的顶级目录的inode号是2 一个inode的大小是0x80byte。 所以可以知道0x2080到0x20df就是顶级目录 screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://docs.google.com/File?id=dhkp88bm_53hq7jcfh8_b');}" onmousewheel="return imgzoom(this);" alt="" /> inode的首块数据块指针存放于41-44的位置。从上图可以看出,这个分区的数据(顶级目录)存在于第0x18个block。OK,我们去0x18个block看看。 重新提醒下,这里一个block的大小是0x400byte。 所以0x18 X 0x400 = 0x6000 下图是0x6000处的数据: screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://docs.google.com/File?id=dhkp88bm_54dvfg28cq_b');}" onmousewheel="return imgzoom(this);" alt="" /> 看到了点什么似曾相识的东西了吧? 没错!我们说过,目录也是一种文件。这个目录文件里面都存储了什么数据?我们可以看到文件以及下一级的文件夹! 目录下存放的文件的数据结构是这样的: screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://docs.google.com/File?id=dhkp88bm_55dp2zkpcf_b');}" onmousewheel="return imgzoom(this);" alt="" /> 注:此图引用自 http://homepage.smc.edu/morgan_david/cs40/analyze-ext2.htm (插一句:知道为什么ext2/3文件系统的文件名长度不能超过256个字符了吧?因为文件结构里面只能用8bit的数字来描述文件名长度, 28 = 256) 那么我们打算定位mydir这个文件夹,查看里面的内容。 OK,根据这个表格,我们可以知道在文件名前面前8bit到前5bit记录了当前目录下该文件/文件夹的inode偏移量! 偏移量是指什么呢?就是指相对于inode table起始位置(这里是0x2000)的相对偏移量。 另外,偏移量是以一个inode(0x80bit)为单位的。 这里获得mydir文件夹的inode的偏移量是0x0c。 所以mydir在分区中的绝对位置是: 0x2000 0x80 X (0x0c – 0x01) = 0x2580 之所以减去0x01,是因为inode是从0x00开始计数,而不是0x01。 那么我们去0x2580看看这里是什么东西: screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://docs.google.com/File?id=dhkp88bm_56fvcstsg6_b');}" onmousewheel="return imgzoom(this);" alt="" /> 很眼花吧@_@ 刚才我们说过了inode的结构。一个inode的数据块是在第40-44byte的位置。 这里是多少? 0x26! 那么我们去找mydir这个inode的数据。 0x26 X 0x400 = 0x9800 screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://docs.google.com/File?id=dhkp88bm_57fhjwbhhb_b');}" onmousewheel="return imgzoom(this);" alt="" /> 是不是看到了我们刚才在mydir目录下添加的东西了?哈哈。 OK,我们再去定位一下name这个文件,查看下name里面的内容! 根据之前图示可以知道,一个目录文件里面的文件的inode是在文件名前0x8开始4byte的。 这里可以得出name的inode在inode table的偏移量是0x0d。 OK,我们去看name文件的inode! 0x2000 0x80 X (0x0d – 0x01) = 0x2600 screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://docs.google.com/File?id=dhkp88bm_58dmj8x2ck_b');}" onmousewheel="return imgzoom(this);" alt="" /> 根据inode结构,我们从name这个文件的inode得知name这个文件的数据块是在第0x27块。 我们到这里去看看! 0x400 X 0x27 = 0x9c00 screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://docs.google.com/File?id=dhkp88bm_59jt93t5cc_b');}" onmousewheel="return imgzoom(this);" alt="" /> 哈哈!看到什么了?这个不是我们刚才创建的name文本文件的内容吗?! 原来linux就是这样找到我们看到的文件的啊! 后话: 这个实验笔记没有很多的理论。没有理论支撑的技术是脆弱的。从这个角度讲,这个实验笔记没有多少技术含量和营养。 希望如果有哥们看了这篇笔记,如果能引起深入学习linux的兴趣,那就很好了。 如果想深入研究,可以参考这个页面: http://homepage.smc.edu/morgan_david/cs40/analyze-ext2.htm 另外……总觉得我的帖子在CU总是没人识货-__-|||这真的只是后话…… 鸣谢: wudx同鞋,quner同鞋。 |
|小黑屋|最新主题|手机版|微赢网络技术论坛 ( 苏ICP备08020429号 )
GMT+8, 2024-9-30 07:18 , Processed in 0.145305 second(s), 12 queries , Gzip On, MemCache On.
Powered by Discuz! X3.5
© 2001-2023 Discuz! Team.