将 SQLITE 数据库从内存中转储出来并在没有原始数据库的情况下查看

逆向工程 记忆 内存转储
2021-07-09 23:35:04

我正在研究一些在运行过程中将多个 Sqlite 数据库加载到内存中的恶意软件。我已经设法将内存转储到一个大块中的磁盘,但是我目前无法查看数据库,因为我无法弄清楚文件应该有多大。

标题看起来完好无损,但我无法轻易弄清楚数据库的“结束”在哪里。有人可以帮我弄清楚整个数据库的字节大小应该是这个标头吗?或者有人可以推荐一些对数据库格式不挑剔的软件,例如,如果我在文件末尾包含垃圾,它会自动找出停止的位置。

格式解释在这里:https : //www.sqlite.org/fileformat.html

Header = SQLite format 3
00 00 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 

Page size = 1024
04 00 

Format write version
01

Format read version
01 

Bytes unreserved space
00 

Maximum embedded payload fraction (must be 64)
40 

Maximum embedded payload fraction (must be 32)
20 
Leaf payload fraction (must be 32)
20 

File Change counter
00 00 01 5f

Size of the database file in pages (16)
00 00 00 10 

Page number of the first freelist trunk page
00 00 00 09 

Total number of freelist pages.
00 00 00 01 

The schema cookie
00 00 00 03 

The schema format number. Supported schema formats are 1, 2, 3, and 4.
00 00 00 04 

Default page cache size.
00 00 00 00 

The page number of the largest root b-tree page when in auto-vacuum or incremental-vacuum modes, or zero otherwise.
00 00 00 00 

The database text encoding. A value of 1 means UTF-8. A value of 2 means UTF-16le. A value of 3 means UTF-16be.
00 00 00 01 

The "user version" as read and set by the user_version pragma.
00 00 00 0F

True (non-zero) for incremental-vacuum mode. False (zero) otherwise.
00 00 00 00 00 

The "Application ID" set by PRAGMA application_id.
00 00 00 00 

Reserved for expansion. Must be zero. 
00 00 00 00 
00 00 00 00
00 00 00 00 
00 00 00 00 
00 00 00 00 

The version-valid-for number.
00 00 00 01

SQLITE_VERSION_NUMBER
00 2D F1 B8

编辑:出现问题可能出在数据库表格式上。这是其中一张表的示例。

转储数据库的格式。表 def 从偏移量 229 开始

tableCommTypeCommType   
CREATE TABLE CommType
(
    CommID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    CommName TEXT NOT NULL
)

如果我自己重新创建数据库,则会得到以下格式。为什么这是不同的?

从偏移 784 开始(之前有很多填充)

tablesqlite_sequencesqlite_sequence
CREATE TABLE sqlite_sequence(name,seq)
utableCommTypeCommType
CREATE TABLE `CommType` (
    `CommID` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    `CommName` TEXT NOT NULL
)

编辑 2:看来我已经转储了创建内存数据库时使用的 RAM。我有很多相同的 CREATE TABLE 字符串在一个重复的序列中进行小的更改。很可能是由于代码执行了“sql = sql + moreSql”或类似的操作,而我刚刚转储了这些字符串,而不是整个内存数据库。我需要做一个更大的内存转储来找到实际的数据库

2个回答

支持二进制模板来解析和查看数据的十六进制编辑器可能是查看 sqlite 数据库开始和结束位置的最佳工具。然后您可以将这些十六进制字节复制到一个单独的文件中,并从那里作为数据库查看。

这种十六进制编辑器的一个例子是010 编辑器,这里是一个用于 sqlitesqlite 二进制模板的例子

.zip 文件上的二进制模板图像

直接来自链接的网站:

最小大小的 SQLite 数据库是一个 512 字节的页面。数据库的最大大小为 2147483646 页,每页 65536 字节或 140,737,488,224,256 字节(约 140 TB)

因此,在您的情况下,我们的页面大小为 1024 字节和 16 页。所以我假设数据库文件的有效负载大约是 16384 字节 + 100 字节的标题。