本次提交包含多项核心更新: 1. 新增微信4.0浅色主题UI模板资源与说明文档,补充了联系人图标、新的朋友入口等四个UI元素的图像匹配模板 2. 重构UI驱动层,将原2375行的单文件拆分为5个职责清晰的子驱动类,提升代码可维护性 3. 新增批量群发消息与聊天记录导出的完整数据模型、路由与后台协程,支持幂等校验与风控配置 4. 为所有业务接口新增post_verify校验逻辑,补充了verified字段返回操作结果 5. 优化媒体文件解密逻辑,修复了导出功能中的数据库错误处理与分辨率硬编码问题 6. 更新版本配置,将媒体发送功能标记为已落地,调整了能力列表与配置项
68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
"""微信 4.x .dat 文件 XOR 解密逻辑的单测。
|
||
|
||
覆盖 DbReader._decrypt_dat 的三个最小用例:
|
||
- PNG(key=0x3A)
|
||
- JPEG(key=0xE5)
|
||
- 纯文本(key=0x00,无法推导时回退原密文)
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import os
|
||
import sys
|
||
|
||
# 将 bridge/ 目录加入 sys.path,使 woc_bridge 包可被导入
|
||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
||
|
||
from woc_bridge.db.reader import DbReader
|
||
|
||
|
||
def _xor(data: bytes, key: int) -> bytes:
|
||
"""对 data 逐字节异或 key,构造密文。"""
|
||
return bytes(b ^ key for b in data)
|
||
|
||
|
||
def test_png_key_0x3a():
|
||
"""PNG magic 0x89 50 4E 47 ... XOR 0x3A,解密后首字节应为 0x89。"""
|
||
plaintext = b"\x89PNG\r\n\x1a\n" + b"\x00" * 16
|
||
ciphertext = _xor(plaintext, 0x3A)
|
||
|
||
result = DbReader._decrypt_dat(ciphertext)
|
||
|
||
assert result is not None, "PNG 密文应能推导出 key"
|
||
decrypted, mime = result
|
||
assert decrypted[0] == 0x89
|
||
assert decrypted == plaintext
|
||
assert mime == "image/png"
|
||
|
||
|
||
def test_jpeg_key_0xe5():
|
||
"""JPEG magic 0xFF D8 FF E0 XOR 0xE5,解密后首字节应为 0xFF。"""
|
||
plaintext = b"\xff\xd8\xff\xe0" + b"\x00" * 16
|
||
ciphertext = _xor(plaintext, 0xE5)
|
||
|
||
result = DbReader._decrypt_dat(ciphertext)
|
||
|
||
assert result is not None, "JPEG 密文应能推导出 key"
|
||
decrypted, mime = result
|
||
assert decrypted[0] == 0xFF
|
||
assert decrypted == plaintext
|
||
assert mime == "image/jpeg"
|
||
|
||
|
||
def test_plaintext_key_0x00_fallback():
|
||
"""纯文本 'Hello' XOR 0x00(即原文),无 magic 命中应回退原密文。
|
||
|
||
key=0x00 时密文即原文 'Hello',其首字节 0x48 不属于任何图片 magic,
|
||
故 _decrypt_dat 返回 None,由调用方回退原密文返回。
|
||
"""
|
||
plaintext = b"Hello"
|
||
ciphertext = _xor(plaintext, 0x00) # 等于原文
|
||
|
||
result = DbReader._decrypt_dat(ciphertext)
|
||
|
||
# 推导失败 → 返回 None(调用方据此回退原密文)
|
||
assert result is None, "纯文本无 magic 命中应返回 None 触发回退"
|
||
# 回退路径下,调用方返回的密文应与原文一致
|
||
assert ciphertext == plaintext
|