PyWxDump技术博客:核心功能实现细节
引言:数据处理的技术挑战
在数字化时代,即时通讯工具已成为个人数据的重要载体。PyWxDump作为一款专业的数据处理工具,能够突破客户端的数据加密限制,实现账号信息提取、数据库解密、记录导出等核心功能。本文将深入剖析PyWxDump的技术架构与实现细节,揭示其如何应对不断升级的安全机制,为开发者提供一份全面的技术参考。
一、信息获取机制
1.1 内存数据定位技术
PyWxDump通过进程内存分析实现关键信息提取,核心实现位于wx_info.py。其创新点在于采用动态基址计算方法,解决不同版本的内存布局差异:
# 动态计算基址偏移(wx_info.py片段)
def get_info_details(pid, WX_OFFS: dict = None):
wechat_base_address = 0
memory_maps = get_memory_maps(pid)
for module in memory_maps:
if module.FileName and 'WeChatWin.dll' in module.FileName:
wechat_base_address = module.BaseAddress # 获取模块基地址
break
# 版本化偏移计算
name_baseaddr = wechat_base_address + bias_list[0]
account_baseaddr = wechat_base_address + bias_list[1]
# ...其他信息地址计算
技术亮点:
- 通过
get_memory_maps遍历进程内存区域,精确定位WeChatWin.dll模块 - 结合版本偏移表
WX_OFFS.json,实现跨版本兼容 - 使用
ReadProcessMemory读取进程内存,规避客户端的内存保护机制
1.2 多维度信息提取流程
信息获取流程采用分层提取策略,确保在不同环境下的稳定性:
关键函数调用链:
get_wx_info:统筹信息提取流程get_key_by_offs:通过偏移获取密钥get_wx_dir_by_reg:从注册表获取安装路径verify_key:验证密钥有效性(基于HMAC-SHA1校验)
二、数据库解密核心实现
2.1 AES-CBC解密算法
数据库采用AES-256-CBC加密模式,PyWxDump在decryption.py中实现了完整的解密流程:
# 数据库解密核心实现(decryption.py片段)
def decrypt(key: str, db_path: str, out_path: str):
password = bytes.fromhex(key.strip())
with open(db_path, "rb") as file:
blist = file.read()
salt = blist[:16] # 盐值
first_block = blist[16:4096] # 第一块数据
# 密钥派生
byteHmac = hashlib.pbkdf2_hmac("sha1", password, salt, 64000, KEY_SIZE)
mac_key = hashlib.pbkdf2_hmac("sha1", byteHmac, mac_salt, 2, KEY_SIZE)
# HMAC验证
hash_mac = hmac.new(mac_key, first_block[:-32], hashlib.sha1)
hash_mac.update(b'\x01\x00\x00\x00')
if hash_mac.digest() != first_block[-32:-12]:
return False, "Key Error"
# 分块解密
for i in range(0, len(blist), 4096):
block = blist[i:i+4096] if i>0 else blist[16:i+4096]
iv = block[-48:-32] # 初始化向量
cipher = AES.new(byteHmac, AES.MODE_CBC, iv)
decrypted_block = cipher.decrypt(block[:-48])
# ...写入解密后数据
数据块结构解析:
| 部分 | 长度 | 说明 |
|---|---|---|
| 盐值 | 16字节 | 用于密钥派生 |
| 加密数据 | 4032字节 | 实际加密内容 |
| IV | 16字节 | CBC模式初始化向量 |
| HMAC | 20字节 | 消息认证码 |
| 填充 | 12字节 | 对齐填充 |
2.2 批量解密与性能优化
batch_decrypt函数实现多文件并行解密,采用目录递归遍历和进度反馈机制:
def batch_decrypt(key: str, db_path: Union[str, List[str]], out_path: str, is_print: bool = False):
# 路径处理逻辑
if isinstance(db_path, str):
if os.path.isdir(db_path):
for root, _, files in os.walk(db_path):
for file in files:
if file.endswith(".db"):
process_list.append(...) # 添加任务
# ...解密任务分发
# 结果统计
success_count = sum(1 for code, _ in result if code)
fail_count = len(result) - success_count
优化策略:
- 采用相对路径保持目录结构
- 错误捕获与重试机制
- 解密后自动清理空文件夹
三、内存搜索与基址定位
3.1 特征码扫描技术
memory_search.py实现了高效的内存特征码扫描,用于定位关键数据结构:
def search_memory(hProcess, pattern=br'\\Msg\\FTSContact', max_num=100):
mbi = MEMORY_BASIC_INFORMATION()
address = 0x0
result = []
while address < 0x7FFFFFFFFFFFFFFF:
VirtualQueryEx(hProcess, address, ctypes.byref(mbi), ctypes.sizeof(mbi))
# 过滤可访问内存页
if mbi.State == MEM_COMMIT and mbi.Protect in [PAGE_READWRITE, PAGE_EXECUTE_READ]:
buffer = ctypes.create_string_buffer(mbi.RegionSize)
ReadProcessMemory(hProcess, mbi.BaseAddress, buffer, mbi.RegionSize, None)
# 正则匹配特征码
matches = re.finditer(pattern, buffer.raw, re.DOTALL)
result.extend([mbi.BaseAddress + m.start() for m in matches])
address += mbi.RegionSize
关键优化:
- 内存页类型过滤,只扫描可读写区域
- 正则表达式预编译,提升匹配效率
- 大内存块分块处理,避免内存溢出
3.2 版本适配机制
BiasAddr类(get_bias_addr.py)实现版本偏移自动适配:
class BiasAddr:
def __init__(self, account, mobile, name, key, db_path):
self.version = get_exe_version(self.exe_path)
# 根据版本选择不同搜索策略
version_nums = list(map(int, self.version.split(".")))
if version_nums[0] <= 3 and version_nums[1] <= 9:
self.address_len = 4 # 32位版本
else:
self.address_len = 8 # 64位版本
def get_key_bias2(self, wx_db_path):
# 多策略密钥偏移搜索
key_bias = self.get_key_bias1() # 基础策略
if key_bias <= 0 and self.key:
key_bias = self.search_key(self.key) # 密钥搜索策略
if key_bias <= 0 and self.db_path:
key_bias = self.get_key_bias2(self.db_path) # 数据库辅助策略
四、数据库操作与合并
4.1 数据库连接池设计
dbbase.py实现了基于dbutils.pooled_db的连接池管理:
class DatabaseBase:
_db_pool = {} # 连接池缓存
@classmethod
def connect(cls, db_config):
db_key = db_config.get("key")
if db_key in cls._db_pool:
return cls._db_pool[db_key]
# 创建SQLite连接池
pool = PooledDB(
creator=sqlite3,
maxconnections=0, # 无限制连接
mincached=4, # 初始空闲连接
blocking=True # 连接耗尽时阻塞等待
)
cls._db_pool[db_key] = pool
return pool
连接池优势:
- 减少频繁连接创建开销
- 资源复用,提升并发性能
- 支持多数据库类型(SQLite/MySQL)
4.2 多数据库合并算法
merge_db.py实现跨数据库合并,核心在于表结构对齐和重复数据处理:
def merge_db(db_paths: List[dict], save_path: str = "merge.db"):
outdb = sqlite3.connect(save_path)
out_cursor = outdb.cursor()
for alias, db in databases.items():
# 附加数据库
out_cursor.execute(f"ATTACH DATABASE '{de_path}' AS {alias}")
# 获取表结构
tables = execute_sql(outdb, f"SELECT tbl_name, sql FROM {alias}.sqlite_master")
for table, create_sql in tables:
# 创建目标表
out_cursor.execute(f"CREATE TABLE IF NOT EXISTS {table} AS SELECT * FROM {alias}.{table} WHERE 0=1")
# 创建唯一索引去重
columns = get_table_columns(outdb, table)
index_sql = f"CREATE UNIQUE INDEX {table}_idx ON {table} ({','.join(columns)})"
out_cursor.execute(index_sql)
# 数据插入(忽略重复)
out_cursor.execute(f"INSERT OR IGNORE INTO {table} SELECT * FROM {alias}.{table}")
合并流程采用附加数据库模式,避免大量数据复制,通过唯一索引确保数据一致性。
五、记录导出实现
5.1 HTML导出流程
exportHtml.py将记录转换为HTML格式,关键在于数据序列化和前端渲染:
def export_html(wxid, outpath, db_config, my_wxid="我"):
db = DBHandler(db_config, my_wxid)
msgs, users = db.get_msgs(wxid) # 获取记录
# 生成前端数据
data_js = f"""
const local_mywxid = '{my_wxid}';
const local_user_list = {json.dumps(users)};
const local_msg_list = {json.dumps(msgs)};
"""
with open(os.path.join(outpath, "data.js"), "w") as f:
f.write(data_js)
导出内容:
- 用户信息列表(头像、昵称映射)
- 消息列表(时间、发送者、内容、附件)
- 媒体文件引用(图片/语音路径)
5.2 实时消息处理
test_real_time_msg.py展示实时消息监听实现,通过内存变更检测和实时解密:
def all_merge_real_time_db(key, wx_path, merge_path: str):
# 实时数据库监听
cmd = f'{real_time_exe_path} "{key}" "{merge_path}" "{endbs}"'
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
out, err = p.communicate()
if "SUCCESS" in out.decode():
return True, merge_path
实时处理挑战:
- 内存数据实时捕获
- 加密数据流解密延迟
- 多版本协议兼容性
六、命令行接口设计
cli.py实现丰富的命令行功能,采用子命令架构提升可用性:
class MainDecrypt(BaseSubMainClass):
mode = "decrypt"
parser_kwargs = {"help": "解密数据库"}
def init_parses(self, parser):
parser.add_argument("-k", "--key", required=True, help="密钥")
parser.add_argument("-i", "--db_path", required=True, help="数据库路径")
parser.add_argument("-o", "--out_path", default="decrypted", help="输出路径")
def run(self, args):
result = batch_decrypt(args.key, args.db_path, args.out_path)
核心命令:
info:获取账号信息decrypt:解密数据库merge:合并多个数据库export:导出记录ui:启动图形界面
总结与展望
PyWxDump通过内存分析、密码学解密、数据库操作三大核心技术,实现了对数据的全面处理。其架构设计注重跨版本兼容性和性能优化,在实际应用中展现了强大的数据提取能力。
未来优化方向:
- 基于机器学习的版本偏移自动推导
- GPU加速大规模数据库解密
- 多平台支持(Linux/macOS)
- 实时消息流处理优化
PyWxDump不仅为开发者提供了数据处理的技术参考,也为即时通讯数据分析领域提供了新思路。项目代码已开源,欢迎社区贡献更多特性与优化。
通过本文的技术解析,相信读者对PyWxDump的实现细节有了深入理解。项目持续维护中,更多技术细节请参考官方代码仓库。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



