吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 14254|回复: 117
上一主题 下一主题
收起左侧

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

    [复制链接]
跳转到指定楼层
楼主
w3812247 发表于 2022-12-9 13:04 回帖奖励
最近突然对一个微信群里的聊天内容感到好奇,大家主要都说了些啥,某些关键词谁说的比较多,哈哈。于是开始在网上查询各路大神的教程,最终集合了网上的教程和其他前辈的源码,进行了整合。期间也测试了各种对加密sqlite进行解密的方法,最后决定使用vbs调用sqlcipher对微信的EnMicroMsg.db文件进行脱密,对这个db文件进行脱密需要进行数据库密码的计算,最后的核心回归到了获取手机(或模拟器)IMEI码的问题,有人说得使用本机的IMEI,但是我在我的模拟器里获取到的IMEI码并不好用,这时看到了其他人的帖子,IMEI码有些人是1234567890ABCDEF,最终我使用这个码成功获得了自己的数据库密码。以下为源码,新人,代码较乱。各路大神可以根据这个源码去解析其他的数据,哈哈。
python源码:
[Python] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
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 / # 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] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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到环境变量







4、微信数据库和xml导出教程,具体的可以去网上搜索教程。

5、常见问题:

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算法的参数是多 ...

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

本版积分规则

返回列表

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

GMT+8, 2025-5-22 23:44

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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