pythonlinuxfilesystemspartitionext4

Browse an ext4 filesystem and locate deleted files


List the deleted files and access the data of deleted files.

I'm trying to read the file system block by block, but it showing the partition size 0.
Here is my python code

import os

BLOCK_SIZE = 4096  
DELETED_FILE_SIGNATURE = b'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0' 
def list_deleted_files(partition_path):
    deleted_files = []

    partition_size = os.stat(partition_path).st_size

    with open(partition_path, 'rb') as f:

        num_blocks = partition_size // BLOCK_SIZE
        print(num_blocks)

        for block_number in range(num_blocks):
            block_data = f.read(BLOCK_SIZE)

            if DELETED_FILE_SIGNATURE in block_data:
                file_offset = block_data.index(DELETED_FILE_SIGNATURE)

                path_start = block_data.rfind(b'\0', 0, file_offset) + 1
                path_end = block_data.index(b'\0', file_offset)
                path = block_data[path_start:path_end].decode('utf-8')

                deleted_files.append(path)

    return deleted_files

partition_path = '/dev/nvme0n1p6'
deleted_files = list_deleted_files(partition_path)
print(deleted_files)

Output showing that number blocks is 0.
How to read partition correctly ?


Another method

import os

partition_path = '/dev/nvme0n1p6'

for root, dirs, files in os.walk(partition_path):

for file in files:
    file_path = os.path.join(root, file)
    
    if os.path.islink(file_path) and not os.path.exists(file_path):
        print(f"Deleted file found: {file_path}")

But it ended with 0 iterations of for loop

Solution

  • You should not use os.stat but os.statvfs.

    >>> os.stat('/dev/dm-2')
    os.stat_result(st_mode=25008, st_ino=432, st_dev=5, st_nlink=1, st_uid=0, st_gid=995,
                   st_size=0, st_atime=1679205488, st_mtime=1678984617, st_ctime=1678984617)
    
    >>> os.statvfs('/dev/dm-2')
    os.statvfs_result(f_bsize=4096, f_frsize=4096, f_blocks=4046122, f_bfree=4046122,
                      f_bavail=4046122, f_files=4046122, f_ffree=4045412, f_favail=4045412,
                      f_flag=4098, f_namemax=255)
    

    You can use f_blocks and f_bsize to read the partition.

    This is the same for command line:

    [...]$ stat /dev/dm-2
      File: /dev/dm-2
      Size: 0           Blocks: 0          IO Block: 4096   block special file
    Device: 0,5 Inode: 432         Links: 1     Device type: 254,2
    Access: (0660/brw-rw----)  Uid: (    0/    root)   Gid: (  995/    disk)
    Access: 2023-03-19 06:58:08.718548364 +0100
    Modify: 2023-03-16 17:36:57.311148772 +0100
    Change: 2023-03-16 17:36:57.311148772 +0100
     Birth: 2023-03-16 17:36:53.131148947 +0100
    
    [...]$ stat -f /dev/dm-2
      File: "/dev/dm-2"
        ID: 33d19ee4e765d8c4 Namelen: 255     Type: tmpfs
    Block size: 4096       Fundamental block size: 4096
    Blocks: Total: 4046122    Free: 4046122    Available: 4046122
    Inodes: Total: 4046122    Free: 4045412