65.9K
CodeProject 正在变化。 阅读更多。
Home

检索并搜索您的 Chrome 历史记录

starIconstarIconstarIconstarIconstarIcon

5.00/5 (7投票s)

2019年6月14日

CPOL

3分钟阅读

viewsIcon

44465

downloadIcon

502

如何通过访问“history”Sqlite 数据库来检索和搜索您的 Chrome 历史记录

如何查看您的 Chrome 历史记录

首先,让我们看看查看 Chrome 历史记录的“正常”方法。只需转到历史记录菜单选项,如下所示

然后您将看到所有最近访问的网站,从后到前。

Chrome 取证

Google Chrome 将其浏览历史记录存储为名为“history”的 SQLite 数据库,该数据库位于不同的位置,具体取决于操作系统。在 Windows 中,该位置位于 %APPDATA% 文件夹中。

还有存档历史记录,早于 History 文件中的信息。请注意,存档历史记录仅包含访问记录。

SQL 查询

为了获取最近(或所有)历史记录,或者对历史记录数据库执行搜索,我准备了几个 SQL 查询

获取所有历史记录

SELECT last_visit_time, datetime(last_visit_time / 1000000 - 11644473600, _
'unixepoch', 'localtime'),url,title FROM urls ORDER BY last_visit_time DESC

所以代码将是

#define CHROME_HISTORY_SQL_QUERY "SELECT last_visit_time, 
datetime(last_visit_time / 1000000 - 11644473600, 'unixepoch', 'localtime'),
url,title FROM urls ORDER BY last_visit_time DESC"

Fetch history based on a search term

在这种情况下,我们希望允许一个搜索词,为了方便起见,我们假设如果搜索词是“child”,我们将搜索“*child*”,在 SQL 语法中是“%child%”。所以代码将是 2 个预处理器定义

#define CHROME_HISTORY_SQL_QUERY2_LEFT "SELECT last_visit_time, 
    datetime(last_visit_time / 1000000 - 11644473600, 'unixepoch', 'localtime'),
    url,title FROM urls WHERE title like '"

#define CHROME_HISTORY_SQL_QUERY2_RIGHT "' ORDER BY last_visit_time DESC"

Fetch history based on a complex query

当我们想添加一个查询词,例如“Where last_visit_time > <date>”时,我们使用以下代码

#define CHROME_HISTORY_SQL_QUERY_LEFT "SELECT last_visit_time, 
  datetime(last_visit_time / 1000000 - 11644473600, 'unixepoch', 'localtime'),
  url,title FROM urls "

#define CHROME_HISTORY_SQL_QUERY_RIGHT " ORDER BY last_visit_time DESC"

数据结构

首先,我们为浏览历史记录定义了一个通用数据结构,它应该支持所有浏览器,并且将在本文中在 Google Chrome 的范围内进行演示

typedef struct _SGBrowserHistory
{
    int Browser;  // 1 = chrome, 2 = firefox, 3 = ie
    WCHAR SiteURL[URL_MAXSIZE];
    WCHAR SiteName[1024];
    WCHAR LastVisitDate[256];
} SGBrowserHistory;

利用 CSimpleArray 类也很有用。我们定义一个新类型 SGBrowserHistoryArray ,它将用于存储一个动态数组,其中包含 SGBrowserHistory 数据结构的元素。所以我们有

  • SGBrowserHistory,和
  • SGBrowserHistoryArray
typedef CSimpleArray<SGBrowserHistory> SGBrowserHistoryArray;

我们的程序

我创建了一个小程序,该程序使用我们为我们的几个产品开发的类库。

现在我们可以深入研究代码

使用我们类的最简单方法是只获取所有已存储的历史记录。这可能需要时间,我们不希望在 Chrome 使用时阻止或被阻止(并且当它被使用时,它的数据库被访问和更改),因此首先创建我们自己的备份数据库并将其命名为 temp.db。(定义为 TEMP_DB_NAME)。

bool SGBrowsingHistory::GetChromeHistory
    (SGBrowserHistoryArray *history, CString FileName,CString SearchString)
{
    bool result = false;
    WCHAR szPath[MAX_PATH];
    //const char *lpTail;
    utils::SG_GetSpecialFolderPath(szPath, CSIDL_LOCAL_APPDATA);
    StrCat(szPath, CHROMEHISTORY);

    WCHAR filename[MAX_PATH + 1] = { TEMP_DB_NAME };

    if (CopyFile(szPath, filename, FALSE))
    {
        if (GetFileAttributes(filename) != 0xFFFFFFFF)
        {
        }
        else
        {
            wprintf(L"Error: Cannot find login data for Google Chrome browser\r\n");
        }
        bool result = db->GetChromeHistoryRecords(filename, history, SearchString);
    }

    return result;
}

将结果存储在我们自己的数据库中

我们的程序不仅与 Chrome 的数据库交互,还创建我们自己的数据库,我们可以在其中根据需要存储数据。

SG_Database 类

我已经创建了一个用于处理数据库的类,大多数情况下我将使用 sqlite,我认为这是最好的。我还使用了 Tyushkov Nikolay 的 CppSQLite3U,它是一个包装类,更易于支持 UNICODE。

创建 ChromeHistory 表

为了创建 ChromeHistory 表,我们使用一个预处理器定义,如下所示

#define createTableChromeHistory L"CREATE TABLE IF NOT EXISTS ChromeHistory(\
id INTEGER PRIMARY KEY AUTOINCREMENT,\
created TIMESTAMP not null default CURRENT_TIMESTAMP,\
date_last_visited TEXT not null default '',\
site_name TEXT not null default '',\
size_url TEXT not null default '',\
);"

记录错误

我在之前的文章中写了很多关于这个主题的内容。在这种情况下,这里是一个用于记录 SQL 错误的非常简单的函数。

#define STR_ERROR_RUNNING_QEURY L"Error running query: %s. Error message: %s. Function = %s\n"

void CSGDatabase::LogSqlError(CppSQLite3Exception &e, CString Function, CString sql)
{
    wprintf(STR_ERROR_RUNNING_QEURY, sql.GetBuffer(), e.errorMessage(), Function.GetBuffer());
}

然后我们创建一个宏

#define LOGSQLERROR(e,sql) LogSqlError(e, (CString)__FUNCTION__, sql);

用于已经调用它,以及 LogSqlError 已调用的当前函数。

LOGSQLERROR(e,sql);

有关 Chrome 数据库的其他信息

日期和时间的存储方式

History 文件使用不同的时间戳。

visits.visit_time

Chrome 将每次访问给定网站的日期存储在 visits.visit_time 中。 visits.visit_time 是自 1601 年 1 月 1 日 UTC 以来(以)微秒为单位的。

这里有一个将 Chrome 时间转换为系统时间的函数。

    // convert chrome time (as long long integer) to system time
    SYSTEMTIME intChromeTimeToSysTime(long long int UnixTime)
    {
        time_t dosTime(UnixTime);
        // Note that LONGLONG is a 64-bit value
        SYSTEMTIME systemTime;


        LARGE_INTEGER utcFT = { 0 };
        utcFT.QuadPart = ((unsigned __int64)dosTime) * 10000000;

        FileTimeToSystemTime((FILETIME*)&utcFT, &systemTime);
        return systemTime;
    }

请注意,此时间戳与 Windows FILETIME 不同,后者是自 1601 年 1 月 1 日 UTC 以来(以)100 纳秒为单位的。

时间戳

History 文件使用不同的时间戳。

visits.visit_time

visits.visit_time 是自 1601 年 1 月 1 日 UTC 以来(以)微秒为单位的。

以下代码演示了将 Chrome 访问时间转换为人类可读格式的正确方法

date_string = datetime.datetime( 1601, 1, 1 )
            + datetime.timedelta( microseconds=timestamp )

请注意,此时间戳与 Windows FILETIME 不同,后者是自 1601 年 1 月 1 日 UTC 以来(以)100 纳秒为单位的。

downloads.start_time

downloads.start_time 是自 1970 年 1 月 1 日 UTC 以来(以)秒为单位的。

延伸阅读

历史

  • 2019 年 6 月 14 日:初始版本
© . All rights reserved.