From b2c9c5de88ee5eff2ba63481241e851c8315c81d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Stucke?= Date: Fri, 26 Jul 2024 14:08:27 +0200 Subject: [PATCH] feat(handler): add support for squashfs v1 --- tests/handlers/filesystem/test_squashfs.py | 28 ++++++++++++ .../big_endian/__input__/squashfs_v1.0_be.bin | 3 ++ .../squashfs_v1.0_be.bin_extract/apple.txt | 3 ++ .../squashfs_v1.0_be.bin_extract/banana.txt | 3 ++ .../squashfs_v1.0_be.bin_extract/cherry.txt | 3 ++ .../__input__/squashfs_v1.0_le.bin | 3 ++ .../squashfs_v1.0_le.bin_extract/apple.txt | 3 ++ .../squashfs_v1.0_le.bin_extract/banana.txt | 3 ++ .../squashfs_v1.0_le.bin_extract/cherry.txt | 3 ++ unblob/handlers/__init__.py | 1 + unblob/handlers/filesystem/squashfs.py | 45 ++++++++++++++----- 11 files changed, 87 insertions(+), 11 deletions(-) create mode 100755 tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__input__/squashfs_v1.0_be.bin create mode 100644 tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__output__/squashfs_v1.0_be.bin_extract/apple.txt create mode 100644 tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__output__/squashfs_v1.0_be.bin_extract/banana.txt create mode 100644 tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__output__/squashfs_v1.0_be.bin_extract/cherry.txt create mode 100755 tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__input__/squashfs_v1.0_le.bin create mode 100644 tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__output__/squashfs_v1.0_le.bin_extract/apple.txt create mode 100644 tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__output__/squashfs_v1.0_le.bin_extract/banana.txt create mode 100644 tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__output__/squashfs_v1.0_le.bin_extract/cherry.txt diff --git a/tests/handlers/filesystem/test_squashfs.py b/tests/handlers/filesystem/test_squashfs.py index f741f6a8ed..72242524ac 100644 --- a/tests/handlers/filesystem/test_squashfs.py +++ b/tests/handlers/filesystem/test_squashfs.py @@ -6,6 +6,7 @@ from unblob.file_utils import round_up from unblob.handlers.filesystem.squashfs import ( + SquashFSv1Handler, SquashFSv3Handler, SquashFSv4BEHandler, SquashFSv4LEHandler, @@ -115,6 +116,32 @@ """ ) +SQUASHFS_V1_LE_NO_PAD_CONTENTS = unhex( + """\ +00000000 68 73 71 73 25 03 00 00 40 01 00 00 A3 12 4B 00 |hsqs%.....K...K.| +00000010 00 00 00 00 13 DF 4A 00 B0 F7 4A 00 01 00 00 00 |......J...J.....| +00000020 00 80 0F 00 00 01 00 A1 82 C8 4D 18 18 AD 0E 00 |..........M.....| +00000030 00 00 00 90 32 00 00 5D 00 80 00 00 00 3F 91 45 |....2..].....?.E| +00000040 84 68 3B DE DE A6 11 C2 7E 99 A6 01 25 A5 98 99 |.h;.....~...%...| +00000050 6C C8 E3 5F C6 96 35 39 B8 DC E2 A2 BC C3 6A C0 |l.._..59......j.| +00000060 84 B4 3E 33 48 CD 5F 6D FC 6E 0E 10 F9 17 BA D0 |..>3H._m.n......| +00000070 D5 B8 6B D2 D1 5D 62 0D 8C A7 F1 C6 C8 C2 87 1D |..k..]b.........| +00000080 5C C0 F3 5C 04 8D 96 3F 94 B9 F1 6B 12 67 F0 78 |\\..\\...?...k.g.x| +00000090 8C 73 66 F6 D6 15 A1 B2 0A EF BF DE DD B7 DD 40 |.sf............@| +000000a0 7B DD 13 2E 1F AD A3 E7 AB 77 DF A3 D9 28 D2 2E |{........w...(..| +000000b0 83 B2 78 48 5C 1E 19 65 05 85 FD 58 A2 65 BD 83 |..xH\\..e...X.e..| +000000c0 D2 BE E6 C1 B6 27 94 99 AA 0E DF 70 75 85 0B 02 |.....'.....pu...| +000000d0 22 98 17 FE F8 7D 2E 9C 59 3A 24 17 13 0F 76 04 |"....}..Y:$...v.| +000000e0 F8 F2 26 A3 33 B1 3C 48 68 00 20 75 13 02 2D DF |..&.3.p....b[.| +00000130 59 3D 3B 7A AD D3 D4 C6 8E 4A 53 A3 9F 88 E9 0A |Y=;z.....JS.....| +00000140 +""" +) + def pad_contents(contents: bytes, alignment: int): content_size = len(contents) @@ -129,6 +156,7 @@ def pad_contents(contents: bytes, alignment: int): pytest.param(SQUASHFS_V4_BE_NO_PAD_CONTENTS, SquashFSv4BEHandler, id="v4_be"), pytest.param(SQUASHFS_V3_LE_NO_PAD_CONTENTS, SquashFSv3Handler, id="v3_le"), pytest.param(SQUASHFS_V3_BE_NO_PAD_CONTENTS, SquashFSv3Handler, id="v3_be"), + pytest.param(SQUASHFS_V1_LE_NO_PAD_CONTENTS, SquashFSv1Handler, id="v1_le"), ], ) @pytest.mark.parametrize( diff --git a/tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__input__/squashfs_v1.0_be.bin b/tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__input__/squashfs_v1.0_be.bin new file mode 100755 index 0000000000..01cc7e5863 --- /dev/null +++ b/tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__input__/squashfs_v1.0_be.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:529e10775cc152e6c5df0c6c63316811004cc73ce99f03989c86ffd396d631e6 +size 4096 diff --git a/tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__output__/squashfs_v1.0_be.bin_extract/apple.txt b/tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__output__/squashfs_v1.0_be.bin_extract/apple.txt new file mode 100644 index 0000000000..fb25b54492 --- /dev/null +++ b/tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__output__/squashfs_v1.0_be.bin_extract/apple.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:303980bcb9e9e6cdec515230791af8b0ab1aaa244b58a8d99152673aa22197d0 +size 6 diff --git a/tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__output__/squashfs_v1.0_be.bin_extract/banana.txt b/tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__output__/squashfs_v1.0_be.bin_extract/banana.txt new file mode 100644 index 0000000000..f822df33ed --- /dev/null +++ b/tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__output__/squashfs_v1.0_be.bin_extract/banana.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a81483d96b0bc15ad19af7f5a662e14b275729fbc05579b18513e7f550016b1 +size 7 diff --git a/tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__output__/squashfs_v1.0_be.bin_extract/cherry.txt b/tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__output__/squashfs_v1.0_be.bin_extract/cherry.txt new file mode 100644 index 0000000000..3193bfe1b1 --- /dev/null +++ b/tests/integration/filesystem/squashfs/squashfs_v1/big_endian/__output__/squashfs_v1.0_be.bin_extract/cherry.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86baf3529da550a44b0681ffa031b6b676e620e9e06dc5ac1119d0cd21cbcf55 +size 7 diff --git a/tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__input__/squashfs_v1.0_le.bin b/tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__input__/squashfs_v1.0_le.bin new file mode 100755 index 0000000000..5919197ca2 --- /dev/null +++ b/tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__input__/squashfs_v1.0_le.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b45925fa779eae0293635ce0e6dc8760308f25227dd88645d677ba3ffce23e71 +size 4096 diff --git a/tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__output__/squashfs_v1.0_le.bin_extract/apple.txt b/tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__output__/squashfs_v1.0_le.bin_extract/apple.txt new file mode 100644 index 0000000000..fb25b54492 --- /dev/null +++ b/tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__output__/squashfs_v1.0_le.bin_extract/apple.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:303980bcb9e9e6cdec515230791af8b0ab1aaa244b58a8d99152673aa22197d0 +size 6 diff --git a/tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__output__/squashfs_v1.0_le.bin_extract/banana.txt b/tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__output__/squashfs_v1.0_le.bin_extract/banana.txt new file mode 100644 index 0000000000..f822df33ed --- /dev/null +++ b/tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__output__/squashfs_v1.0_le.bin_extract/banana.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a81483d96b0bc15ad19af7f5a662e14b275729fbc05579b18513e7f550016b1 +size 7 diff --git a/tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__output__/squashfs_v1.0_le.bin_extract/cherry.txt b/tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__output__/squashfs_v1.0_le.bin_extract/cherry.txt new file mode 100644 index 0000000000..3193bfe1b1 --- /dev/null +++ b/tests/integration/filesystem/squashfs/squashfs_v1/little_endian/__output__/squashfs_v1.0_le.bin_extract/cherry.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86baf3529da550a44b0681ffa031b6b676e620e9e06dc5ac1119d0cd21cbcf55 +size 7 diff --git a/unblob/handlers/__init__.py b/unblob/handlers/__init__.py index df12eb0df7..3ccbc8f4fd 100644 --- a/unblob/handlers/__init__.py +++ b/unblob/handlers/__init__.py @@ -43,6 +43,7 @@ jffs2.JFFS2OldHandler, ntfs.NTFSHandler, romfs.RomFSFSHandler, + squashfs.SquashFSv1Handler, squashfs.SquashFSv2Handler, squashfs.SquashFSv3Handler, squashfs.SquashFSv3DDWRTHandler, diff --git a/unblob/handlers/filesystem/squashfs.py b/unblob/handlers/filesystem/squashfs.py index d115c35fac..d97d8e3b56 100644 --- a/unblob/handlers/filesystem/squashfs.py +++ b/unblob/handlers/filesystem/squashfs.py @@ -75,30 +75,30 @@ def calculate_chunk(self, file: File, start_offset: int) -> Optional[ValidChunk] ) -class SquashFSv2Handler(_SquashFSBase): - NAME = "squashfs_v2" +class SquashFSv1Handler(_SquashFSBase): + NAME = "squashfs_v1" PATTERNS = [ HexString( """ // 00000000 73 71 73 68 00 00 00 03 00 00 00 00 00 00 00 00 |sqsh............| - // 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 |................| - // squashfs_v2_magic_be - 73 71 73 68 [24] 00 02 + // 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 |................| + // squashfs_v1_magic_be + 73 71 73 68 [24] 00 01 """ ), HexString( """ // 00000000 68 73 71 73 03 00 00 00 00 00 00 00 00 00 00 00 |hsqs............| - // 00000010 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 |................| - // squashfs_v2_magic_le - 68 73 71 73 [24] 02 00 + // 00000010 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| + // squashfs_v1_magic_le + 68 73 71 73 [24] 01 00 """ ), ] C_DEFINITIONS = r""" - typedef struct squashfs2_super_block + typedef struct squashfs_super_block { char s_magic[4]; uint32 inodes; @@ -109,9 +109,32 @@ class SquashFSv2Handler(_SquashFSBase): uint32 directory_table_start; uint16 s_major; uint16 s_minor; - } squashfs2_super_block_t; + } squashfs_super_block_t; """ - HEADER_STRUCT = "squashfs2_super_block_t" + HEADER_STRUCT = "squashfs_super_block_t" + + +class SquashFSv2Handler(SquashFSv1Handler): + NAME = "squashfs_v2" + + PATTERNS = [ + HexString( + """ + // 00000000 73 71 73 68 00 00 00 03 00 00 00 00 00 00 00 00 |sqsh............| + // 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 |................| + // squashfs_v2_magic_be + 73 71 73 68 [24] 00 02 + """ + ), + HexString( + """ + // 00000000 68 73 71 73 03 00 00 00 00 00 00 00 00 00 00 00 |hsqs............| + // 00000010 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 |................| + // squashfs_v2_magic_le + 68 73 71 73 [24] 02 00 + """ + ), + ] class SquashFSv3Handler(_SquashFSBase):