1 Star 0 Fork 9

党凯/WeChatDecodeDB

forked from Ben/WeChatDecodeDB 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
wechat_db.py 2.96 KB
一键复制 编辑 原始数据 按行查看 历史
Ben 提交于 2024-01-11 19:54 . 最新支持微信版本3.9.8.25
from ctypes.wintypes import MAX_PATH
import os
import winreg
import hmac
import ctypes
import hashlib
from Crypto.Cipher import AES
class WechatDB:
def __init__(self, aes_key):
self.aes_key = bytes.fromhex(aes_key)
self.save_path_directory = os.path.join(os.getcwd(), "wechat_db")
if not os.path.exists(self.save_path_directory):
os.makedirs(self.save_path_directory)
def get_wechat_user_directory(self) -> str:
"""
获取微信用户数据库保存文件目录
"""
try:
path = r"Software\Tencent\WeChat"
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, path) as registry_key:
# 读取注册表项中的值
value, _ = winreg.QueryValueEx(registry_key, "FileSavePath")
if value == "MyDocument:":
dll = ctypes.windll.shell32
buf = ctypes.create_unicode_buffer(MAX_PATH + 1)
if dll.SHGetSpecialFolderPathW(None, buf, 0x0005, False):
return os.path.join(buf.value, "WeChat Files")
else:
raise Exception("未找到微信用户数据路径,请确保电脑上安装了微信")
return value
except FileNotFoundError:
raise Exception("未找到微信用户数据路径,请确保电脑上安装了微信")
def decrypt_db(self, path):
KEY_SIZE = 32
DEFAULT_ITER = 64000
DEFAULT_PAGESIZE = 4096 # 4048数据 + 16IV + 20 HMAC + 12
SQLITE_FILE_HEADER = bytes("SQLite format 3", encoding="ASCII") + bytes(
1
) # SQLite 文件头
with open(path, "rb") as f:
# TODO: 优化,考虑超大文件
blist = f.read()
salt = blist[:16] # 前16字节为盐
key = hashlib.pbkdf2_hmac(
"sha1", self.aes_key, salt, DEFAULT_ITER, KEY_SIZE
) # 获得Key
page1 = blist[16:DEFAULT_PAGESIZE] # 丢掉salt
mac_salt = bytes([x ^ 0x3A for x in salt])
mac_key = hashlib.pbkdf2_hmac("sha1", key, mac_salt, 2, KEY_SIZE)
hash_mac = hmac.new(mac_key, digestmod="sha1")
hash_mac.update(page1[:-32])
hash_mac.update(bytes(ctypes.c_int(1)))
if hash_mac.digest() != page1[-32:-12]:
raise RuntimeError("密码错误!")
pages = [
blist[i : i + DEFAULT_PAGESIZE]
for i in range(DEFAULT_PAGESIZE, len(blist), DEFAULT_PAGESIZE)
]
pages.insert(0, page1) # 把第一页补上
return SQLITE_FILE_HEADER, key, pages
def save_db(self, header, key, pages, path):
with open(path, "wb") as f:
f.write(header) # 写入文件头
for i in pages:
t = AES.new(key, AES.MODE_CBC, i[-48:-32])
f.write(t.decrypt(i[:-48]))
f.write(i[-48:])
if __name__ == "__main__":
wxdb = WechatDB("")
print(wxdb.get_wechat_user_directory())
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/dangkai/we-chat-decode-db.git
git@gitee.com:dangkai/we-chat-decode-db.git
dangkai
we-chat-decode-db
WeChatDecodeDB
master

搜索帮助