5

On an ext3 (or ext2/4, pick your flavor) filesystem, how would one extract raw byte data that corresponds to a particular inode directly from the hard drive?

Is it possible given, say, an inode number to determine its location on disk (perhaps as an offset from the start of the partition, or some other LBA offset) and then use some utility such as dd or a system call (something like lseek except operating on the filesystem?) to read that data without having to reference it as a file?

I'm assuming this can be done, perhaps with some sort of driver-level utility.

1
  • 1
    I'd be interested in knowing the specific problem you are trying to solve. Maybe there is a good solution to your problem out there. Commented Nov 11, 2014 at 4:23

2 Answers 2

10

The imap command in debugfs can tell you where an inode is. Example:

$ debugfs -R 'imap <128901>' /dev/whatever debugfs 1.42.5 (29-Jul-2012) Inode 128901 is part of block group 16 located at block 524344, offset 0x0400 

To get a raw dump of inode 128901, you'd seek to byte 524344*block_size + 0x0400 and read inode_size bytes. You can get the sizes with the stats command in debugfs, or the separate utility dumpe2fs.

stats or dumpe2fs will also give you a complete listing of all the inode storage areas so you can build your own function that performs the equivalent of imap without actually calling debugfs every time (or running it interactively). Just remember when you do your calculation there is no inode zero. inode 1 starts at byte 0 of the first block of inodes.

If you want to do this in a C program without external programs then you should look at the libext2 library, which is used by all the standard ext2 utilities. I haven't used it myself but I suspect with the libext2 documentation plus the source code of debugfs to use as inspiration, you can write your own imap-like function pretty easily.

... and here's where it occurred to me that maybe you didn't literally mean you wanted the raw data of the inode. Maybe you want the contents of the file that the inode describes. In that case it's even easier. debugfs has a built-in command for that:

debugfs -R 'cat <128901>' /dev/whatever 

prints the contents of the file whose inode number is 128901.

1
  • Thank you for this amazing in comprehensive answer. FWIW: When I landed on this question, raw information was exactly what I was looking for, not just dumping the contents of the file at an inode. I was trying to see how extended filesystem attributes are stored in a file's inode. Commented Feb 22, 2020 at 22:26
1

I wanted to do something similar and ended up using debugfs similar to the other answer, but used the following (where my root file-system is on /dev/nvme0n1p4):

$ debugfs debugfs: open /dev/nvme0n1p4 debugfs: stat /usr/bin/docker-current debugfs: inode_dump <9445675> # After getting the inode number from the output above 

You can also do the following, which gives the same output without the manual inode lookup:

debugfs: inode_dump /usr/bin/docker-current 0000 ed81 0000 2819 f200 e805 ab5d ed28 7d5d ....(......].(}] 0020 be5c 585d 0000 0000 0000 0100 1079 0000 .\X].........y.. 0040 0000 0800 0100 0000 0af3 0200 0400 0000 ................ 0060 0000 0000 0000 0000 0008 0000 0060 8f02 .............`.. 0100 0008 0000 2207 0000 0050 8f02 0000 0000 ...."....P...... 0120 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0140 0000 0000 76bb 0b93 0000 0000 0000 0000 ....v........... 0160 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0200 2000 0000 0025 6ad3 0000 0000 2c57 e8ca ....%j.....,W.. 0220 ed28 7d5d 18db 8a5f 0000 0000 0000 0000 .(}]..._........ 0240 0000 0000 0000 0000 0000 0000 0000 0000 ................ * 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.