1

我编写了一个小型 C#/.Net 应用程序,它能够读取 Firefox 的 cookies.sqlite 文件。由于我升级到 Firefox 4,我的应用程序无法打开数据库文件:

执行“connection.Open();”行 (在下面的代码示例中)将有一个 execption 说:

“打开的文件不是数据库文件。文件已加密或不是数据库”

这是我的程序代码:

class Program
{
    static void Main()
    {

        const string PATH_TO_DATABASE = @"C:\Users\Boris\Desktop\TEMP\cookies.sqlite";
        const string CONNECTION_STRING = @"Data Source=" + PATH_TO_DATABASE;

        if (!File.Exists(PATH_TO_DATABASE)) return;

        using (SQLiteConnection connection = new SQLiteConnection(CONNECTION_STRING))
        {
            connection.Open();
            using (SQLiteCommand command = new SQLiteCommand("SELECT id, name, host, path FROM moz_cookies", connection))
            {
                using (SQLiteDataReader read = command.ExecuteReader())
                {
                    while (read.Read())
                    {
                        string id = read[0].ToString();
                        string name = read[1].ToString();
                        string host = read[2].ToString();
                        string path = read[3].ToString();
                        Console.WriteLine("ID: " + id);
                        Console.WriteLine("Name: " + name);
                        Console.WriteLine("Host: " + host);
                        Console.WriteLine("Path: " + path);
                    }
                }
            }
        }
    }
}

我正在为 Sqlite v. 3.6.23.1 使用 .Net Wrapper DLL。该应用程序的目标框架是.Net 2.0。

使用名为 SqliteExpert 的应用程序,我能够毫无问题地打开 sqlite 数据库。

如果有人有想法,那就太好了!

问候,鲍里斯

4

4 回答 4

7

Firefox 4.0 使用 SQLite 版本 3.7.4。(要查看此内容,请下载SQLite 管理器select sqlite_version();在“执行 SQL”选项卡中运行。)

v3.7.4 似乎创建了 v3.6.23.1 无法读取的数据库。我在发行说明中找不到明确说明,但是通过将 cookies.sqlite 文件与文件格式文档进行比较可以清楚地看出格式已更改。具体来说,根据文档,字节 19 (0x13) 应该是1,但是 cookies.sqlite 文件中的那个字节是2. 根据文档:

如果 SQLite 读取到大于 1 的值,则库将拒绝打开数据库。

像上面描述的“写版本”一样,这个字段的存在是为了促进某种程度的前向兼容性,以防万一需要它。如果将来创建的 SQLite 版本使用旧 SQLite 版本可能无法安全读取的文件格式,则该字段将设置为大于 1 的值。

要读取数据库,您需要使用最新版本的 SQLite;不幸的是System.Data.SQLite几乎一年没有更新了。该项目已被 sqlite.org 接管,但目前无法下载

如果您不想等待 sqlite.org 发布基于 v3.7.x 的 .NET 包装器,您可以尝试下载源代码并手动升级SQLite.NET/SQLite.Interop/src/sqlite3.c到最新的融合 C 源文件(可在此处获得)。

编辑:正如sdwilsh所指出的,Firefox 4.0 使用Write-Ahead Logging;正如对该新日记模式的描述所述:

因此,如果旧版本的 SQLite 尝试连接到在 WAL 模式下运行的 SQLite 数据库,它将报告“文件已加密或不是数据库”的错误。

于 2011-03-29T14:29:39.183 回答
3

我有同样的问题。以前我使用 Python 脚本(与 sqlite 集成)从 cookies.sqlite 和 perms.sqlite 文件中获取数据。后者仍然可以正常工作。事实上,所有其他 .sqlite 文件都是可读的……除了 cookies.sqlite 和 places.sqlite。这两个产生“加密或不是数据库”错误。

我没有为 Python(或 sqlite3)寻找升级,而是为 .sqlite 文件创建了一个补丁。此 C 代码将偏移量 18 和 19 处的字节从 2 更改为 1。我在 Cygwin 下的 Windows 上运行它,但它应该在 Unix/Linux 上编译和运行。

警告:不要对原始的 Firefox cookies.sqlite 文件执行此操作。相反,将其复制到临时文件,然后在副本上运行补丁。

// ffpatch.c
// Edits the specified Firefox .sqlite file.
// Changes 0x0202 to 0x0101 at offset 18/19.
// BEFORE
//   0000000   S   Q   L   i   t   e       f   o   r   m   a   t       3  \0
//   0000020 004  \0 002 002  \0   @          \0  \0 005 034  \0  \0  \0   N
// AFTER
//   0000000   S   Q   L   i   t   e       f   o   r   m   a   t       3  \0
//   0000020 004  \0 001 001  \0   @          \0  \0 005 034  \0  \0  \0   N

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#define PROGNAME "ffpatch"
#define MY_OFFSET 18

int main (int argc, char *argv[])
{
  int      fd;
  char     buf[2];
  off_t    offset;
  ssize_t  wsize;

  if (argc != 2)
  {
    fprintf(stderr, "usage: %s sqlite-file\n", PROGNAME);
    exit(1);
  }

  if ((fd = open(argv[1], O_RDWR)) == -1)
  {
    fprintf(stderr, "cannot open %s\n", argv[1]);
    exit(1);
  }

  if ((offset = lseek(fd, MY_OFFSET, SEEK_SET)) != MY_OFFSET)
  {
    fprintf(stderr, "lseek() failed\n");
    exit(1);
  }

  buf[0] = 1;
  buf[1] = 1;
  wsize = write(fd, buf, 2);   

  close(fd);

  exit(0);
}
于 2011-03-29T17:59:31.177 回答
2

您好,非常感谢您的回答!

我使我的应用程序以这种方式工作:

1. 我在这里下载了当前 ADO.NET Connector for .NET 4.0 的源代码:http: //system.data.sqlite.org/index.html/timeline ?r=trunk

也许您必须首先使用匿名用户名和验证码作为密码登录网站。

2.我通过下载安装此ADO.NET连接器获得了sqlite3.dll v.3.7.4的预编译版本:http: //www.devart.com/dotconnect/sqlite/ (您可以使用ADO.NET连接器libs 作为 system.data.sqlite.org 的连接器的替代品。我自己只对 sqlite3.dll 感兴趣。)

3. 从 system.data.sqlite.org 编译源代码后,我将生成的 System.Data.Sqlite.dll 和 sqlite3.dll 复制到我的应用程序输出目录。请注意,这两个 DLL 都是针对 x86 或 x64 机器编译的。

问候

于 2011-03-31T07:19:28.443 回答
-1

我想我有你的问题。您的数据库连接正常。首先你用的是哪个版本的dotnetFramework?因此,您可以下载并使用System.Data.SQLite.dll文件到您的参考文献,然后您的问题可能会得到解决。我认为您使用的System.Data.SQLite.dll是较旧的文件(与您的 dot net 版本不匹配)。

于 2015-05-04T06:12:55.967 回答