[sleuthkit-users] ext3 inode block and indirect block pointers data structures
Brought to you by:
carrier
From: Okti <wma...@gm...> - 2014-03-13 11:57:41
|
Hi, Pardon if this may seem as a "stupid" or a "newbie" question, but because I’m self-learning and don't really have nobody to ask, and since i'm using TSK tools I think it would be ok to post. So I'm learning about ext2/3 fs's and was trying to recover some files "manually" (which was easy at first, but not so easy when recovering large files). I was trying to look at direct and indirect block pointers to see how this data actually looks (both for deleted and existing files), but it seems I cannot really find these data structures. First of all I would like to say that I have a bit of an unusual setup. Since I have only 500GB disk on my pc and my linux partition is 350GB, i cannot just make an image of this partition. So instead, I copied 10GB from my windows partition (with dd), then zeroed out all remaining data (by copying bits from /dev/zero, again with dd), and made ext3 fs with mkfs. All looks good and I can mount this "disk" as it would be a valid ext3 partition. Then for some reason I thought it would be OK to create a partition table for this "disk", to make it look more "real" but then decided it was not such a good idea so I removed partition table. I don't know if this could be relevant to the problem which I'm having, or maybe simply data in my image is corrupt now. TSK tools recognize this as a valid ext3 partition. $ dd if=data.dd bs=512 skip=2 count=1 | xxd 0000000: 80fa 0a00 b0e3 2b00 c831 0200 b495 2a00 ......+..1....*. 0000010: 67fa 0a00 0000 0000 0200 0000 0200 0000 g............... 0000020: 0080 0000 0080 0000 f01f 0000 e23e 2053 .............> S 0000030: 473f 2053 0900 ffff 53ef 0100 0100 0000 G? S....S....... 0000040: 108c 1853 0000 0000 0000 0000 0100 0000 ...S............ 0000050: 0000 0000 0b00 0000 0001 0000 3c00 0000 ............<... 0000060: 0200 0000 0300 0000 5c71 eed4 4d97 4dd8 ........\q..M.M. 0000070: 843d 6ab0 7677 a6e5 506f 7765 7253 6f75 .=j.vw..PowerSou 0000080: 7263 6500 0000 0000 0000 0000 0000 0000 rce............. 0000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000c0: 0000 0000 0000 0000 0000 0000 0000 be02 ................ 00000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000e0: 0800 0000 0000 0000 0000 0000 f571 8b86 .............q.. 00000f0: 6b6b 48fe 8921 c500 33ab 6667 0101 0000 kkH..!..3.fg.... 0000100: 0c00 0000 0000 0000 108c 1853 0102 1500 ...........S.... 0000110: 0202 1500 0302 1500 0402 1500 0502 1500 ................ 0000120: 0602 1500 0702 1500 0802 1500 0902 1500 ................ 0000130: 0a02 1500 0b02 1500 0c02 1500 0d02 1500 ................ 0000140: 0e06 1500 0000 0000 0000 0000 0000 0008 ................ 0000150: 0000 0000 0000 0000 0000 0000 1c00 1c00 ................ 0000160: 0100 0000 0000 0000 0000 0000 0000 0000 ................ 0000170: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000180: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000190: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00001a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00001b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00001c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00001d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00001e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00001f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ So we can see Volume label and superblock signatures, so all looks good (or correct me if I'm wrong). Now let's say I want to view some inode data structures, First thing we need view primary group descriptor table which is located one block after a superblock, or it supposed to be.. $ blkcat -f ext3 data.dd 1 | xxd 0000000: c002 0000 c102 0000 c202 0000 397b e51f ............9{.. 0000010: 0200 0000 0000 0000 0000 0000 0000 0000 ................ 0000020: c082 0000 c182 0000 c282 0000 3f7b f01f ............?{.. 0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000040: 0000 0100 0100 0100 0200 0100 ff7d f01f .............}.. 0000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000060: c082 0100 c182 0100 c282 0100 3f7b f01f ............?{.. 0000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000080: 0000 0200 0100 0200 0200 0200 ff7d f01f .............}.. 0000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000a0: c082 0200 c182 0200 c282 0200 3f7b f01f ............?{.. 00000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000c0: 0000 0300 0100 0300 0200 0300 ff7d f01f .............}.. 00000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000e0: c082 0300 c182 0300 c282 0300 3f7b f01f ............?{.. 00000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000100: 0000 0400 0100 0400 0200 0400 fe7d ef1f .............}.. So bytes 8-11 should show starting block address of inode table, which in my case is c202. Um, i'm not really sure how to interpret this value. If this is in hexadecimal and I would want to covert this to decimal, minding endian ordering I would get 8236. Which seems rather stupid to have inode table located in this block. Again please correct me if I'm wrong. So my first question would be, why do I have output like this? It's easy how it is displayed in the book block address 4 (0400) My second question: Let's say I want to view the contents of inode specially direct and indirect block pointers. I have inode 237114 (which is an existing .jpg file). First I need to locate to which group this inode belongs to which is easy, I can calculate this myself or just look at istat's output. Next I need to find group descriptor table for this group, and find inode table block address. I'm note sure how to do that, assuming this group (group 29) has no superblock backup in the first block, so I could take starting block address of this group plus one and I should be looking at group descriptor right? Well if I try to do that, all I got is 0's and f's : $ dd if=data.dd bs=4096 skip=950273 count=1 | xxd 0000000: ff01 0000 0000 0000 0000 0000 0000 0000 ................ 0000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000100: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000110: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000120: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000130: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000140: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000150: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000160: 0000 0000 0000 0000 0000 0000 0000 0000 ................ Although this is not necessary. According to ext kernel wiki page, I can calculate the location of this inode in the inode table by: (inode - 1) % inodes/per group. There is also an example how to get byte address within the inode table, but I’m not sure if I need this one. $ echo "(237114-1)%8176" | bc 9 This is in fact correct, if I would use debugfs utility to check this information all looks good: $ debugfs data.dd debugfs 1.42 (29-Nov-2011) debugfs: imap <237114> Inode 237114 is part of block group 29 located at block 950274, offset 0x0900 debugfs: I don't exactly understand what this offset means? Offset within the inode table? If so, shouldn't user created files start from inode 16?. So we got block address of the inode table in this group (which is also shown in fsstat's output). Also apparently my inode size is 256 bytes, not standard 128. $ dd if=data.dd bs=4096 skip=950274 | dd bs=256 skip=9 count=1 | xxd 1+0 records in 1+0 records out 256 bytes (256 B) copied, 0.000525543 s, 487 kB/s 0000000: a481 0000 e1af 0000 2e3f 2053 2e3f 2053 .........? S.? S 0000010: 2e3f 2053 0000 0000 0000 0100 5800 0000 .? S........X... 0000020: 0000 0000 0000 0000 6590 0e00 6690 0e00 ........e...f... 0000030: 6790 0e00 6890 0e00 6990 0e00 6a90 0e00 g...h...i...j... 0000040: 6b90 0e00 6c90 0e00 6d90 0e00 6e90 0e00 k...l...m...n... 0000050: 6f90 0e00 0000 0000 0000 0000 0000 0000 o............... 0000060: 0000 0000 0f5e c3a7 0000 0000 0000 0000 .....^.......... 0000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000080: 0400 0000 0000 0000 0000 0000 0000 0000 ................ 0000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ This looks like a valid inode data structure, first two bytes should show us file mode (814a), and the rest of it looks good. However, when I try look at that location of first direct block pointers bytes 40-43, i got : 6590 0e00, when converted to decimal minding endian ordering I got 955984 (again I can be wrong with this number). But this looks rather good, I checked block range for this group and block address 955984 falls within group 29. When i try to look at the contents of this block all I got is 0' and f's (i piped my output through "less" to not mess up my terminal, but i can assure you there was nothing). So why is that? For all i know i could be looking at some random inode data structure, totally not related to my file.. When I removed this file and tried to look at this again everything looked fine, block pointers have been wiped as it should be on deleted files: $ dd if=data.dd bs=4096 skip=950274 | dd bs=256 skip=9 count=1 | xxd 1+0 records in 1+0 records out 0000000: a481 0000 0000 0000 2e3f 2053 3387 2153 .........? S3.!S 0000010: 3387 2153 3387 2153 0000 0000 0000 0000 3.!S3.!S........ 256 bytes (256 B) copied0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ , 0.000143114 s, 1.8 MB/s 0000060: 0000 0000 0f5e c3a7 0000 0000 0000 0000 .....^.......... 0000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000080: 0400 0000 0000 0000 0000 0000 0000 0000 ................ 0000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ So I'm a really looking at the correct inode data structures? Thanks. |