解决相对导入包的问题,完善错误提示
This commit is contained in:
parent
c61618aadd
commit
03b694e1da
@ -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>
|
||||
|
@ -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")
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
|
@ -5,3 +5,4 @@
|
||||
# Author: xaoyaoo
|
||||
# Date: 2023/11/10
|
||||
# -------------------------------------------------------------------------------
|
||||
from .main_window import app_show_chat, get_user_list, export
|
||||
|
@ -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}"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user