解决相对导入包的问题,完善错误提示

This commit is contained in:
xaoyo 2023-11-27 10:12:12 +08:00
parent c61618aadd
commit 03b694e1da
6 changed files with 60 additions and 14 deletions

View File

@ -16,6 +16,7 @@
<details>
<summary><strong>更新日志(点击展开)</strong></summary>
* 2023.11.27 解决相对导入包的问题,完善错误提示
* 2023.11.25 聊天记录查看工具bootstrap更换国内cdn
* 2023.11.22 添加all命令中解密错误数据日志写入文件,修复部分bug
* 2023.11.16 增加聊天记录导出为html
@ -160,13 +161,13 @@ PyWxDump
## 1. 安装
### 1.1 从pypi安装
### 1.1 从pypi安装(安装稳定版)
```shell script
pip install pywxdump
```
### 1.2 从源码安装
### 1.2 从源码安装(安装最新版)
<details>
<summary>点击展开</summary>

View File

@ -11,6 +11,8 @@ from .wx_info.get_wx_db import get_wechat_db
from .decrypted.decrypt import batch_decrypt, decrypt
from .decrypted.get_wx_decrypted_db import all_decrypt, merge_copy_msg_db, merge_msg_db, merge_media_msg_db
from .analyse.parse import read_img_dat, read_emoji, decompress_CompressContent, read_audio_buf, read_audio, parse_xml_string
from .show_chat import app_show_chat, get_user_list, export
import os,json
VERSION_LIST_PATH = os.path.join(os.path.dirname(__file__), "version_list.json")

View File

@ -10,7 +10,7 @@ import importlib.metadata
import sys
import textwrap
from . import *
from pywxdump import *
# version_list_path = os.path.join(os.path.dirname(__file__), "version_list.json")
@ -142,7 +142,6 @@ class MainShowChatRecords():
try:
from flask import Flask, request, jsonify, render_template, g
import logging
from .show_chat.main_window import app_show_chat, get_user_list
except Exception as e:
print(e)
print("[-] 请安装flask( pip install flask )")
@ -177,7 +176,7 @@ class MainExportChatRecords():
self.mode = "export"
# 添加 'decrypt' 子命令解析器
sb_decrypt = parser.add_parser(self.mode, help="聊天记录导出为html[需要安装flask]")
sb_decrypt.add_argument("-u", "--username", type=str, help="微信账号", required=True, metavar="")
sb_decrypt.add_argument("-u", "--username", type=str, help="微信账号(聊天对象账号)", required=True, metavar="")
sb_decrypt.add_argument("-o", "--outpath", type=str, help="导出路径", required=True, metavar="")
sb_decrypt.add_argument("-msg", "--msg_path", type=str, help="解密后的 MSG.db 的路径", required=True,
metavar="")
@ -195,10 +194,9 @@ class MainExportChatRecords():
try:
from flask import Flask, request, jsonify, render_template, g
import logging
from .show_chat.main_window import app_show_chat, get_user_list, export
except Exception as e:
print(e)
print("[-] 请安装flask( pip install flask )")
print("[-] 请安装flask( pip install flask)")
return
if not os.path.exists(args.msg_path) or not os.path.exists(args.micro_path) or not os.path.exists(

View File

@ -53,6 +53,8 @@ def decrypt(key: str, db_path, out_path):
salt = blist[:16]
byteKey = hashlib.pbkdf2_hmac("sha1", password, salt, DEFAULT_ITER, KEY_SIZE)
first = blist[16:DEFAULT_PAGESIZE]
if len(salt) != 16:
return False, f"[-] db_path:'{db_path}' File Error!"
mac_salt = bytes([(salt[i] ^ 58) for i in range(16)])
mac_key = hashlib.pbkdf2_hmac("sha1", byteKey, mac_salt, 2, KEY_SIZE)
@ -162,6 +164,50 @@ def batch_decrypt(key: str, db_path: Union[str, List[str]], out_path: str, is_lo
return True, result
def encrypt(key: str, db_path, out_path):
"""
通过密钥加密数据库
:param key: 密钥 64位16进制字符串
:param db_path: 待加密的数据库路径(必须是文件)
:param out_path: 加密后的数据库输出路径(必须是文件)
:return:
"""
if not os.path.exists(db_path) or not os.path.isfile(db_path):
return False, f"[-] db_path:'{db_path}' File not found!"
if not os.path.exists(os.path.dirname(out_path)):
return False, f"[-] out_path:'{out_path}' File not found!"
if len(key) != 64:
return False, f"[-] key:'{key}' Len Error!"
password = bytes.fromhex(key.strip())
with open(db_path, "rb") as file:
blist = file.read()
salt = os.urandom(16) # 生成随机盐值
byteKey = hashlib.pbkdf2_hmac("sha1", password, salt, DEFAULT_ITER, KEY_SIZE)
# 计算消息认证码
mac_salt = bytes([(salt[i] ^ 58) for i in range(16)])
mac_key = hashlib.pbkdf2_hmac("sha1", byteKey, mac_salt, 2, KEY_SIZE)
hash_mac = hmac.new(mac_key, blist[:-32], hashlib.sha1)
hash_mac.update(b'\x01\x00\x00\x00')
mac_digest = hash_mac.digest()
newblist = [blist[i:i + DEFAULT_PAGESIZE] for i in range(DEFAULT_PAGESIZE, len(blist), DEFAULT_PAGESIZE)]
with open(out_path, "wb") as enFile:
enFile.write(salt) # 写入盐值
enFile.write(mac_digest) # 写入消息认证码
for i in newblist:
t = AES.new(byteKey, AES.MODE_CBC, os.urandom(16)) # 生成随机的初始向量
encrypted = t.encrypt(i) # 加密数据块
enFile.write(encrypted)
return True, [db_path, out_path, key]
if __name__ == '__main__':
# 创建命令行参数解析器
parser = argparse.ArgumentParser()
@ -179,9 +225,4 @@ if __name__ == '__main__':
out_path = args.out_path
# 调用 decrypt 函数,并传入参数
result = batch_decrypt(key, db_path, out_path)
for i in result:
if isinstance(i, str):
print(i)
else:
print(f'[+] "{i[1]}" -> "{i[2]}"')
result = batch_decrypt(key, db_path, out_path, is_logging=True)

View File

@ -5,3 +5,4 @@
# Author: xaoyaoo
# Date: 2023/11/10
# -------------------------------------------------------------------------------
from .main_window import app_show_chat, get_user_list, export

View File

@ -184,6 +184,8 @@ def export_html(user, outpath, MSG_ALL_db_path, MediaMSG_all_db_path, FileStorag
username = user.get("username", "")
chatCount = user.get("chat_count", 0)
if chatCount == 0:
return False, "没有聊天记录"
for i in range(0, chatCount, page_size):
start_index = i
@ -191,7 +193,8 @@ def export_html(user, outpath, MSG_ALL_db_path, MediaMSG_all_db_path, FileStorag
FileStorage_path)
if len(data) == 0:
break
with open(f"{outpath}/{name_save}_{int(i / page_size)}.html", "w", encoding="utf-8") as f:
save_path = os.path.join(outpath, f"{name_save}_{int(i / page_size)}.html")
with open(save_path, "w", encoding="utf-8") as f:
f.write(render_template("chat.html", msgs=data))
return True, f"导出成功{outpath}"