1

I am researching some malware which loads multiple Sqlite Databases into memory during its operation. I've managed to dump the memory to disk in a large block however I cannot view the databases currently as I can't figure out how large the file should be.

The headers appear intact however I can't easily figure out where the "end" of the database is. Can someone help me figure out what the byte size of the entire DB should be form this header? Or can someone suggest some software that is not picky on the format of the DB, eg if I include garbage at the end of the file it will automatically figure out where to stop.

Format explained here: 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

edit: Appears the problem may be in the database table format. Here is an example of one of the tables.

Format of Dumped DB. Table def starts at offset 229

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

If I recreate the DB myself I get the following format. Why is this different?

Starts at offset 784 (lots of padding before)

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

edit2: It appears I've dumped RAM that was used by the in memory database creation. I have lots and lots of the same CREATE TABLE strings in a sequence repeating with small changes. Most likely due to the code doing "sql = sql + moreSql" or something like that and I've just dumped these strings opposed to an entire in memory database. I need to do a bigger memory dump to find the actual DB

  • The problem is possibly in the CREATE TABLE statements. My test DB produces different text in the binary at a different offset. – rolls Mar 23 '17 at 22:21
  • can you provide the sample hash digest? – Nordwald Mar 24 '17 at 6:11
  • Sorry I'm not familiar with what that is. – rolls Mar 24 '17 at 10:05
  • The string-form of a hash of the sample (e.g. md5, sha1, ...) – Nordwald Mar 24 '17 at 10:37
1

A Hex Editor that supports binary templates to parse and view data is probably the best tool to view where a sqlite database starts and ends. Then you can copy these hex bytes out to a seperate file and view as database from there on.

An example of such a hex editor is 010 editor and here is an example of a sqlite binary template for sqlite.

Image of binary template on a .zip file

0

Straight from the linked website:

The minimum size SQLite database is a single 512-byte page. The maximum size database would be 2147483646 pages at 65536 bytes per page or 140,737,488,224,256 bytes (about 140 terabytes)

So in your case, we have a page size of 1024 bytes and 16 pages. So i assume the payload of the database file is about 16384 bytes + 100 bytes for the header.

  • I tried changing the page size to something small like 10 pages and making the file size at least that however i always says corrupt database header. I tried making some test databases and adding junk data at the end however they always load successfully so perhaps there is something else screwy with this DB. – rolls Mar 23 '17 at 7:20
  • 2
    That indicates something is wrong with the header. Could you provide the last 4 header fields or even upload a sample? (e.g. memory page dump) – Nordwald Mar 23 '17 at 7:41
  • When you say header fields what are you referring to? – rolls Mar 23 '17 at 12:11
  • @rolls I'm referring to the last 32 bytes not listed in the table (see header definition, starting at 'Application Id' – Nordwald Mar 23 '17 at 12:22
  • My bad I thought I had the entire thing in there. I've added it in. It appears to be correct and valid. From the testing I've done it appears the table creation is possibly where the problem is. It uses different style quotes and different spacing to what 3011 normally produces. I might try recreating the entire header manually and then appending the pages and see if it will open. If that fails I'll get the C# sqlite source code and step through it to see what specifically it disagrees with. – rolls Mar 23 '17 at 22:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.