-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtest_jffs2.py
More file actions
107 lines (76 loc) · 3.33 KB
/
test_jffs2.py
File metadata and controls
107 lines (76 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from __future__ import annotations
import hashlib
from datetime import datetime, timezone
from io import BytesIO
from typing import BinaryIO
import pytest
from dissect.jffs.exceptions import FileNotFoundError
from dissect.jffs.jffs2 import JFFS2
def test_jffs2_uncompressed(jffs2_bin: BinaryIO) -> None:
fs = JFFS2(jffs2_bin)
root = fs.root
assert root.is_dir()
assert root.nlink == 4 # 3 from root and 1 from subdirectory
assert list(root.listdir().keys()) == ["foo", "test.txt"]
test_file = fs.get("/test.txt")
assert test_file.is_file()
assert test_file.nlink == 1
assert test_file.atime == datetime(2023, 6, 23, 20, 27, 20, tzinfo=timezone.utc)
assert test_file.ctime == datetime(2023, 6, 23, 20, 27, 20, tzinfo=timezone.utc)
assert test_file.mtime == datetime(2023, 6, 23, 20, 27, 20, tzinfo=timezone.utc)
assert test_file.open().read() == b"contents\n"
link_file = fs.get("/foo/bar/link.txt")
assert link_file.is_symlink()
assert link_file.nlink == 1
assert link_file.link == "/test.txt"
def test_jffs2_zlib_compressed(jffs2_zlib: BinaryIO) -> None:
fs = JFFS2(jffs2_zlib)
root = fs.root
assert root.is_dir()
assert list(root.listdir().keys()) == ["folder", "fox-banner.png", "link.txt", "readme.md"]
large_file = fs.get("/fox-banner.png")
assert large_file.is_file()
assert large_file.size == 103911
for time in ["atime", "ctime", "mtime"]:
assert getattr(large_file, time) == datetime(2023, 9, 29, 12, 9, 23, tzinfo=timezone.utc)
with large_file.open() as fh:
data = fh.read()
assert len(data) == 103911
assert hashlib.sha1(data).hexdigest() == "a0dc9f8d64cd34a96778984f3f13ca75cc99bbe4"
def test_jffs2_deleted_file(jffs2_zlib: BinaryIO) -> None:
del_dirent = """
851901e036000000a4e155df01000000010000000000000073be16650e080000
99e595847c15af55666f782d62616e6e65722e706e67
"""
data = jffs2_zlib.read() + bytes.fromhex(del_dirent)
fs = JFFS2(BytesIO(data))
assert len(fs._lost_found) == 1
with pytest.raises(FileNotFoundError):
fs.get("/fox-banner.png")
lost_found = fs.get("/lost+found")
assert list(lost_found.listdir().keys()) == ["fox-banner.png_ino_3_pino_1_ver_1"]
deleted_file = fs.get("/lost+found/fox-banner.png_ino_3_pino_1_ver_1")
assert deleted_file.parent is None
with deleted_file.open() as fh:
data = fh.read()
assert len(data) == 103911
assert hashlib.sha1(data).hexdigest() == "a0dc9f8d64cd34a96778984f3f13ca75cc99bbe4"
def test_jffs2_first_ctf_2023(jffs2_router: BinaryIO) -> None:
fs = JFFS2(jffs2_router)
assert len(fs._dirents) == 133
assert len(fs._inodes) == 1384
assert len(fs._lost_found) == 0
file = fs.get("/upper/www/src/static/images/background.jpg")
with file.open() as fh:
data = fh.read()
assert len(data) == 45469
assert hashlib.sha1(data).hexdigest() == "669b00be651d29e618befddbfecf9f9ee82b93f9"
def test_jffs2_out_of_order_versions(jffs2_zlib: BinaryIO) -> None:
old_dirent = """
851901e03000000078be3efa010000000100000004000000b3be1665080a0000
61748c85eecaede66c696e6b2e747874
"""
data = jffs2_zlib.read() + bytes.fromhex(old_dirent)
fs = JFFS2(BytesIO(data))
assert fs._dirents[1][b"link.txt"][0].version == 1
assert fs._dirents[1][b"link.txt"][1].version == 2