劫持微信聊天记录并分析还原 —— 访问数据库并检察聊天记录(五) ...

打印 上一主题 下一主题

主题 1809|帖子 1809|积分 5431



  • 本工具设计的初衷是用来获取微信账号的相关信息并解析PC版微信的数据库。
  • 程序以 Python 语言开辟,可读取、解密、还原微信数据库并帮助用户检察聊天记录,还可以将其聊天记录导出为csv、html等格式用于AI练习,自动复兴或备份等等作用。下面我们将深入探究这个工具的各个方面及其工作原理。
  • 本项目仅供学习交换利用,严禁用于商业用途或非法途径,任何违反法律法规、侵犯他人合法权益的举动,均与本项目及其开辟者无关,后果由举动人自行承担。
  • 创作不易,请动动您发财的小手点点赞并收藏,您的支持是咱敲键盘的动力。
【完整演示工具下载】
https://www.chwm.vip/index.html?aid=23
我们接着上一篇文章《劫持微信聊天记录并分析还原 —— 数据库布局解说(四)》继承演示与解说如何访问微信归并后的数据库并利用程序自带的网页UI来检察PC端微信的聊天记录,包括实时消息的获取等。
详细命令:
dbshow -merge "C:\Users\admin\AppData\Local\Temp\wxdb_all.db" -wid "C:\Users\admin\Documents\WeChat Files\wxid_b*************1"


  • -merge 为指定归并后的微信数据库路径
  • -wid 为微信用户帐号文件目录(用于显示图片)


运行命令后程序会自动打开网页UI。

此时我们点击“聊天检察”功能是无法看到聊天数据的,首次利用我们需要先将程序初始化设置。

依次点击右下角“更多设置”  - “初始化设置” - “自动解密已登录微信”

选择已登录的微信(支持多个微信检察)


并耐心等待提示成功后(加载的时间根据数据量的巨细而定),我们再次点击“聊天检察”功能。

此时全部该帐号下最近的聊天数据即可一一检察,但这些数据并不会实时显示,假如需要获取实时聊天数据,我们还需要手动点击聊天记录框右上角“实时消息”。


等待提示成功后,我们刷新一下页面即可检察实时聊天记录。
部分现实代码:
  1. # -*- coding: utf-8 -*-#
  2. # -------------------------------------------------------------------------------
  3. # Name:         __init__.py
  4. # Description:  
  5. # Author:       Rainbow
  6. # Date:         2024/11/09
  7. # -------------------------------------------------------------------------------
  8. import os
  9. import subprocess
  10. import sys
  11. import time
  12. import uvicorn
  13. import mimetypes
  14. import logging
  15. from logging.handlers import RotatingFileHandler
  16. from uvicorn.config import LOGGING_CONFIG
  17. from fastapi import FastAPI, Request, Path, Query
  18. from fastapi.staticfiles import StaticFiles
  19. from fastapi.exceptions import RequestValidationError
  20. from starlette.middleware.cors import CORSMiddleware
  21. from starlette.responses import RedirectResponse, FileResponse
  22. from .utils import gc, is_port_in_use, server_loger
  23. from .rjson import ReJson
  24. from .remote_server import rs_api
  25. from .local_server import ls_api
  26. from pywxdump import __version__
  27. def gen_fastapi_app(handler):
  28.     app = FastAPI(title="wxdump", description="微信工具", version=__version__,
  29.                   terms_of_service="https://www.chwm.vip",
  30.                   contact={"name": "Rainbow", "url": "https://www.chwm.vip"},
  31.                   license_info={"name": "MIT License",
  32.                                 "url": "https://www.chwm.vip"})
  33.     web_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "ui", "web")  # web文件夹路径
  34.     # 跨域
  35.     origins = [
  36.         "http://localhost:5000",
  37.         "http://127.0.0.1:5000",
  38.         "http://localhost:8080",  # 开发环境的客户端地址"
  39.         # "http://0.0.0.0:5000",
  40.         # "*"
  41.     ]
  42.     app.add_middleware(
  43.         CORSMiddleware,
  44.         allow_origins=origins,  # 允许所有源
  45.         allow_credentials=True,
  46.         allow_methods=["*"],  # 允许所有方法
  47.         allow_headers=["*"],  # 允许所有头
  48.     )
  49.     @app.on_event("startup")
  50.     async def startup_event():
  51.         logger = logging.getLogger("uvicorn")
  52.         logger.addHandler(handler)
  53.     # 错误处理
  54.     @app.exception_handler(RequestValidationError)
  55.     async def request_validation_exception_handler(request: Request, exc: RequestValidationError):
  56.         # print(request.body)
  57.         return ReJson(1002, {"detail": exc.errors()})
  58.     # 首页
  59.     @app.get("/")
  60.     @app.get("/index.html")
  61.     async def index():
  62.         response = RedirectResponse(url="/s/index.html", status_code=307)
  63.         return response
  64.     # 路由挂载
  65.     app.include_router(rs_api, prefix='/api/rs', tags=['远程api'])
  66.     app.include_router(ls_api, prefix='/api/ls', tags=['本地api'])
  67.     # 根据文件类型,设置mime_type,返回文件
  68.     @app.get("/s/{filename:path}")
  69.     async def serve_file(filename: str):
  70.         # 构建完整的文件路径
  71.         file_path = os.path.join(web_path, filename)
  72.         file_path = os.path.abspath(file_path)
  73.         # 检查文件是否存在
  74.         if os.path.isfile(file_path):
  75.             # 获取文件 MIME 类型
  76.             mime_type, _ = mimetypes.guess_type(file_path)
  77.             # 如果 MIME 类型为空,则默认为 application/octet-stream
  78.             if mime_type is None:
  79.                 mime_type = "application/octet-stream"
  80.                 server_loger.warning(f"[+] 无法获取文件 MIME 类型,使用默认值:{mime_type}")
  81.             if file_path.endswith(".js"):
  82.                 mime_type = "text/javascript"
  83.             server_loger.info(f"[+] 文件 {file_path} MIME 类型:{mime_type}")
  84.             # 返回文件
  85.             return FileResponse(file_path, media_type=mime_type)
  86.         # 如果文件不存在,返回 404
  87.         return {"detail": "Not Found"}, 404
  88.     # 静态文件挂载
  89.     # if os.path.exists(os.path.join(web_path, "index.html")):
  90.     #     app.mount("/s", StaticFiles(directory=web_path), name="static")
  91.     return app
  92. def start_server(port=5000, online=False, debug=False, isopenBrowser=True,
  93.                  merge_path="", wx_path="", my_wxid="", ):
  94.     """
  95.     启动flask
  96.     :param port:  端口号
  97.     :param online:  是否在线查看(局域网查看)
  98.     :param debug:  是否开启debug模式
  99.     :param isopenBrowser:  是否自动打开浏览器
  100.     :return:
  101.     """
  102.     work_path = os.path.join(os.getcwd(), "wxdump_work")  # 临时文件夹,用于存放图片等    # 全局变量
  103.     if not os.path.exists(work_path):
  104.         os.makedirs(work_path, exist_ok=True)
  105.         server_loger.info(f"[+] 创建临时文件夹:{work_path}")
  106.         print(f"[+] 创建临时文件夹:{work_path}")
  107.     # 日志处理,写入到文件
  108.     log_format = '[{levelname[0]}] {asctime} [{name}:{levelno}] {pathname}:{lineno} {message}'
  109.     log_datefmt = '%Y-%m-%d %H:%M:%S'
  110.     log_file_path = os.path.join(work_path, "wxdump.log")
  111.     file_handler = RotatingFileHandler(log_file_path, mode="a", maxBytes=10 * 1024 * 1024, backupCount=3)
  112.     formatter = logging.Formatter(fmt=log_format, datefmt=log_datefmt, style='{')
  113.     file_handler.setFormatter(formatter)
  114.     wx_core_logger = logging.getLogger("wx_core")
  115.     db_prepare = logging.getLogger("db_prepare")
  116.     # 这几个日志处理器为本项目的日志处理器
  117.     server_loger.addHandler(file_handler)
  118.     wx_core_logger.addHandler(file_handler)
  119.     db_prepare.addHandler(file_handler)
  120.     conf_file = os.path.join(work_path, "conf_auto.json")  # 用于存放各种基础信息
  121.     auto_setting = "auto_setting"
  122.     env_file = os.path.join(work_path, ".env")  # 用于存放环境变量
  123.     # set 环境变量
  124.     os.environ["PYWXDUMP_WORK_PATH"] = work_path
  125.     os.environ["PYWXDUMP_CONF_FILE"] = conf_file
  126.     os.environ["PYWXDUMP_AUTO_SETTING"] = auto_setting
  127.     with open(env_file, "w", encoding="utf-8") as f:
  128.         f.write(f"PYWXDUMP_WORK_PATH = '{work_path}'\n")
  129.         f.write(f"PYWXDUMP_CONF_FILE = '{conf_file}'\n")
  130.         f.write(f"PYWXDUMP_AUTO_SETTING = '{auto_setting}'\n")
  131.     if merge_path and os.path.exists(merge_path):
  132.         my_wxid = my_wxid if my_wxid else "wxid_dbshow"
  133.         gc.set_conf(my_wxid, "wxid", my_wxid)  # 初始化wxid
  134.         gc.set_conf(my_wxid, "merge_path", merge_path)  # 初始化merge_path
  135.         gc.set_conf(my_wxid, "wx_path", wx_path)  # 初始化wx_path
  136.         db_config = {"key": my_wxid, "type": "sqlite", "path": merge_path}
  137.         gc.set_conf(my_wxid, "db_config", db_config)  # 初始化db_config
  138.         gc.set_conf(auto_setting, "last", my_wxid)  # 初始化last
  139.     # 检查端口是否被占用
  140.     if online:
  141.         host = '0.0.0.0'
  142.     else:
  143.         host = "127.0.0.1"
  144.     if is_port_in_use(host, port):
  145.         server_loger.error(f"Port {port} is already in use. Choose a different port.")
  146.         print(f"Port {port} is already in use. Choose a different port.")
  147.         input("Press Enter to exit...")
  148.         return  # 退出程序
  149.     if isopenBrowser:
  150.         try:
  151.             # 自动打开浏览器
  152.             url = f"http://127.0.0.1:{port}/"
  153.             # 根据操作系统使用不同的命令打开默认浏览器
  154.             if sys.platform.startswith('darwin'):  # macOS
  155.                 subprocess.call(['open', url])
  156.             elif sys.platform.startswith('win'):  # Windows
  157.                 subprocess.call(['start', url], shell=True)
  158.             elif sys.platform.startswith('linux'):  # Linux
  159.                 subprocess.call(['xdg-open', url])
  160.             else:
  161.                 server_loger.error(f"Unsupported platform, can't open browser automatically.", exc_info=True)
  162.                 print("Unsupported platform, can't open browser automatically.")
  163.         except Exception as e:
  164.             server_loger.error(f"自动打开浏览器失败:{e}", exc_info=True)
  165.     time.sleep(1)
  166.     server_loger.info(f"启动 Web 服务,host:port:{host}:{port}")
  167.     print("[+] 请使用浏览器访问 http://127.0.0.1:5000/ 查看聊天记录")
  168.     global app
  169.     print("[+] 如需查看api文档,请访问 http://127.0.0.1:5000/docs ")
  170.     app = gen_fastapi_app(file_handler)
  171.     LOGGING_CONFIG["formatters"]["default"]["fmt"] = "[%(asctime)s] %(levelprefix)s %(message)s"
  172.     LOGGING_CONFIG["formatters"]["access"][
  173.         "fmt"] = '[%(asctime)s] %(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s'
  174.     uvicorn.run(app=app, host=host, port=port, reload=debug, log_level="info", workers=1, env_file=env_file)
  175. app = None
  176. __all__ = ["start_server", "gen_fastapi_app"]
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

刘俊凯

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表