GetDbHandles.cpp 4.1 KB
Newer Older
L
ljc545w 已提交
1 2
#include "pch.h"

L
ljc545w 已提交
3
// 联系人相关库偏移
L
ljc545w 已提交
4
#define SqlHandleMicroMsgOffset  0x2366934
L
ljc545w 已提交
5
// 公众号相关库偏移
L
ljc545w 已提交
6
#define SqlHandlePublicMsgOffset 0x239E3C8
L
ljc545w 已提交
7
// 聊天记录相关库偏移
L
ljc545w 已提交
8
#define SqlHandleMSGOffset 0x239FF68
L
ljc545w 已提交
9

L
ljc545w 已提交
10
// 保存数据库信息的容器
L
ljc545w 已提交
11 12
vector<DbInfoStruct> dbs;

L
ljc545w 已提交
13 14 15 16 17
/*
* 根据数据库名从`dbs`中检索数据库句柄
* dbname:数据库名
* return:DWORD,如果检索成功,返回数据库句柄,否则返回`0`
*/
L
ljc545w 已提交
18 19 20 21 22 23 24 25 26 27
DWORD GetDbHandleByDbName(wchar_t* dbname) {
	if (dbs.size() == 0)
		GetDbHandles();
	for (unsigned int i = 0; i < dbs.size() - 1; i++) {
		if (!lstrcmpW(dbs[i].dbname, dbname))
			return dbs[i].handle;
	}
	return 0;
}

L
ljc545w 已提交
28 29 30 31
/*
* 供外部调用的获取数据库信息接口
* return:DWORD,`dbs`首个成员地址
*/
32
#ifndef USE_SOCKET
L
ljc545w 已提交
33 34 35 36 37
DWORD GetDbHandlesRemote() {
	if (dbs.size() == 0)
		GetDbHandles();
	return (DWORD)dbs.data() ;
}
38
#endif
L
ljc545w 已提交
39

L
ljc545w 已提交
40 41 42 43
/*
* 获取数据库信息的具体实现
* return:void
*/
44
void* GetDbHandles() {
L
ljc545w 已提交
45 46
	dbs.clear();
	DWORD WeChatWinBase = GetWeChatWinBase();
L
ljc545w 已提交
47
	DWORD SqlHandleBaseAddr = WeChatWinBase + SqlHandleMicroMsgOffset;
L
ljc545w 已提交
48 49
	DWORD SqlHandleBeginAddr = 0x0;
	DWORD SqlHandleEndAddr = 0x0;
L
ljc545w 已提交
50
	DWORD SqlHandlePublicMsgAddr = *(DWORD*)(WeChatWinBase + SqlHandlePublicMsgOffset);
L
ljc545w 已提交
51
	DWORD SqlHandleMSGAddr = *(DWORD*)(WeChatWinBase + SqlHandleMSGOffset);
L
ljc545w 已提交
52 53 54
	__asm {
		mov eax, [SqlHandleBaseAddr];
		mov ecx, [eax];
L
ljc545w 已提交
55
		add ecx, 0x1428;
L
ljc545w 已提交
56 57 58 59 60
		mov eax, [ecx];
		mov SqlHandleBeginAddr, eax;
		mov eax, [ecx + 0x4];
		mov SqlHandleEndAddr, eax;
	}
L
ljc545w 已提交
61
	DWORD dwHandle = 0x0;
L
ljc545w 已提交
62
	wstring dbnames = L"";
L
ljc545w 已提交
63
	// 获取联系人数据库句柄
L
ljc545w 已提交
64
	while (SqlHandleBeginAddr < SqlHandleEndAddr) {
L
ljc545w 已提交
65
		dwHandle = *(DWORD*)SqlHandleBeginAddr;
L
ljc545w 已提交
66 67 68
		SqlHandleBeginAddr += 0x4;
		if (SqlHandleBeginAddr == SqlHandleEndAddr)
			break;
L
ljc545w 已提交
69
		if(dbnames.find(L"|" + (wstring)(wchar_t*)(*(DWORD*)(dwHandle + 0x50)) + L"|",0) != wstring::npos)
L
ljc545w 已提交
70 71
			continue;
		DbInfoStruct db = { 0 };
L
ljc545w 已提交
72
		dbnames = dbnames + L"|" + (wchar_t*)(*(DWORD*)(dwHandle + 0x50)) + L"|";
L
ljc545w 已提交
73
		db.dbname = (wchar_t*)(*(DWORD*)(dwHandle + 0x50));
L
ljc545w 已提交
74
		db.l_dbname = wcslen(db.dbname);
L
ljc545w 已提交
75 76
		db.handle = *(DWORD*)(dwHandle + 0x3C);
		ExecuteSQL(*(DWORD*)(dwHandle + 0x3C), "select * from sqlite_master where type=\"table\";",(DWORD)GetDbInfo,&db);
L
ljc545w 已提交
77 78
		dbs.push_back(db);
	}
L
ljc545w 已提交
79
	// 获取公众号数据库句柄
L
ljc545w 已提交
80 81
	for (int i = 1; i < 4; i++) {
		dwHandle = *((DWORD*)(SqlHandlePublicMsgAddr + i * 0x4));
L
ljc545w 已提交
82
		if (dbnames.find(L"|" + (wstring)(wchar_t*)(*(DWORD*)(dwHandle + 0x50)) + L"|", 0) != wstring::npos)
L
ljc545w 已提交
83 84
			continue;
		DbInfoStruct db = { 0 };
L
ljc545w 已提交
85
		dbnames = dbnames + L"|" + (wchar_t*)(*(DWORD*)(dwHandle + 0x50)) + L"|";
L
ljc545w 已提交
86
		db.dbname = (wchar_t*)(*(DWORD*)(dwHandle + 0x50));
L
ljc545w 已提交
87
		db.l_dbname = wcslen(db.dbname);
L
ljc545w 已提交
88 89
		db.handle = *(DWORD*)(dwHandle + 0x3C);
		ExecuteSQL(*(DWORD*)(dwHandle + 0x3C), "select * from sqlite_master where type=\"table\";", (DWORD)GetDbInfo, &db);
L
ljc545w 已提交
90 91
		dbs.push_back(db);
	}
L
ljc545w 已提交
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
	// 获取聊天记录数据库句柄
	int msgdb_count = *(int*)(SqlHandleMSGAddr + 0x4);
	DWORD MsgdwHandle = *(DWORD*)(SqlHandleMSGAddr + 0x1C);
	for (int i = 0; i < msgdb_count; i++) {
		for (int j = 0; j < 4; j++) {
			dwHandle = *(DWORD*)(MsgdwHandle + 0x14 + j * 4);
			if (dbnames.find(L"|" + (wstring)(wchar_t*)(*(DWORD*)(dwHandle + 0x50)) + L"|", 0) != wstring::npos)
				continue;
			DbInfoStruct db = { 0 };
			dbnames = dbnames + L"|" + (wchar_t*)(*(DWORD*)(dwHandle + 0x50)) + L"|";
			db.dbname = (wchar_t*)(*(DWORD*)(dwHandle + 0x50));
			db.l_dbname = wcslen(db.dbname);
			db.handle = *(DWORD*)(dwHandle + 0x3C);
			ExecuteSQL(*(DWORD*)(dwHandle + 0x3C), "select * from sqlite_master where type=\"table\";", (DWORD)GetDbInfo, &db);
			dbs.push_back(db);
		}
		MsgdwHandle += 0x68;
	}
L
ljc545w 已提交
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
	// 添加一个空结构体,作为读取结束标志
	DbInfoStruct db_end = { 0 };
	dbs.push_back(db_end);
#ifdef _DEBUG
	for (unsigned int i = 0; i < dbs.size() - 1; i++) {
		printf("dbname = %ws,handle = 0x%08X,table_count:%d\n",dbs[i].dbname,dbs[i].handle,dbs[i].tables.size());
		for (unsigned int j = 0; j < dbs[i].tables.size();j++) {
			cout << "name     = " << dbs[i].tables[j].name << endl;
			cout << "tbl_name = " << dbs[i].tables[j].tbl_name << endl;
			cout << "rootpage = " << dbs[i].tables[j].rootpage << endl;
			cout << "sql      = " << dbs[i].tables[j].sql << endl;
			cout << endl;
		}
		cout << endl;
	}
#endif
126
	return dbs.data();
L
ljc545w 已提交
127
}