dissect.database 0.1.dev3__tar.gz → 0.1.dev4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/PKG-INFO +8 -4
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/README.md +6 -2
- dissect_database-0.1.dev4/dissect/database/__init__.py +11 -0
- dissect_database-0.1.dev4/dissect/database/exception.py +5 -0
- dissect_database-0.1.dev4/dissect/database/sqlite3/__init__.py +25 -0
- dissect_database-0.1.dev4/dissect/database/sqlite3/c_sqlite3.py +72 -0
- dissect_database-0.1.dev4/dissect/database/sqlite3/c_sqlite3.pyi +132 -0
- dissect_database-0.1.dev4/dissect/database/sqlite3/exception.py +27 -0
- dissect_database-0.1.dev4/dissect/database/sqlite3/sqlite3.py +650 -0
- dissect_database-0.1.dev4/dissect/database/sqlite3/util.py +144 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/dissect.database.egg-info/PKG-INFO +8 -4
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/dissect.database.egg-info/SOURCES.txt +18 -2
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/pyproject.toml +1 -1
- dissect_database-0.1.dev4/tests/_data/sqlite3/empty.sqlite +0 -0
- dissect_database-0.1.dev4/tests/_data/sqlite3/test.sqlite +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/tests/_docs/conf.py +1 -0
- dissect_database-0.1.dev4/tests/_util.py +22 -0
- {dissect_database-0.1.dev3/tests → dissect_database-0.1.dev4/tests/bsd}/conftest.py +2 -16
- dissect_database-0.1.dev4/tests/sqlite3/__init__.py +0 -0
- dissect_database-0.1.dev4/tests/sqlite3/conftest.py +20 -0
- dissect_database-0.1.dev4/tests/sqlite3/test_default_values.py +75 -0
- dissect_database-0.1.dev4/tests/sqlite3/test_row.py +36 -0
- dissect_database-0.1.dev4/tests/sqlite3/test_sqlite3.py +64 -0
- dissect_database-0.1.dev4/tests/sqlite3/test_util.py +163 -0
- dissect_database-0.1.dev3/dissect/database/bsd/__init__.py +0 -5
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/.gitattributes +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/COPYRIGHT +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/LICENSE +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/MANIFEST.in +0 -0
- {dissect_database-0.1.dev3/dissect/database → dissect_database-0.1.dev4/dissect/database/bsd}/__init__.py +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/dissect/database/bsd/c_db.py +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/dissect/database/bsd/c_db.pyi +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/dissect/database/bsd/db.py +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/dissect/database/bsd/tools/__init__.py +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/dissect/database/bsd/tools/c_rpm.py +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/dissect/database/bsd/tools/c_rpm.pyi +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/dissect/database/bsd/tools/rpm.py +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/dissect.database.egg-info/dependency_links.txt +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/dissect.database.egg-info/requires.txt +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/dissect.database.egg-info/top_level.txt +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/setup.cfg +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/tests/__init__.py +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/tests/_data/bsd/btree.db.gz +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/tests/_data/bsd/hash.db.gz +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/tests/_data/bsd/recno.db.gz +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/tests/_data/bsd/rpm/Packages.gz +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/tests/_docs/Makefile +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/tests/_docs/index.rst +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/tests/bsd/__init__.py +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/tests/bsd/test_db.py +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/tests/bsd/test_rpm.py +0 -0
- {dissect_database-0.1.dev3 → dissect_database-0.1.dev4}/tox.ini +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dissect.database
|
|
3
|
-
Version: 0.1.
|
|
4
|
-
Summary: A Dissect module implementing parsers for various database formats
|
|
3
|
+
Version: 0.1.dev4
|
|
4
|
+
Summary: A Dissect module implementing parsers for various database formats, including Berkeley DB and SQLite3
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
7
7
|
Project-URL: homepage, https://dissect.tools
|
|
@@ -29,8 +29,12 @@ Dynamic: license-file
|
|
|
29
29
|
|
|
30
30
|
# dissect.database
|
|
31
31
|
|
|
32
|
-
A Dissect module implementing parsers for various database formats
|
|
33
|
-
|
|
32
|
+
A Dissect module implementing parsers for various database formats, including:
|
|
33
|
+
|
|
34
|
+
- Berkeley DB
|
|
35
|
+
- SQLite3
|
|
36
|
+
|
|
37
|
+
For more information, please see [the documentation](https://docs.dissect.tools/en/latest/projects/dissect.database/index.html).
|
|
34
38
|
|
|
35
39
|
## Installation
|
|
36
40
|
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
# dissect.database
|
|
2
2
|
|
|
3
|
-
A Dissect module implementing parsers for various database formats
|
|
4
|
-
|
|
3
|
+
A Dissect module implementing parsers for various database formats, including:
|
|
4
|
+
|
|
5
|
+
- Berkeley DB
|
|
6
|
+
- SQLite3
|
|
7
|
+
|
|
8
|
+
For more information, please see [the documentation](https://docs.dissect.tools/en/latest/projects/dissect.database/index.html).
|
|
5
9
|
|
|
6
10
|
## Installation
|
|
7
11
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dissect.database.sqlite3.exception import (
|
|
4
|
+
InvalidDatabase,
|
|
5
|
+
InvalidPageNumber,
|
|
6
|
+
InvalidPageType,
|
|
7
|
+
InvalidSQL,
|
|
8
|
+
NoCellData,
|
|
9
|
+
NoWriteAheadLog,
|
|
10
|
+
)
|
|
11
|
+
from dissect.database.sqlite3.sqlite3 import WAL, Column, Row, SQLite3, Table
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"WAL",
|
|
15
|
+
"Column",
|
|
16
|
+
"InvalidDatabase",
|
|
17
|
+
"InvalidPageNumber",
|
|
18
|
+
"InvalidPageType",
|
|
19
|
+
"InvalidSQL",
|
|
20
|
+
"NoCellData",
|
|
21
|
+
"NoWriteAheadLog",
|
|
22
|
+
"Row",
|
|
23
|
+
"SQLite3",
|
|
24
|
+
"Table",
|
|
25
|
+
]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dissect.cstruct import cstruct
|
|
4
|
+
|
|
5
|
+
# Resource: https://www.sqlite.org/fileformat.html
|
|
6
|
+
sqlite3_def = """
|
|
7
|
+
#define PAGE_FLAG_INTKEY 0x01
|
|
8
|
+
#define PAGE_FLAG_ZERODATA 0x02
|
|
9
|
+
#define PAGE_FLAG_LEAFDATA 0x04
|
|
10
|
+
#define PAGE_FLAG_LEAF 0x08
|
|
11
|
+
|
|
12
|
+
#define PAGE_TYPE_INTERIOR_INDEX PAGE_FLAG_ZERODATA
|
|
13
|
+
#define PAGE_TYPE_INTERIOR_TABLE PAGE_FLAG_INTKEY | PAGE_FLAG_LEAFDATA
|
|
14
|
+
#define PAGE_TYPE_LEAF_INDEX PAGE_FLAG_ZERODATA | PAGE_FLAG_LEAF
|
|
15
|
+
#define PAGE_TYPE_LEAF_TABLE PAGE_FLAG_INTKEY | PAGE_FLAG_LEAFDATA | PAGE_FLAG_LEAF
|
|
16
|
+
|
|
17
|
+
struct header {
|
|
18
|
+
char magic[16];
|
|
19
|
+
uint16 page_size;
|
|
20
|
+
uint8 write_version;
|
|
21
|
+
uint8 read_version;
|
|
22
|
+
uint8 reserved_size;
|
|
23
|
+
uint8 max_embedded_payload_fraction;
|
|
24
|
+
uint8 min_embedded_payload_fraction;
|
|
25
|
+
uint8 leaf_payload_fraction;
|
|
26
|
+
uint32 change_counter;
|
|
27
|
+
uint32 page_count;
|
|
28
|
+
uint32 first_freelist_page;
|
|
29
|
+
uint32 freelist_page_count;
|
|
30
|
+
uint32 schema_cookie;
|
|
31
|
+
uint32 schema_format_number;
|
|
32
|
+
uint32 page_cache_size;
|
|
33
|
+
uint32 largest_root_btree_page;
|
|
34
|
+
uint32 text_encoding;
|
|
35
|
+
uint32 user_version;
|
|
36
|
+
uint32 incremental_vacuum_mode;
|
|
37
|
+
uint32 application_id;
|
|
38
|
+
char reserved1[20];
|
|
39
|
+
uint32 version_valid_for_number;
|
|
40
|
+
uint32 sqlite_version_number;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
struct page_header {
|
|
44
|
+
uint8 flags;
|
|
45
|
+
uint16 first_freeblock;
|
|
46
|
+
uint16 cell_count;
|
|
47
|
+
uint16 cell_start;
|
|
48
|
+
uint8 fragmented_free_bytes;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
struct wal_header {
|
|
52
|
+
uint32 magic;
|
|
53
|
+
uint32 version;
|
|
54
|
+
uint32 page_size;
|
|
55
|
+
uint32 checkpoint_sequence_number;
|
|
56
|
+
uint32 salt1;
|
|
57
|
+
uint32 salt2;
|
|
58
|
+
uint32 checksum1;
|
|
59
|
+
uint32 checksum2;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
struct wal_frame {
|
|
63
|
+
uint32 page_number;
|
|
64
|
+
uint32 page_count;
|
|
65
|
+
uint32 salt1;
|
|
66
|
+
uint32 salt2;
|
|
67
|
+
uint32 checksum1;
|
|
68
|
+
uint32 checksum2;
|
|
69
|
+
};
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
c_sqlite3 = cstruct(endian=">").load(sqlite3_def)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Generated by cstruct-stubgen
|
|
2
|
+
from typing import BinaryIO, Literal, TypeAlias, overload
|
|
3
|
+
|
|
4
|
+
import dissect.cstruct as __cs__
|
|
5
|
+
|
|
6
|
+
class _c_sqlite3(__cs__.cstruct):
|
|
7
|
+
PAGE_FLAG_INTKEY: Literal[1] = ...
|
|
8
|
+
PAGE_FLAG_ZERODATA: Literal[2] = ...
|
|
9
|
+
PAGE_FLAG_LEAFDATA: Literal[4] = ...
|
|
10
|
+
PAGE_FLAG_LEAF: Literal[8] = ...
|
|
11
|
+
PAGE_TYPE_INTERIOR_INDEX: Literal[2] = ...
|
|
12
|
+
PAGE_TYPE_INTERIOR_TABLE: Literal[5] = ...
|
|
13
|
+
PAGE_TYPE_LEAF_INDEX: Literal[10] = ...
|
|
14
|
+
PAGE_TYPE_LEAF_TABLE: Literal[13] = ...
|
|
15
|
+
class header(__cs__.Structure):
|
|
16
|
+
magic: __cs__.CharArray
|
|
17
|
+
page_size: _c_sqlite3.uint16
|
|
18
|
+
write_version: _c_sqlite3.uint8
|
|
19
|
+
read_version: _c_sqlite3.uint8
|
|
20
|
+
reserved_size: _c_sqlite3.uint8
|
|
21
|
+
max_embedded_payload_fraction: _c_sqlite3.uint8
|
|
22
|
+
min_embedded_payload_fraction: _c_sqlite3.uint8
|
|
23
|
+
leaf_payload_fraction: _c_sqlite3.uint8
|
|
24
|
+
change_counter: _c_sqlite3.uint32
|
|
25
|
+
page_count: _c_sqlite3.uint32
|
|
26
|
+
first_freelist_page: _c_sqlite3.uint32
|
|
27
|
+
freelist_page_count: _c_sqlite3.uint32
|
|
28
|
+
schema_cookie: _c_sqlite3.uint32
|
|
29
|
+
schema_format_number: _c_sqlite3.uint32
|
|
30
|
+
page_cache_size: _c_sqlite3.uint32
|
|
31
|
+
largest_root_btree_page: _c_sqlite3.uint32
|
|
32
|
+
text_encoding: _c_sqlite3.uint32
|
|
33
|
+
user_version: _c_sqlite3.uint32
|
|
34
|
+
incremental_vacuum_mode: _c_sqlite3.uint32
|
|
35
|
+
application_id: _c_sqlite3.uint32
|
|
36
|
+
reserved1: __cs__.CharArray
|
|
37
|
+
version_valid_for_number: _c_sqlite3.uint32
|
|
38
|
+
sqlite_version_number: _c_sqlite3.uint32
|
|
39
|
+
@overload
|
|
40
|
+
def __init__(
|
|
41
|
+
self,
|
|
42
|
+
magic: __cs__.CharArray | None = ...,
|
|
43
|
+
page_size: _c_sqlite3.uint16 | None = ...,
|
|
44
|
+
write_version: _c_sqlite3.uint8 | None = ...,
|
|
45
|
+
read_version: _c_sqlite3.uint8 | None = ...,
|
|
46
|
+
reserved_size: _c_sqlite3.uint8 | None = ...,
|
|
47
|
+
max_embedded_payload_fraction: _c_sqlite3.uint8 | None = ...,
|
|
48
|
+
min_embedded_payload_fraction: _c_sqlite3.uint8 | None = ...,
|
|
49
|
+
leaf_payload_fraction: _c_sqlite3.uint8 | None = ...,
|
|
50
|
+
change_counter: _c_sqlite3.uint32 | None = ...,
|
|
51
|
+
page_count: _c_sqlite3.uint32 | None = ...,
|
|
52
|
+
first_freelist_page: _c_sqlite3.uint32 | None = ...,
|
|
53
|
+
freelist_page_count: _c_sqlite3.uint32 | None = ...,
|
|
54
|
+
schema_cookie: _c_sqlite3.uint32 | None = ...,
|
|
55
|
+
schema_format_number: _c_sqlite3.uint32 | None = ...,
|
|
56
|
+
page_cache_size: _c_sqlite3.uint32 | None = ...,
|
|
57
|
+
largest_root_btree_page: _c_sqlite3.uint32 | None = ...,
|
|
58
|
+
text_encoding: _c_sqlite3.uint32 | None = ...,
|
|
59
|
+
user_version: _c_sqlite3.uint32 | None = ...,
|
|
60
|
+
incremental_vacuum_mode: _c_sqlite3.uint32 | None = ...,
|
|
61
|
+
application_id: _c_sqlite3.uint32 | None = ...,
|
|
62
|
+
reserved1: __cs__.CharArray | None = ...,
|
|
63
|
+
version_valid_for_number: _c_sqlite3.uint32 | None = ...,
|
|
64
|
+
sqlite_version_number: _c_sqlite3.uint32 | None = ...,
|
|
65
|
+
): ...
|
|
66
|
+
@overload
|
|
67
|
+
def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ...
|
|
68
|
+
|
|
69
|
+
class page_header(__cs__.Structure):
|
|
70
|
+
flags: _c_sqlite3.uint8
|
|
71
|
+
first_freeblock: _c_sqlite3.uint16
|
|
72
|
+
cell_count: _c_sqlite3.uint16
|
|
73
|
+
cell_start: _c_sqlite3.uint16
|
|
74
|
+
fragmented_free_bytes: _c_sqlite3.uint8
|
|
75
|
+
@overload
|
|
76
|
+
def __init__(
|
|
77
|
+
self,
|
|
78
|
+
flags: _c_sqlite3.uint8 | None = ...,
|
|
79
|
+
first_freeblock: _c_sqlite3.uint16 | None = ...,
|
|
80
|
+
cell_count: _c_sqlite3.uint16 | None = ...,
|
|
81
|
+
cell_start: _c_sqlite3.uint16 | None = ...,
|
|
82
|
+
fragmented_free_bytes: _c_sqlite3.uint8 | None = ...,
|
|
83
|
+
): ...
|
|
84
|
+
@overload
|
|
85
|
+
def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ...
|
|
86
|
+
|
|
87
|
+
class wal_header(__cs__.Structure):
|
|
88
|
+
magic: _c_sqlite3.uint32
|
|
89
|
+
version: _c_sqlite3.uint32
|
|
90
|
+
page_size: _c_sqlite3.uint32
|
|
91
|
+
checkpoint_sequence_number: _c_sqlite3.uint32
|
|
92
|
+
salt1: _c_sqlite3.uint32
|
|
93
|
+
salt2: _c_sqlite3.uint32
|
|
94
|
+
checksum1: _c_sqlite3.uint32
|
|
95
|
+
checksum2: _c_sqlite3.uint32
|
|
96
|
+
@overload
|
|
97
|
+
def __init__(
|
|
98
|
+
self,
|
|
99
|
+
magic: _c_sqlite3.uint32 | None = ...,
|
|
100
|
+
version: _c_sqlite3.uint32 | None = ...,
|
|
101
|
+
page_size: _c_sqlite3.uint32 | None = ...,
|
|
102
|
+
checkpoint_sequence_number: _c_sqlite3.uint32 | None = ...,
|
|
103
|
+
salt1: _c_sqlite3.uint32 | None = ...,
|
|
104
|
+
salt2: _c_sqlite3.uint32 | None = ...,
|
|
105
|
+
checksum1: _c_sqlite3.uint32 | None = ...,
|
|
106
|
+
checksum2: _c_sqlite3.uint32 | None = ...,
|
|
107
|
+
): ...
|
|
108
|
+
@overload
|
|
109
|
+
def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ...
|
|
110
|
+
|
|
111
|
+
class wal_frame(__cs__.Structure):
|
|
112
|
+
page_number: _c_sqlite3.uint32
|
|
113
|
+
page_count: _c_sqlite3.uint32
|
|
114
|
+
salt1: _c_sqlite3.uint32
|
|
115
|
+
salt2: _c_sqlite3.uint32
|
|
116
|
+
checksum1: _c_sqlite3.uint32
|
|
117
|
+
checksum2: _c_sqlite3.uint32
|
|
118
|
+
@overload
|
|
119
|
+
def __init__(
|
|
120
|
+
self,
|
|
121
|
+
page_number: _c_sqlite3.uint32 | None = ...,
|
|
122
|
+
page_count: _c_sqlite3.uint32 | None = ...,
|
|
123
|
+
salt1: _c_sqlite3.uint32 | None = ...,
|
|
124
|
+
salt2: _c_sqlite3.uint32 | None = ...,
|
|
125
|
+
checksum1: _c_sqlite3.uint32 | None = ...,
|
|
126
|
+
checksum2: _c_sqlite3.uint32 | None = ...,
|
|
127
|
+
): ...
|
|
128
|
+
@overload
|
|
129
|
+
def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ...
|
|
130
|
+
|
|
131
|
+
# Technically `c_sqlite3` is an instance of `_c_sqlite3`, but then we can't use it in type hints
|
|
132
|
+
c_sqlite3: TypeAlias = _c_sqlite3
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dissect.database.exception import Error
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class InvalidDatabase(Error):
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class InvalidPageNumber(Error):
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class InvalidPageType(Error):
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class InvalidSQL(Error):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class NoCellData(Error):
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class NoWriteAheadLog(Error):
|
|
27
|
+
pass
|