如何从硬盘的十六进制视图确定 SQLite db 文件的结尾?

问题描述

我有一个硬盘,它可能已经删除sqlite db 文件。我正在读取磁盘的字节并寻找 sqlite 文件的十六进制签名:53514c69746520666f726d6174203300

我的代码告诉我这些文件在磁盘上的偏移量,但我不知道它们的大小。

例如偏移量

  • 760360
  • 935448

是否可以从十六进制视图确定dbs的大小?据我所知,这些文件没有共同的结束字符。

我的代码

from pathlib import Path
import logging

file_sig = '53514c69746520666f726d6174203300'
disk = Path('/dev/sde1')  # sde is old HDD
try:
    with disk.open(mode="rb") as drive:
        for block_no in range(0,488281250):
            byte = drive.read(512)
            hexx = byte.hex()

            try:
                idx = hexx.index(file_sig)
                byte_nos.append(idx + block_no * 512)
            except ValueError as e:
                logging.debug(e)
                pass
except KeyboardInterrupt:
    pass

with Path('./results.csv').open(mode='w') as f:
    for item in byte_nos:
        f.write("%s\n" % item)

解决方法

感谢@Shawn,我找到了 this 非常有用的 SQLite 数据库指南。

从 SQLite 3.7.1 版本开始,65536 字节的页面大小是 支持的。值 65536 不适合两个字节的整数,因此要 指定 65536 字节的页面大小,该值在偏移量 16 处为 0x00 0x01。

我的 db 文件的开头看起来像:

53514C69746520666F726D617420330010000101004020200000CC9B0000032B000002E1
000000170000008000000002000000000000000000000001000000000000000000000000
00000000000000000000000000000000000000000000CC9B00

所以我认为我的页面大小是 0001 = 65536 字节,即使这似乎是偏移 15(可能是从 0 到 1 计数的情况)。页数存储在偏移量 28 如果...

偏移量 24 处的 4 字节更改计数器与 4 字节完全匹配 偏移量 92 处的版本有效编号

在我的情况下,这些偏移量处的更改计数器偏移量似乎是“00CC9B00”。因此,我将我的页数设为 0000032B,这将转换为 43 的大端 8 位值。

43 (page count) * 65536 (page size) = 2,818,048 bytes = 2.818048 MB

这与 Ubuntu 中的文件资源管理器告诉我的很接近,但它不正确。我知道我的测试数据库是 3,321,856 字节,所以我大约短 503,808 字节。在搜索文件时,我只会扩展我抓取的磁盘部分,因为我只是尝试在原始文件中搜索某些文本,而不是将它们作为数据库加载。