Awesome
PySquashfsImage is a lightweight library and tool for reading and extracting squashfs 4.0 little endian images in Python. It provides a high-level API for easy access to these file systems. It is compatible with Python 2.7 and Python 3.1+.
Installation
pip install PySquashfsImage
Compression
Supported compression methods:
- Gzip
- LZ4 (requires Python 3.7+)
- LZO (requires Python 2.7 or 3.5+, also see here)
- XZ (included in Python 3.3+)
- Zstandard (requires Python 3.7+)
Some of them require a third-party library that you'll need to install separately if needed.
Use as a library
List all elements in the image:
from PySquashfsImage import SquashFsImage
image = SquashFsImage.from_file('/path/to/my/image.img')
for item in image:
print(item.name)
image.close()
Print all entries with their absolute path:
from PySquashfsImage import SquashFsImage
# Use with a context manager (recommended).
with SquashFsImage.from_file('/path/to/my/image.img') as image:
for file in image:
print(file.path)
Print all entries that aren't directories:
from PySquashfsImage import SquashFsImage
with open('/path/to/my/image.img', "rb") as f:
imgbytes = f.read()
# Create an image from bytes.
with SquashFsImage.from_bytes(imgbytes) as image:
for item in image:
if not item.is_dir:
print(item.path)
Save the content of a file:
from PySquashfsImage import SquashFsImage
from PySquashfsImage.extract import extract_file
with SquashFsImage.from_file('/path/to/my/image.img') as image:
myfile = image.find('myfilename')
if myfile is not None:
with open('/tmp/' + myfile.name, 'wb') as f:
print('Saving original ' + myfile.path + ' in /tmp/' + myfile.name)
f.write(myfile.read_bytes())
# If the file is large it's preferable to iterate over its content.
hugefile = image.select("/hugedir/myhugefile.big")
with open("myhugefile.big", "wb") as f:
for block in hugefile.iter_bytes():
f.write(block)
# Or use extract_file(), which preserves the file's metadata (except extended attributes).
extract_file(myfile, "myextractedfile")
Save the content of a directory:
from PySquashfsImage import SquashFsImage
from PySquashfsImage.extract import extract_dir
with SquashFsImage.from_file('/path/to/my/image.img') as image:
mydir = image.select("/mydir")
if mydir is not None:
# Metadata is handled the same way as with extract_file().
extract_dir(mydir, "/tmp/mydir")
Use as a command
List
$ pysquashfs list -h
usage: pysquashfs list [-h] [-o OFFSET] [--utc] [--showtz] [-p PATH] [-r] [-t TYPE [TYPE ...]] file
List the contents of the file system
positional arguments:
file squashfs filesystem
optional arguments:
-h, --help show this help message and exit
-o OFFSET, --offset OFFSET absolute position of file system's start. Default: 0
--utc use UTC rather than local time zone when displaying time. Default: False
--showtz show UTC offset when displaying time. Default: False
-p PATH, --path PATH absolute path of directory or file to list. Default: '/'
-r, --recursive whether to list recursively. For the root directory the value is inverted. Default: False
-t TYPE [TYPE ...], --type TYPE [TYPE ...]
when listing a directory, filter by file type with f, d, l, p, s, b, c
Similar to unsquashfs -ll -full
.
Example that only lists directories under the root directory:
$ pysquashfs list myimage.img -r -t d
drwxrwxrwx 1049/1049 468 2018-10-10 08:14:16 /bin
drwxrwxrwx 1049/1049 3 2021-05-14 18:46:17 /dev
drwxrwxrwx 1049/1049 869 2019-11-12 09:31:30 /etc
drwxrwxrwx 1049/1049 3 2021-05-14 18:46:17 /home
drwxrwxrwx 1049/1049 406 2017-12-11 08:14:16 /lib
drwxrwxrwx 1049/1049 98 2021-05-14 18:46:17 /mnt
drwxrwxrwx 1049/1049 3 2021-05-14 15:12:17 /proc
drwxrwxrwx 1049/1049 3 2021-05-14 15:12:17 /root
drwxrwxrwx 1049/1049 690 2021-05-14 12:11:44 /sbin
drwxrwxrwx 1049/1049 3 2021-05-14 15:12:17 /sys
drwxrwxrwx 1049/1049 3 2021-05-14 18:46:17 /tmp
drwxrwxrwx 1049/1049 364 2021-05-14 18:46:17 /usr
drwxrwxrwx 1049/1049 60 2018-11-09 05:38:43 /var
13 file(s) found
Extract
$ pysquashfs extract -h
usage: pysquashfs extract [-h] [-o OFFSET] [-d DEST] [-p PATH] [-f] [-q] file
Extract files from the file system
positional arguments:
file squashfs filesystem
optional arguments:
-h, --help show this help message and exit
-o OFFSET, --offset OFFSET absolute position of file system's start. Default: 0
-d DEST, --dest DEST directory that will contain the extracted file(s). If it doesn't exist it will be created. Default: current directory
-p PATH, --path PATH absolute path of directory or file to extract. Default: '/'
-f, --force overwrite files that already exist. Default: False
-q, --quiet don't print extraction status. Default: False
On Unix, this command tries to give the same output as unsquashfs
, but should
not be preferred over it. Some features like extended attributes are missing.
On Windows, you might create symlinks with a privileged account or with an unprivileged one if Developer Mode is enabled. Otherwise, a regular file containing the target will be created. Special files are ignored.
Example command that will extract /bin
under /tmp
:
$ pysquashfs extract myimage.img -p /bin -d /tmp
Scan
$ pysquashfs scan -h
usage: pysquashfs scan [-h] [--utc] [--showtz] file
Find and show all the superblocks that can be found in a file
positional arguments:
file squashfs filesystem
optional arguments:
-h, --help show this help message and exit
--utc use UTC rather than local time zone when displaying time. Default: False
--showtz show UTC offset when displaying time. Default: False
Output is similar to unsquashfs -s [-UTC]
.
Example:
$ pysquashfs scan myimage.img
Superblock #1
Magic: 0x73717368
Major: 4
Minor: 0
Creation or last append time: 2018-06-16 16:46:23
Size: 7864320
Compression: XZ
Block size: 524288
Flags: 192
Number of fragments: 27
Number of inodes: 361
Number of ids: 1
Inode table start: 0x77E924
Directory table start: 0x77FAF2
Fragment table start: 0x781448
Lookup table start: 0x7817C6
ID table start: 0x7817D4
xattr ID table start: 0xFFFFFFFFFFFFFFFF
Offset: 161843