-
-
[原创]1.企业微信数据库解密
-
发表于: 2025-11-28 22:25 7451
-
基本信息介绍:
企业微信所使用的数据库的WCDB,基本介绍自己AI
简单讲讲sqlite3,sqlCipher,WCDB三者的关系:

目前pc端使用的是C++,也就是类似于SQLCipher,而且是内联,将sqlite3.dll内联进去主程序中,会导致很多sql的函数都需要你通过特征码去定位,当然你可以自己编译出合理的dll,注入进行调用
数据库存储位置:
C:\Users\Administrator\Documents\WXWork\<账号id>
主要关注的数据库db:C:\Users\Administrator\Documents\WXWork\<账号id>\Data
里面主要有:
user.db:主要关注user_table(员工,客户), external_user_relation_v3(外部客户)

message.db:主要关注message_table(消息),

company.db:

session.db: conversation_table(群聊,私聊等), conversation_user_table(群成员)

关键sql函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | //AI写的代码#include <stdio.h>#include <Windows.h>#include "sqlite3.h"#include <time.h>int main() { printf("SQLite版本: %s\n", sqlite3_libversion()); sqlite3* db; int rc = sqlite3_open("message.db", &db); // 创建物理数据库文件// sqlcipher需要设置加密密钥// const char* key = "CreateSun";// rc = sqlite3_key(db, key, strlen(key)); if (rc != SQLITE_OK) { printf("打开数据库失败: %s\n", sqlite3_errmsg(db)); return 1; } printf("成功打开数据库\n"); // 创建消息表 const char* create_table_sql = "CREATE TABLE IF NOT EXISTS message_table (" "message_id INTEGER PRIMARY KEY AUTOINCREMENT," "server_id INTEGER DEFAULT 0 NOT NULL," "sequence INTEGER DEFAULT 0 NOT NULL," "sender_id INTEGER DEFAULT 0 NOT NULL," "conversation_id TEXT DEFAULT '' NOT NULL," "content_type INTEGER DEFAULT 0 NOT NULL," "send_time INTEGER DEFAULT 0 NOT NULL," "flag INTEGER DEFAULT 0 NOT NULL," "content TEXT," "devinfo INTEGER DEFAULT 0 NOT NULL," "from_app_id TEXT DEFAULT '' NOT NULL," "msg_from_devinfo INTEGER DEFAULT 0 NOT NULL," "extra_content TEXT," "local_extra_content TEXT," "client_id TEXT DEFAULT ''," "local_extra_content_translate_info TEXT," "local_extra_content_time_nlp TEXT," "local_extra_content_approval_nlp TEXT);"; char* err_msg = 0; rc = sqlite3_exec(db, create_table_sql, 0, 0, &err_msg); if (rc != SQLITE_OK) { printf("创建表失败: %s\n", err_msg); sqlite3_free(err_msg); } else { printf("消息表创建成功\n"); } // 插入几条聊天记录 time_t now = time(0); const char* insert_sql[] = { "INSERT INTO message_table (server_id, sequence, sender_id, conversation_id, " "content_type, send_time, flag, content, devinfo, from_app_id, msg_from_devinfo) " "VALUES (1001, 1, 10001, 'C_GROUP_123', 1, %ld, 0, " "'CreateSun是最聪明的人!!!!!!!!!!!!!!!!!', 0, 'com.example.app', 0);", "INSERT INTO message_table (server_id, sequence, sender_id, conversation_id, " "content_type, send_time, flag, content, devinfo, from_app_id, msg_from_devinfo) " "VALUES (1001, 2, 10002, 'C_GROUP_123', 1, %ld, 0, " "'我也同意,CreateSun太厉害了!', 0, 'com.example.app', 0);", "INSERT INTO message_table (server_id, sequence, sender_id, conversation_id, " "content_type, send_time, flag, content, devinfo, from_app_id, msg_from_devinfo) " "VALUES (1001, 3, 10003, 'C_GROUP_123', 1, %ld, 0, " "'向CreateSun学习编程技巧', 0, 'com.example.app', 0);" }; char sql_buffer[1024]; for (int i = 0; i < 3; i++) { snprintf(sql_buffer, sizeof(sql_buffer), insert_sql[i], now + i); rc = sqlite3_exec(db, sql_buffer, 0, 0, &err_msg); if (rc != SQLITE_OK) { printf("插入记录失败: %s\n", err_msg); sqlite3_free(err_msg); } else { printf("成功插入记录 %d\n", i+1); } } // 查询并打印所有记录 printf("\n数据库中的消息记录:\n"); const char* select_sql = "SELECT message_id, sender_id, content FROM message_table;"; sqlite3_stmt *stmt; rc = sqlite3_prepare_v2(db, select_sql, -1, &stmt, 0); if (rc != SQLITE_OK) { printf("查询准备失败: %s\n", sqlite3_errmsg(db)); } else { while (sqlite3_step(stmt) == SQLITE_ROW) { int mid = sqlite3_column_int(stmt, 0); int sid = sqlite3_column_int(stmt, 1); const char* content = (const char*)sqlite3_column_text(stmt, 2); printf("[消息ID:%d] [发送者:%d] 内容: %s\n", mid, sid, content); } sqlite3_finalize(stmt); } sqlite3_close(db); printf("\n数据库操作完成,数据已保存到 message.db 文件\n"); system("pause"); return 0;} |
主要的几个关键函数:
sqlite3_open:打开数据库
sqlite3_exec:执行sql
sqlite3_prepare_v2:相当于预编译,重复执行
sqlite3_step:执行sqlite3_stmt*,里面包含sqlite*句柄及其sql
两种解密企业微信数据库的方法
- 使用加密数据库的key直接进行解密
找到这个函数的特征码:sqlite3_key,将其进行hook获取密钥
企业微信的密钥是由一个总key,根据数据库db文件等的不同派发出不同的分key
也就是每个db文件的key都是不一样的,不同电脑的同一个账号也是不一样的 - Hook获取sql句柄,执行解密sql进行解密
Hook函数:sqlite3_step,sqlite3_prepare_v2,sqlite3_exec等基本上就可以获取所有的数据库句柄
sqlite3_db_filename:通过句柄获取数据库的路径
1 2 3 | //使用这写sql可以清除sqlcipher的密码const char* sql_SetKeyNull = "PRAGMA rekey = '';";const char* sql_SaveDB = "PRAGMA wal_checkpoint(FULL);"; |
你甚至可以设置一个回调函数,写入一条数据,执行一次回调导出数据
找特征码可以通过下载DB Browser for SQLite.exe,DB Browser for SQLCipher.exe着两个软件,里面包含两个dll,自己通过IDA去找特征码定位
咨询一次888(开玩笑):

鹅群:749050322
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
赞赏
- [原创]CRC32补丁算法 1593
- [原创]注册机-2016腾讯游戏安全大赛-pc-第一轮 1170
- [原创]进程多开检测-2016腾讯游戏安全大赛-PC-第二轮-第一题 1291
- [原创]2.企业微信收消息 2021
- [原创]1.企业微信数据库解密 7451