最近作者心血来潮弄了一下微信数据库。看到很多。
MSG.db 是存储聊天消息记录
MicroMsg.db 存储好友信息、群组、小程序等信息。
MediaMsg.db 主要存储语音数据
Misc.db 存储头像信息
本想着对数据库备份(不在加密)进行实现的,有个没法解决的问题---release win32的工程运行不了 报0xc7b错误 。折腾好久,没解决,凑合着用x64的。
多的不说了,一些简单的sql操作 具体能做什么,在图片里
主目录
#include"operateDB.h"
#ifndef SQLITE3_H
#define SQLITE3_H
#endif
#define SQLITE_CODE 1
int main()
{
//sqlite3* db = NULL;
//int rc = create(&db);
printf("当前 sqlite 使用的版本%s\n",sqlite3_libversion());
char c_path[MAX_PATH];
printf("注意!!!! 要将DB文件和程序置于同一目录之下 \n !!!!只针对contact 数据库查询其他库无效 \n");
printf("请输入解密之后的数据库名:\n");
scanf_s("%s",&c_path);
printf("%s\n", c_path);
//readDB("SELECT UserName,NickName from Contact where UserName like '%@chatroom'and Type=2;", c_path);
menu();
int num = 0;
while (1)
{
scanf_s("%d", &num);
switch (num)
{
//所有好友信息 wxid 账号 名称
case 1:
readDB("SELECT UserName,Alias,NickName from Contact where UserName like 'wxid%' and Type =3;", c_path);
break;
case 2:
//查看被删除
readDB("SELECT UserName,Alias,NickName from Contact where UserName like 'wxid%' and Type =259;", c_path);
break;
case 3: //公众号
readDB("SELECT UserName,NickName from Contact where UserName like 'gh_%' and VerifyFlag=8;", c_path);
break;
case 4: //所有聊天室成员账号
readDB("SELECT UserName,NickName from Contact where UserName like 'wxid%' and Type=4;", c_path);
break;
case 5:
//查询加入的聊天室
readDB("SELECT UserName,NickName from Contact where UserName like '%@chatroom'and Type=2;", c_path);
break;
default:
printf("你输入的数字不合理\n");
break;
}
menu();
}
return 0;
}
功能函数模块头文件
#include<iostream>
#include<Windows.h>
#include<atlstr.h>
#include<sqlite3.h>
//菜单
void menu();
//回调函数
int callback(void* data, int argc, char** argv, char** azColName);
//读取数据库的函数
void readVXDb(const char * sql);
//utf-8 转为 unicode
char * utf2Unicode(char * utf8);
//unicode 转为 utf-8
char *unicode2Utf8( wchar_t * unicode);
//读取数据库
void readDB(const char * sql, char * path);
//所有好友信息 wxid 账号 名称
#define friendSql "SELECT UserName,Alias,NickName from Contact where UserName like 'wxid%' and Type =3;";
//查看被删除的sql
#define delFriendSql "SELECT UserName,Alias,NickName from Contact where UserName like 'wxid%' and Type =259;";
//公众号
#define publicAccountSql "SELECT UserName,Alias,NickName from Contact where UserName like 'gh_%' and VerifyFlag=8;";
//所有聊天室成员账号 不能获取到 微信账号
#define chartRoomMemberSql "SELECT UserName,NickName from Contact where UserName like 'wxid%' and Type=4;";
//查询加入的聊天室
#define chartRoomSql "SELECT UserName,NickName from Contact where UserName like '%@chatroom'and Type=2;";
功能函数实现的的cpp文件
#include"operateDB.h"
//参数解释
//每查到一条数据则调用一次
/*
第一个参数是来自sqlite3_exec()函数中的第四个参数
第二个参数是查询到的列数
第三个参数是表示每一行中那一列的一个值
第四个参数 表示列名
例如 查询出的结果是这样
*/
int count = 0;
void menu()
{
printf("\n请输入数字将进行你想要的操作:\n");
printf("1 显示好友信息 \t 2 查看被删除\n");
printf("3 公众号 \t 4 所有聊天室成员账号\n");
printf("5 查询加入的聊天室\n");
}
int callback(void* data, int argc, char** argv, char** azColName)
{
int i ;
//fprintf(stderr, "%s:", (const char *)data);
//int count = *((int *)data);
//printf("count %d",count);
//打印表头
if (count == 0)
{
for (int j = 0; j < argc; j++)
{
printf("%s\t\t", azColName[j]);
}
//表头打印完以后换行
printf("\n");
}
/*count++;*/
count++;
for (i = 0; i < argc; i++)
{
//utf2Unicode(argv[i]);
//有值就输出转化之后的
printf("%s \t", argv[i] ? utf2Unicode(argv[i]) : " | \t\t \t");
//printf("%s\n", argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
void readVXDb(const char * sql ){
count = 0;
//做sql语句为空处理
if (sql == nullptr)
{
return;
}
sqlite3 *db = NULL;
const char * path = "dec_MicroMsg.db"; //dec_MicroMsg.db
//sqlite3_open
//打开数据库
int res = sqlite3_open(path, &db);
const char * data = "回调函数回调成功";
//int* count = 0;
char *errMsg;
if (res == SQLITE_OK)
{
printf("数据打开成功 %d \n进行数据库查询操作:\n", res);
}
else
{
fprintf(stderr, "数据库打开失败%s", sqlite3_errmsg);
return;
}
//执行sql语句select * from Contact
//const char* sql = "SELECT UserName,NickName from Contact where UserName like '%@chatroom'and Type=2;";
res = sqlite3_exec(db, sql, callback, (void *)count, &errMsg);
printf("sql 语句执行后的结果%d\n 共有%d条数据", res,count);
if (res != SQLITE_OK)
{
fprintf(stderr, "sql error %s\n", errMsg);
sqlite3_free(errMsg);
}
//关闭句柄
sqlite3_close(db);
}
//utf-8 转为 unicode
char * utf2Unicode( char * utf8)
{
//与转换 得到所需空间大小
int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, utf8, (int)strlen(utf8), NULL, 0);
//分配空间给'\0'留个位置,MuliByteToWideChar 不会给'\0'预留
wchar_t * wszString = new wchar_t[wcsLen + 1];
//转化
::MultiByteToWideChar(CP_UTF8, NULL, utf8, (int)strlen(utf8), wszString, wcsLen);
//最后加上
wszString[wcsLen]='\0';
char * m_char;
int len = WideCharToMultiByte(CP_ACP, 0, wszString, (int)wcslen(wszString), NULL, 0, NULL, NULL);
m_char = new char[len + 1];
WideCharToMultiByte(CP_ACP, 0, wszString, (int)wcslen(wszString), m_char, len, NULL, NULL);
m_char[len] = '\0';
return m_char;
}
//unicode 转为 utf-8
char *unicode2Utf8( wchar_t * unicode)
{
// unicode to UTF8
//预转换,得到所需空间的大小,这次用的函数和上面名字相反
int u8Len = ::WideCharToMultiByte(CP_UTF8, NULL, unicode, (int)wcslen(unicode), NULL, 0, NULL, NULL);
//同上,分配空间要给'\0'留个空间
//UTF8虽然是Unicode的压缩形式,但也是多字节字符串,所以可以以char的形式保存
char* szU8 = new char[u8Len + 1];
//转换
//unicode版对应的strlen是wcslen
::WideCharToMultiByte(CP_UTF8, NULL, unicode, (int)wcslen(unicode), szU8, u8Len, NULL, NULL);
//最后加上'\0'
szU8[u8Len] = '\0';
return szU8;
}
void readDB(const char * sql, char * path)
{
count = 0;
//做sql语句为空处理
if (sql == nullptr)
{
return;
}
sqlite3 *db = NULL;
//const char * path = "dec_MicroMsg.db"; //dec_MicroMsg.db
//sqlite3_open
//打开数据库
int res = sqlite3_open(path, &db);
const char * data = "回调函数回调成功";
//int* count = 0;
char *errMsg;
if (res == SQLITE_OK)
{
printf("数据打开成功 %d \n进行数据库查询操作:\n", res);
}
else
{
fprintf(stderr, "数据库打开失败%s", sqlite3_errmsg);
return;
}
//执行sql语句select * from Contact
//const char* sql = "SELECT UserName,NickName from Contact where UserName like '%@chatroom'and Type=2;";
res = sqlite3_exec(db, sql, callback, (void *)count, &errMsg);
printf("sql 语句执行后的结果%d\n 共有%d条数据", res, count);
if (res != SQLITE_OK)
{
fprintf(stderr, "sql error %s\n", errMsg);
sqlite3_free(errMsg);
}
//关闭句柄
sqlite3_close(db);
}
评论列表(3条)
怎么解密呢
如何解密数据库呢
怎一个6字了得