吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 13695|回复: 117
收起左侧

[Python 原创] 半自动微信数据库脱密及解析,生成词云和条状图

    [复制链接]
w3812247 发表于 2022-12-9 13:04
最近突然对一个微信群里的聊天内容感到好奇,大家主要都说了些啥,某些关键词谁说的比较多,哈哈。于是开始在网上查询各路大神的教程,最终集合了网上的教程和其他前辈的源码,进行了整合。期间也测试了各种对加密sqlite进行解密的方法,最后决定使用vbs调用sqlcipher对微信的EnMicroMsg.db文件进行脱密,对这个db文件进行脱密需要进行数据库密码的计算,最后的核心回归到了获取手机(或模拟器)IMEI码的问题,有人说得使用本机的IMEI,但是我在我的模拟器里获取到的IMEI码并不好用,这时看到了其他人的帖子,IMEI码有些人是1234567890ABCDEF,最终我使用这个码成功获得了自己的数据库密码。以下为源码,新人,代码较乱。各路大神可以根据这个源码去解析其他的数据,哈哈。
python源码:
[Python] 纯文本查看 复制代码
import ast
import subprocess
import threading
import time
from tkinter import *
from tkinter import filedialog
from tkinter.ttk import *
import os
import hashlib
from xml.etree.ElementTree import parse
import jieba
import sqlite3
import tkinter.messagebox as GUI

from PIL import Image, ImageTk
from wordcloud import WordCloud
from snapshot_selenium import snapshot
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.render import make_snapshot
import matplotlib.pyplot as plt
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
jieba.set_dictionary("dict.txt")
jieba.initialize()
global dbpath
global xmlpath
dbpath = ""
xmlpath = ""
chatroomkey = ""


class db1():
    def __init__(self, db_path="plaintext.db"):
        """
        本地数据库初始化
        :param self:
        :param db_path:
        :return:
        """
        self.db = sqlite3.connect(db_path)

        self.cursor = self.db.cursor()

        self.top_data = []
        self.top_num = 5

    def execute1(self, sql, param=None):
        """
        sql:sql语句,包含:增、删、改
        数据,可以为列表、字典,也可以为空
        :param self:
        :param sql:
        :param param:
        :return:
        """
        count = 0
        try:
            if param is None:
                self.cursor.execute(sql)
                self.db.commit()
            else:
                if type(param) is list:
                    self.cursor.executemany(sql, param)
                else:
                    self.cursor.execute(sql, param)
                count = self.db.total_changes
                self.db.commit()
        except Exception as e:
            print(e)
            return False, e
        # 返回结果
        return True if count > 0 else False

    def query1(self, sql, param=None):
        """
        查询语句
        sql:sql语句
        param:参数,可以包含空
        return:成功返回True
        :param self:
        :param sql:
        :param param:
        :return:
        """
        if param is None:
            #print("--", sql)
            self.cursor.execute(sql)
        else:
            self.cursor.execute(sql, param)
        return self.cursor.fetchall()

    def get_chartroom_id(self, chatroomname):
        """
        获取群聊的id
        :return:
        """
        res = self.query1("select username from rcontact where nickname like '%" + chatroomname + "%'")
        print("select username from rcontact where nickname='" + chatroomname + "'")
        # 群聊id
        chatroom_id = res[0][0]
        print("---", res)
        return chatroom_id

    def getallchatroommesg(self, chatroom_id):
        """
        获取群聊天记录
        :param self:
        :param chatroom_id:
        :return:
        """
        # message表:聊天记录表
        # isSend=0:对方发送的;
        # isSend=1:自己发送的
        sql = "SELECT content FROM message WHERE talker='{}' and isSend=0".format(chatroom_id)
        # 查询表,获取所有的聊天记录#
        result = self.query1(sql)
        return result

    def insertop(self, result):
        # 生成top表
        self.create_top_table()
        msg_pre = []
        print(len(result))
        result11 = self.query1("select count(*) from top")
        win.tk_list_box_lb2z9la5.insert(0, "top表共计:" + str(result11[0][0]) + "条数据。")
        if result11[0][0] == 0:
            i = 0
            for item1 in result:
                # 发送者
                msg_pre = []
                i = i + 1
                send_from = item1[0].split(':')[0]
                # 发送内容
                send_msg = "".join(item1[0].split(':')[1:]).strip().replace("\"", "")
                msg_pre.append((send_from, send_msg))
                # 把要统计的数据,插入到top表中
                win.tk_list_box_lb2z9la5.insert(0, msg_pre)
                self.execute1("insert into top(uid,name,msg) values (NULL,?,?);", msg_pre)
        else:
            win.tk_list_box_lb2z9la5.insert(0, "已生成过top表,如需要重新生成(想分析其他群),请删除plaintext.db文件!")

    def getchatroommesg(self, result):
        mes = []
        # 循环查询到的所有的消息
        for item in result:
            # 过滤数据
            if not item or not item[0] or item[0].find('xml') != -1 or item[0].find('sysmsg') != -1 or item[0].find(
                    '<msg>') != -1 or item[0].find('chatroom') != -1 or item[0].find('weixinhongbao') != -1:
                continue
            # 过滤掉自己发送的内容,不包含:
            temps = item[0].split(':')
            if len(temps) < 2:
                # print('自己发送的内容:' + item[0])
                continue
            # 每一条聊天记录,过滤掉发送者,只保留消息正文
            # 发送者
            send_from = item[0].split(':')[0]
            # 发送内容
            send_msg = "".join(item[0].split(':')[1:]).strip().replace("\"", "")
            # 过长的消息,也过滤掉
            if len(send_msg) > 200:
                continue
            if "xml" in send_msg:
                print("----------------------包含xml----------------")
                continue
            # print(send_msg)
            mes.append(send_msg)
        return mes

    def getchatroommesg1(self, result):
        #此处犯懒了,其实可以和上边的方法进行整合。
        mes1 = []
        # 循环查询到的所有的消息
        for item in result:
            # 过滤数据
            if not item or not item[0] or item[0].find('xml') != -1 or item[0].find('sysmsg') != -1 or item[0].find(
                    '<msg>') != -1 or item[0].find('chatroom') != -1 or item[0].find('weixinhongbao') != -1:
                continue
            # 过滤掉自己发送的内容,不包含:
            temps = item[0].split(':')
            if len(temps) < 2:
                # print('自己发送的内容:' + item[0])
                continue
            # 每一条聊天记录,过滤掉发送者,只保留消息正文
            # 发送者
            send_from = item[0].split(':')[0]
            # 发送内容
            send_msg = "".join(item[0].split(':')[1:]).strip().replace("\"", "")
            # 过长的消息,也过滤掉
            if len(send_msg) > 200:
                continue
            if "xml" in send_msg:
                print("----------------------包含xml----------------")
                continue
            # print(send_from+":"+send_msg)
            mes1.append(send_from + ":" + send_msg)
        return mes1

    def generate_wordcloud(self, word1):
        """
        生成词云
        param word:
        return:
        """

        img = WordCloud(font_path="DroidSansFallback.ttf", width=2000, height=2000, margin=2,
                        collocations=False).generate(word1)
        plt.imshow(img)
        plt.axis("off")
        # plt.show()
        # 保存图片
        img.to_file("{}.png".format("群聊"))

    def create_top_table(self):
        """
        创建Top表
        :return:
        """
        # 创建Top表,如果存在就不重新创建
        result = self.execute1(
            "CREATE TABLE IF NOT EXISTS top(uid integer primary key,name varchar(200),msg varchar(200))")

    def get_top_partner(self):
        """
        排名前15的成员
        :return:
        """
       #过滤无用的消息
        strconditions = "where name not like '%撤回了一条消息%' and name not like '%领取了你的%'  and name not like '%当前版本不支持展示该内容%' and name not like '%我给你发了一个红包,赶紧去拆!%' and name not like '%位置共享已经结束%' and name not like '%你领取了自己发的%' "
        if len(chatroomkey.replace("\n", ""))>0:
            strconditions = strconditions + " and  msg like '%" + chatroomkey.replace("\n", "") + "%' "
        sql = "SELECT name as 姓名,COUNT(*) as times FROM top " + strconditions + "  GROUP BY name ORDER BY times DESC limit " + str(self.top_num) + "; "
        result = self.query1(sql)
        for item in result:
            # 用户id
            id = item[0]
            # 发言次数
            count = item[1]
            # 获取用户的昵称,即:微信昵称
            username = self.get_username(id)
            self.top_data.append({
                'username': username,
                'count': count
            })

    def get_username(self, id):
        #获取用户的真实昵称或备注(有备注的获取备注,没有备注的获取昵称)
        sql = "SELECT conRemark  FROM rcontact where username='" + id + "'"
        result = self.query1(sql)
        if result[0][0]=="":
            sql = "SELECT nickname  FROM rcontact where username='" + id + "'"
            result = self.query1(sql)
        return result[0][0]
    def draw_image(self):
        """
        数据可视化
        :return:
        """
        usernames = []
        counts = []
        for user in self.top_data:
            # 去除昵称中的特殊符号
            usernames.append(str(user.get('username')).strip()[0:8])
            counts.append(user.get('count'))
        def bar_chart() -> Bar:
            c = (
                Bar()
                    .add_xaxis(usernames)
                    # .add_yaxis("活跃度", counts)
                    .add_yaxis(chatroomkey, counts)
                    .reversal_axis()
                    .set_series_opts(label_opts=opts.LabelOpts(position="right"))
                    .set_global_opts(title_opts=opts.TitleOpts(title="最活跃的%d个小伙伴" % self.top_num))
            )
            return c

        # 需要安装 snapshot-selenium 或者 snapshot-phantomjs
        make_snapshot(snapshot, bar_chart().render(), "bar.png")


class WinGUI(Tk):
    #GUI部分

    def __init__(self):
        super().__init__()
        self.__win()
        self.tk_input_lauxqn9y = self.__tk_input_lauxqn9y()
        self.tk_button_lauxqrfi = self.__tk_button_lauxqrfi()
        self.tk_input_lauxrzf1 = self.__tk_input_lauxrzf1()
        self.tk_button_lauxs4bi = self.__tk_button_lauxs4bi()
        self.tk_label_lauxutbi = self.__tk_label_lauxutbi()
        self.tk_label_lauxxqk6 = self.__tk_label_lauxxqk6()
        self.tk_input_lauxz6au = self.__tk_input_lauxz6au()
        self.tk_label_lauxznxk = self.__tk_label_lauxznxk()
        self.tk_label_lauy095q = self.__tk_label_lauy095q()
        self.tk_input_lauy1c0v = self.__tk_input_lauy1c0v()
        self.tk_button_lauy9mi9 = self.__tk_button_lauy9mi9()
        self.tk_label_lauyak54 = self.__tk_label_lauyak54()
        self.tk_label_lauybx1s = self.__tk_label_lauybx1s()
        self.tk_label_lauyc5pl = self.__tk_label_lauyc5pl()
        self.tk_label_lb0d40rz = self.__tk_label_lb0d40rz()
        self.tk_input_lb0d550v = self.__tk_input_lb0d550v()
        self.tk_button_lb1m63sc = self.__tk_button_lb1m63sc()
        self.tk_list_box_lb2z9la5 = self.__tk_list_box_lb2z9la5()
        #判断是否存在mima.txt以及mima.txt内是否有内容,如果没有内容,那么禁用掉“复制上一次配置”按钮
        if os.path.exists("mima.txt"):
            with open("mima.txt", 'r', encoding='gb2312') as f:  # 打开文件

                firstline = f.readline()  # 读取第一行
                if firstline=="":
                    self.tk_button_lb1m63sc.config(state=DISABLED)
        else:
            self.tk_button_lb1m63sc.config(state=DISABLED)
    def __win(self):


        self.title("五哈半自动微信分析")
        self.iconbitmap()
        # 设置窗口大小、居中
        width = 600
        height = 700
        screenwidth = self.winfo_screenwidth()
        screenheight = self.winfo_screenheight()
        geometry = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
        self.geometry(geometry)
        self.iconbitmap("favicon.ico")
        self.resizable(width=False, height=False)

    def select_file(self, strpath, strname):
        # 单个文件选择
        strpath = filedialog.StringVar()
        selected_file_path = filedialog.askopenfilename()  # 使用askopenfilename函数选择单个文件
        if strname == "db":
            self.tk_input_lauxqn9y.delete(0, "end")
            self.tk_input_lauxqn9y.insert(0, selected_file_path)
            global dbpath
            dbpath = selected_file_path
        else:
            self.tk_input_lauxrzf1.delete(0, "end")
            self.tk_input_lauxrzf1.insert(0, selected_file_path)
            global xmlpath
            xmlpath = selected_file_path
        global image1
        image1 = selected_file_path

    def __tk_input_lauxqn9y(self):
        ipt = Entry(self,textvariable="")
        ipt.place(x=30, y=10, width=401, height=24)
        return ipt

    def __tk_button_lauxqrfi(self):
        btn = Button(self, text="选择EnMicroMsg.db",
                     command=lambda: self.thread_it(self.select_file('select_path', 'db')))
        btn.place(x=450, y=10, width=140, height=30)
        btn.place(x=450, y=10, width=140, height=30)
        return btn

    def __tk_input_lauxrzf1(self):
        ipt = Entry(self,textvariable="")
        ipt.place(x=30, y=90, width=402, height=24)
        return ipt

    def __tk_button_lauxs4bi(self):
        btn = Button(self, text="选择", command=lambda: self.thread_it(self.select_file('select_path', 'xml')))
        btn.place(x=460, y=90, width=125, height=30)
        return btn

    def __tk_label_lauxutbi(self):
        label = Label(self, text="文件夹路径:在安卓手机的/data/data/com.tencent.mm/MicroMsg/一长串/EnMicroMsg.db")
        label.place(x=30, y=50, width=552, height=24)
        return label

    def __tk_label_lauxxqk6(self):
        label = Label(self, text="文件夹路径:在安卓手机的/data/data/com.tencent.mm/shared_prefs/auth_info_key_prefs.xml中")
        label.place(x=30, y=130, width=555, height=24)
        return label

    def __tk_input_lauxz6au(self):
        ipt = Entry(self)
        ipt.place(x=180, y=200, width=404, height=24)
        return ipt

    def __tk_label_lauxznxk(self):
        label = Label(self, text="请输入要解析的群名:")
        label.place(x=30, y=200, width=136, height=24)
        return label

    def __tk_label_lauy095q(self):
        label = Label(self, text="请输入关键字(为空为活跃度排名):")
        label.place(x=30, y=240, width=215, height=24)
        return label

    def __tk_input_lauy1c0v(self):
        ipt = Entry(self)
        ipt.place(x=262, y=240, width=321, height=24)
        return ipt

    def __tk_button_lauy9mi9(self):
        btn = Button(self, text="开始解析", command=lambda: self.thread_it(self.startanalysis))
        btn.place(x=350, y=300, width=121, height=46)
        return btn

    def __tk_button_lb1m63sc(self):
        btn = Button(self, text="复制上一次配置", command=lambda: self.gethistroy())
        btn.place(x=150, y=300, width=132, height=45)
        return btn

    def __tk_label_lauyak54(self):
        label = Label(self, text="1、生成的词云在本程序的同级目录。2、生成的活跃度排名在本程序的同级目录。")
        label.place(x=30, y=270, width=551, height=23)
        return label

    def __tk_label_lauybx1s(self):
        label = Label(self, image="")  # text="词云",
        label.place(x=40, y=540, width=248, height=147)
        return label

    def __tk_label_lauyc5pl(self):
        label = Label(self, image="")  # , text="活跃度排名"
        label.place(x=319, y=540, width=248, height=147)
        return label

    def __tk_label_lb0d40rz(self):
        label = Label(self, text="手机IMEI码:")
        label.place(x=30, y=163, width=137, height=24)
        return label

    def __tk_input_lb0d550v(self):
        ipt = Entry(self, textvariable="")
        ipt.place(x=180, y=163, width=404, height=24)
        ipt.insert(0, '1234567890ABCDEF')
        return ipt

    def __tk_list_box_lb2z9la5(self):
        lb = Listbox(self)
        lb.insert(END, "运行状态")
        lb.place(x=31, y=353, width=547, height=171)
        return lb

    def gethistroy(self):
        # 获取历史记录,并赋值给默认值
        list = []  # 存档列表
        with open('mima.txt', 'r', encoding='gb2312') as file:
            for strline in file:
                #strline = strline.replace("b\'","")
                strline = strline.replace("\\\\","\\")
                #strline = strline.replace("\\n","")
                list.append(strline)


        self.tk_input_lauxqn9y.delete(0, "end")
        self.tk_input_lauxrzf1.delete(0, "end")
        self.tk_input_lauxz6au.delete(0, "end")
        self.tk_input_lauy1c0v.delete(0, "end")
        self.tk_input_lauxqn9y.insert(0, list[1])
        self.tk_input_lauxrzf1.insert(0, list[2])
        self.tk_input_lauxz6au.insert(0, list[3])
        self.tk_input_lauy1c0v.insert(0, list[4])

    def resize(self, w, h, w_box, h_box, pil_image):
        '''
        resize a pil_image object so it will fit into
        a box of size w_box times h_box, but retain aspect ratio
        对一个pil_image对象进行缩放,让它在一个矩形框内,还能保持比例
        '''
        f1 = 1.0 * w_box / w  # 1.0 forces float division in Python2
        f2 = 1.0 * h_box / h
        factor = min([f1, f2])
        # print(f1, f2, factor) # test
        # use best down-sizing filter
        width = int(w * factor)
        height = int(h * factor)
        return pil_image.resize((width, height), Image.ANTIALIAS)

    def thread_it(self, func, *args):
        """ 将函数打包进线程,防止解析的时候GUI出现卡死的情况 """
        print("----------------------启动多线程--------------")
        self.myThread = threading.Thread(target=func, args=args)
        self.myThread.setDaemon(True)  # 主线程退出就直接让子线程跟随退出,不论是否运行完成。
        self.myThread.start()
    def shownewwindows(self,imagepath):
        #生成新的窗口,用以展示放大的图片
        top = Toplevel(self)
        top.title(imagepath)
        top.geometry("850x500")
        top.iconbitmap("favicon.ico")
        v1 = StringVar()
        label1 = Label(top)
        label1.place(width=843, height=500)
        img_open1 = Image.open(imagepath)
        # 获取图像的原始大小
        w, h = img_open1.size
        # 期望图像显示的大小
        w_box = 850
        h_box = 500
        img_open1 = self.resize(w, h, w_box, h_box, img_open1)
        img_png1 = ImageTk.PhotoImage(img_open1)
        label1.configure(image=img_png1)
        label1.image = img_png1
    def startanalysis(self):
        #开始解析的主函数
        xmlpath = self.tk_input_lauxrzf1.get().replace("\n", "")
        dbpath = self.tk_input_lauxqn9y.get().replace("\n", "")
        if(self.tk_input_lauxrzf1.get()!="" and self.tk_input_lauxqn9y.get()!="" and self.tk_input_lb0d550v.get()!="" and self.tk_input_lauxz6au.get()!=""):
            try:
                self.tk_button_lauy9mi9.config(state=DISABLED)
                self.tk_button_lb1m63sc.config(state=DISABLED)
                self.tk_button_lauxqrfi.config(state=DISABLED)
                self.tk_button_lauxs4bi.config(state=DISABLED)
                self.tk_list_box_lb2z9la5.insert(0, "dbpath路径获取成功:" + str(dbpath))
                self.tk_list_box_lb2z9la5.insert(0, "xmlpath路径获取成功:" + str(dbpath))
                strimei = self.tk_input_lb0d550v.get()
                # 解析xml,取到unid
                f = open(xmlpath)
                # 第1个参数为输入源,返回一个ElementTree对象
                et = parse(f)
                # 通过元素树(ElementTree)得到根结点
                root = et.getroot()
                # 获取xml中value的值
                strunid = ""
                for e in root.iterfind('int'):
                    if e.get('name') == "_auth_uin":
                        strunid = e.get('value')
                # 开始计算微信数据库密码
                self.tk_list_box_lb2z9la5.insert(0, "_auth_uin值获取成功:" + str(strunid))
                md5 = hashlib.md5((strimei + strunid).encode()).hexdigest()
                pwd = md5[0:7]
                self.tk_list_box_lb2z9la5.insert(0, "数据库密码值计算成功:" + str(pwd))
                file = open('mima.txt', 'w', encoding='gb2312')
                self.tk_list_box_lb2z9la5.insert(0, "配置文件打开成功!")
                # 拼接字符串,给vbs传递参数
                strwechatname = self.tk_input_lauxz6au.get().replace("\n", "")
                strwechatkey = self.tk_input_lauy1c0v.get().replace("\n", "")
                #strvbs = pwd + "\n" + str(dbpath.encode("utf-8")) + "\n" + str(xmlpath.encode("utf-8")) + "\n" + str(strwechatname.encode("utf-8")) + "\n" + str(strwechatkey.encode("utf-8"))+"\n!@no~~"
                strvbs = pwd + "\n" + dbpath + "\n" + xmlpath + "\n" + strwechatname + "\n" + strwechatkey + "\n!@no~~"
                #print(strvbs)
                #time.sleep(500)
                strvbs = str(strvbs)
                file.write(strvbs)
                file.close()
                if os.path.exists("plaintext.db"):
                    GUI.showinfo(title='提示', message='检测到已存在脱密数据库plaintext.db,如需要重新生成请删除这个db文件!')
                else:
                    # os.popen('1.vbs')  # 执行微信数据库解密,并生成未加密数据库
                    # subprocess.call("cmd /c 1.vbs")  # works
                    # os.system("start 1.vbs")
                    self.tk_list_box_lb2z9la5.insert(0, "开始生成脱密数据库!")
                    os.system("test.vbs")
                    last_line = "!@no~~" #获取vbs的状态,看看其是否完成了
                    while last_line != "yes":
                        with open("mima.txt", 'r', encoding='gb2312') as f:  # 打开文件

                            lines = f.readlines()  # 读取所有行
                            last_line = lines[-1]  # 取最后一行
                            print(last_line)
                            self.tk_list_box_lb2z9la5.insert(0, "等待数据库脱密完成~")
                            time.sleep(2)
                    self.tk_list_box_lb2z9la5.insert(0, "数据库脱密完成!")
                # 开始解析 -----------------------
                self.tk_list_box_lb2z9la5.insert(0, "开始解析数据库!")
                wechat = db1()
                chatroomname = self.tk_input_lauxz6au.get().replace("\n", "")  # 输入的群名
                chartroom_id = wechat.get_chartroom_id(chatroomname)
                allchatroommesg = wechat.getallchatroommesg(chartroom_id)
                words = wechat.getchatroommesg(allchatroommesg)
                words1 = wechat.getchatroommesg1(allchatroommesg)
                # 分词
                strwords = str(words)
                temp = jieba.cut(strwords, cut_all=True)
                temp1 = ""
                for i in temp:
                    temp1 += str(i) + " "
                # 生成词云
                self.tk_list_box_lb2z9la5.insert(0, "开始生成词云!")
                wechat.generate_wordcloud(temp1)
                # 获取top表数据
                wechat.insertop(allchatroommesg)
                global chatroomkey
                chatroomkey = self.tk_input_lauy1c0v.get()  # 输入的关键词
                self.tk_list_box_lb2z9la5.insert(0, "开始生成柱状图!")
                wechat.get_top_partner()
                # 生成柱状图
                wechat.draw_image()
                # 结束解析 -----------------------
                # 生成的图片显示在图形界面上---
                img_open1 = Image.open("群聊.png")
                # print(img_open1)
                self.tk_list_box_lb2z9la5.insert(0, "柱状图生成完毕!")
                # 获取图像的原始大小
                w, h = img_open1.size
                # 期望图像显示的大小
                w_box = 248
                h_box = 147
                img_open1 = self.resize(w, h, w_box, h_box, img_open1)
                # print(img_open1)
                img_png1 = ImageTk.PhotoImage(img_open1)
                # self.tk_label_lauybx1s().image = img_png1
                self.tk_label_lauybx1s.configure(image=img_png1)
                self.tk_label_lauybx1s.image = img_png1
                img_open2 = Image.open("bar.png")
                img_open2 = self.resize(w, h, w_box, h_box, img_open2)
                img_png2 = ImageTk.PhotoImage(img_open2)
                self.tk_label_lauyc5pl.configure(image=img_png2)
                self.tk_label_lauyc5pl.image = img_png2
                self.tk_list_box_lb2z9la5.insert(0, "程序运行完毕!")
                self.tk_list_box_lb2z9la5.insert(0, "点击图片可以进行放大!")
                self.tk_button_lauy9mi9.config(state=ACTIVE)
                self.tk_button_lb1m63sc.config(state=ACTIVE)
                self.tk_button_lauxqrfi.config(state=ACTIVE)
                self.tk_button_lauxs4bi.config(state=ACTIVE)
            except Exception as err:
                self.tk_button_lauy9mi9.config(state=ACTIVE)
                self.tk_button_lb1m63sc.config(state=ACTIVE)
                self.tk_button_lauxqrfi.config(state=ACTIVE)
                self.tk_button_lauxs4bi.config(state=ACTIVE)
                print('An exception happened: ' + str(err))
                # 发生异常所在的文件
                print(err.__traceback__.tb_frame.f_globals["__file__"])
                # 发生异常所在的行数
                print(err.__traceback__.tb_lineno)

                self.tk_list_box_lb2z9la5.insert(0, "程序出现异常-异常文件:"+str(err.__traceback__.tb_frame.f_globals["__file__"]))
                self.tk_list_box_lb2z9la5.insert(0, "程序出现异常行数:" + str(err.__traceback__.tb_lineno))
                self.tk_list_box_lb2z9la5.insert(0, "程序出现异常:" + str(err))
        else:
            GUI.showinfo(title='提示', message='请把必填项填写完整后再次提交!')

class Win(WinGUI):
    def __init__(self):
        super().__init__()
        self.__event_bind()

    def 词云show(self, evt):
        win.shownewwindows("群聊.png")


    def 排名show(self, evt):

        win.shownewwindows("bar.png")

    def __event_bind(self):
        self.tk_label_lauybx1s.bind('<Button>', self.词云show)
        self.tk_label_lauyc5pl.bind('<Button>', self.排名show)


if __name__ == "__main__":
    win = Win()
    win.mainloop()

以上是python的源码,下面一部分是vbs的源码,需要两部分配合起来使用。复制到txt里,并保存文件名为test.vbs。
[Visual Basic] 纯文本查看 复制代码
Set s = WScript.CreateObject("WScript.Shell") 
strtime = 10 '设置统一的延迟时间
app = s.Run("cmd") '运行cmd
dim fso,fread,line_1st,len_line,a,strall,cc,dd,ee,eee
set fso=createobject("scripting.filesystemobject")
set fread=fso.opentextfile("mima.txt",1)
line_1st=fread.readline
a=right("0000"&line_1st,4)
a = line_1st
b = fread.readline
c = fread.readline
fread.close
set fso=nothing
'app=s.Run ("C:\Users\86480\Desktop\sqlcipher.exe C:\Users\86480\Desktop\EnMicroMsg.db")
code0 ="sqlcipher.exe" & " "&b
code1="PRAGMA key = '"&a&"';"
code2="PRAGMA cipher_use_hmac = off;"
code3="PRAGMA kdf_iter = 4000;"
code4="ATTACH DATABASE 'plaintext.db' AS plaintext KEY '';"
code5="SELECT sqlcipher_export{(}'plaintext'{)};"
code6="DETACH DATABASE plaintext;"
code7 = "{ENTER}"
code8=".exit"
code9="exit"
msgbox "为了防止卡死,请停留在cmd界面后,点击确定"

s.AppActivate app
s.SendKeys code0
s.SendKeys code7
WScript.Sleep strtime  '毫秒
s.SendKeys code1
s.SendKeys code7
WScript.Sleep strtime  '毫秒
s.SendKeys code2
s.SendKeys code7
WScript.Sleep strtime  '毫秒
s.SendKeys code3
s.SendKeys code7
WScript.Sleep strtime  '毫秒
s.SendKeys code4
s.SendKeys code7
WScript.Sleep strtime  '毫秒
s.SendKeys code5
s.SendKeys code7
WScript.Sleep strtime  '毫秒
s.SendKeys code6
s.SendKeys code7
WScript.Sleep strtime  '毫秒
s.SendKeys code8
s.SendKeys code7
WScript.Sleep strtime  '毫秒
s.SendKeys code9
s.SendKeys code7

dim oTxt,content,fso1
set fso1=createobject("scripting.filesystemobject")
set oTxt=fso1.opentextfile("mima.txt",1)
strall = oTxt.readall
oTxt.close
set fso1=createobject("scripting.filesystemobject")
set oTxt=fso1.opentextfile("mima.txt",2)
content = replace(strall,"!@no~~","yes")
oTxt.write(content)
oTxt.close

Wscript.quit


以上的代码需要配置好基础环境。
1、安装google浏览器108.0.5359.72_chrome_installer.exe
2、拷贝这个文件至本地chromedriver
3、添加chromedriver到环境变量
3添加chromedriver到环境变量_页面_1.jpg
3添加chromedriver到环境变量_页面_2.jpg
3添加chromedriver到环境变量_页面_3.jpg
3添加chromedriver到环境变量_页面_4.jpg



4、微信数据库和xml导出教程,具体的可以去网上搜索教程。
image.png
5、常见问题:
image.png
6、数据库查看器:文件过大,可以去成品里去找。


成品链接:https://www.aliyundrive.com/s/bapL6ZeBmDG

免费评分

参与人数 48威望 +2 吾爱币 +145 热心值 +41 收起 理由
我要笑 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
elan + 1 + 1 谢谢@Thanks!
onlywey + 1 + 1 用心讨论,共获提升!
chenfeng630 + 1 + 1 热心回复!
PDX123 + 1 + 1 我很赞同!
freexsony + 1 + 1 谢谢@Thanks!
板砖亲你头 + 1 + 1 用心讨论,共获提升!
luolifu + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
shamemist + 1 + 1 用心讨论,共获提升!
Crazypolice + 1 + 1 谢谢@Thanks!
UXGO + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
angren + 1 我很赞同!
hqf106 + 1 + 1 谢谢@Thanks!
qbpman + 1 + 1 谢谢@Thanks!
suadzh + 1 + 1 用心讨论,共获提升!
guoruihotel + 1 + 1 谢谢@Thanks!
gaosld + 1 + 1 用心讨论,共获提升!
discuz0 + 1 + 1 用心讨论,共获提升!
beginnerzero + 1 + 1 谢谢@Thanks!
jzcjy + 1 + 1 谢谢@Thanks!
柑桔 + 1 + 1 谢谢@Thanks!
香芋 + 1 + 1 用心讨论,共获提升!
梦入神机 + 2 + 1 更期待PC端
DIGI + 1 谢谢@Thanks!
sywee + 1 用心讨论,共获提升!
renshaowei + 1 + 1 谢谢@Thanks!
zhixiangwangluo + 1 谢谢@Thanks!
cooker689 + 1 我很赞同!
wongJzzz + 1 我很赞同!
imumu1239 + 1 + 1 谢谢@Thanks!
随便起 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
thrinity + 1 + 1 谢谢@Thanks!
SAPLU + 1 谢谢@Thanks!
杰少123 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
s757129 + 1 + 1 ggnb!
nqzva + 1 谢谢@Thanks!
yixi + 1 + 1 谢谢@Thanks!
康康认真的 + 1 + 1 谢谢@Thanks!
zhangyoung + 1 谢谢@Thanks!
18685157041 + 1 + 1 用心讨论,共获提升!
蓝天伯爵 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
assa + 1 + 1 我很赞同!
gqdsc + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
shadmmd + 1 谢谢@Thanks!
xzqsr + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
gcode + 1 + 1 谢谢@Thanks!
wushaominkk + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| w3812247 发表于 2022-12-9 13:25
对了,还有一个大家可能会碰到的问题,运行vbs的时候,搜狗拼音要切换成英文,如果切换为中文,vbs会乱套。哈哈
 楼主| w3812247 发表于 2022-12-9 18:24
云烟成雨 发表于 2022-12-9 15:20
前辈,我想问下拿到数据库密钥以后,怎么用SQLite直接打开,页大小、KDF迭代、HMAC算法、KDF算法的参数是多 ...

这个我也没试出来,不过我的那个成品链接里有一个能打开加密的。
 楼主| w3812247 发表于 2022-12-9 13:09
孤寡 发表于 2022-12-9 14:14
路过  学习一下
gdzdhyb 发表于 2022-12-9 14:18
学习一下
gcode 发表于 2022-12-9 14:47
看代码,还是花了很多时间和精力,谢谢分享,
lfordch 发表于 2022-12-9 14:49
学习了,感谢大佬分享~
Tatwing 发表于 2022-12-9 15:04
哇,这个值得参考学习!
冷月天涯 发表于 2022-12-9 15:17
这个很牛,值得学习
云烟成雨 发表于 2022-12-9 15:20
前辈,我想问下拿到数据库密钥以后,怎么用SQLite直接打开,页大小、KDF迭代、HMAC算法、KDF算法的参数是多少?我知道sqlcipher老版本可以打开,但是那个旧版的数据量大很容易卡死退出,新版的能改下参数打开吗?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-22 19:04

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表