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

L
ljc545w 已提交
3
// 联系人相关库偏移
L
ljc545w 已提交
4
#define SqlHandleMicroMsgOffset 0x2363934
L
ljc545w 已提交
5
// 公众号相关库偏移
L
ljc545w 已提交
6
#define SqlHandlePublicMsgOffset 0x239B3C8
L
ljc545w 已提交
7

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

L
ljc545w 已提交
11 12 13 14 15
/*
* 根据数据库名从`dbs`中检索数据库句柄
* dbname:数据库名
* return:DWORD,如果检索成功,返回数据库句柄,否则返回`0`
*/
L
ljc545w 已提交
16 17 18 19 20 21 22 23 24 25
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 已提交
26 27 28 29
/*
* 供外部调用的获取数据库信息接口
* return:DWORD,`dbs`首个成员地址
*/
L
ljc545w 已提交
30 31 32 33 34 35
DWORD GetDbHandlesRemote() {
	if (dbs.size() == 0)
		GetDbHandles();
	return (DWORD)dbs.data() ;
}

L
ljc545w 已提交
36 37 38 39
/*
* 获取数据库信息的具体实现
* return:void
*/
L
ljc545w 已提交
40 41 42
void GetDbHandles() {
	dbs.clear();
	DWORD WeChatWinBase = GetWeChatWinBase();
L
ljc545w 已提交
43
	DWORD SqlHandleBaseAddr = WeChatWinBase + SqlHandleMicroMsgOffset;
L
ljc545w 已提交
44 45
	DWORD SqlHandleBeginAddr = 0x0;
	DWORD SqlHandleEndAddr = 0x0;
L
ljc545w 已提交
46
	DWORD SqlHandlePublicMsgAddr = *(DWORD*)(WeChatWinBase + SqlHandlePublicMsgOffset);
L
ljc545w 已提交
47 48 49
	__asm {
		mov eax, [SqlHandleBaseAddr];
		mov ecx, [eax];
L
ljc545w 已提交
50
		add ecx, 0x1428;
L
ljc545w 已提交
51 52 53 54 55
		mov eax, [ecx];
		mov SqlHandleBeginAddr, eax;
		mov eax, [ecx + 0x4];
		mov SqlHandleEndAddr, eax;
	}
L
ljc545w 已提交
56
	DWORD dwHandle = 0x0;
L
ljc545w 已提交
57 58
	wstring dbnames = L"";
	while (SqlHandleBeginAddr < SqlHandleEndAddr) {
L
ljc545w 已提交
59
		dwHandle = *(DWORD*)SqlHandleBeginAddr;
L
ljc545w 已提交
60 61 62
		SqlHandleBeginAddr += 0x4;
		if (SqlHandleBeginAddr == SqlHandleEndAddr)
			break;
L
ljc545w 已提交
63
		if(dbnames.find((wchar_t*)(*(DWORD*)(dwHandle + 0x50)),0) != wstring::npos)
L
ljc545w 已提交
64 65
			continue;
		DbInfoStruct db = { 0 };
L
ljc545w 已提交
66 67
		dbnames += (wchar_t*)(*(DWORD*)(dwHandle + 0x50));
		db.dbname = (wchar_t*)(*(DWORD*)(dwHandle + 0x50));
L
ljc545w 已提交
68
		db.l_dbname = wcslen(db.dbname);
L
ljc545w 已提交
69 70
		db.handle = *(DWORD*)(dwHandle + 0x3C);
		ExecuteSQL(*(DWORD*)(dwHandle + 0x3C), "select * from sqlite_master where type=\"table\";",(DWORD)GetDbInfo,&db);
L
ljc545w 已提交
71 72
		dbs.push_back(db);
	}
L
ljc545w 已提交
73 74
	for (int i = 1; i < 4; i++) {
		dwHandle = *((DWORD*)(SqlHandlePublicMsgAddr + i * 0x4));
L
ljc545w 已提交
75
		if (dbnames.find((wchar_t*)(*(DWORD*)(dwHandle + 0x50)), 0) != wstring::npos)
L
ljc545w 已提交
76 77
			continue;
		DbInfoStruct db = { 0 };
L
ljc545w 已提交
78 79
		dbnames += (wchar_t*)(*(DWORD*)(dwHandle + 0x50));
		db.dbname = (wchar_t*)(*(DWORD*)(dwHandle + 0x50));
L
ljc545w 已提交
80
		db.l_dbname = wcslen(db.dbname);
L
ljc545w 已提交
81 82
		db.handle = *(DWORD*)(dwHandle + 0x3C);
		ExecuteSQL(*(DWORD*)(dwHandle + 0x3C), "select * from sqlite_master where type=\"table\";", (DWORD)GetDbInfo, &db);
L
ljc545w 已提交
83 84
		dbs.push_back(db);
	}
L
ljc545w 已提交
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
	// 添加一个空结构体,作为读取结束标志
	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
}