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设置->文件管理查看

- 点击**设置微信路径**按钮,选择该文件夹路径
+ 点击**设置微信路径**按钮,选择该文件夹路径下的带有wxid_xxx的路径
+ 
+
5. 获取到密钥和微信路径之后点击开始解密
6. 解密后的数据库文件保存在./app/DataBase/Msg路径下
From 01a4733b55d1f37992537b712d68543592b65ff5 Mon Sep 17 00:00:00 2001
From: shuaikangzhou <863909694@qq.com>
Date: Mon, 20 Nov 2023 23:08:10 +0800
Subject: [PATCH 2/3] =?UTF-8?q?=E6=98=BE=E7=A4=BA=E8=81=8A=E5=A4=A9?=
=?UTF-8?q?=E5=9B=BE=E7=89=87?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.idea/workspace.xml | 41 +++++++++++++++----------------
app/DataBase/hard_link.py | 8 +++---
app/components/bubble_message.py | 28 +++++++++++++--------
app/data/icons/404.png | Bin 0 -> 1994 bytes
app/ui_pc/Icon.py | 1 +
app/ui_pc/chat/chat_info.py | 22 +++++++++++++++--
app/ui_pc/mainview.py | 1 -
app/util/__init__.py | 1 +
app/util/path.py | 11 +++++++++
9 files changed, 75 insertions(+), 38 deletions(-)
create mode 100644 app/data/icons/404.png
create mode 100644 app/util/path.py
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index ab978f1..4978b11 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,16 +4,15 @@
-
-
+
+
-
-
-
+
+
+
+
-
-
-
+
@@ -122,7 +121,7 @@
-
+
@@ -251,10 +250,10 @@
-
-
+
+
@@ -271,13 +270,6 @@
1672848140146
-
- 1698681328723
-
-
-
- 1698681328723
-
1698765961025
@@ -614,7 +606,14 @@
1700478493497
-
+
+ 1700490633275
+
+
+
+ 1700490633275
+
+
@@ -650,7 +649,6 @@
-
@@ -675,7 +673,8 @@
-
+
+
diff --git a/app/DataBase/hard_link.py b/app/DataBase/hard_link.py
index 448199f..34236ec 100644
--- a/app/DataBase/hard_link.py
+++ b/app/DataBase/hard_link.py
@@ -8,7 +8,7 @@ lock = threading.Lock()
DB = None
cursor = None
db_path = "./app/Database/Msg/HardLinkImage.db"
-root_path = '/MsgAttach/'
+root_path = 'FileStorage/MsgAttach/'
if os.path.exists(db_path):
DB = sqlite3.connect(db_path, check_same_thread=False)
# '''创建游标'''
@@ -47,16 +47,16 @@ def get_md5_from_xml(content):
root = ET.fromstring(content)
# 提取md5的值
md5_value = root.find(".//img").get("md5")
- print(md5_value)
+ # print(md5_value)
return md5_value
-def get_image(content, thumb=True):
+def get_image(content, thumb=False):
md5 = get_md5_from_xml(content)
# md5 = 'bc37a58c32cb203ee9ac587b068e5853'
result = get_image_by_md5(binascii.unhexlify(md5))
if result:
- print(result)
+ # print(result)
dir1 = result[3]
dir2 = result[4]
data_image = result[2]
diff --git a/app/components/bubble_message.py b/app/components/bubble_message.py
index 7c982c3..fc26e4b 100644
--- a/app/components/bubble_message.py
+++ b/app/components/bubble_message.py
@@ -8,7 +8,7 @@ from PyQt5.QtWidgets import QWidget, QLabel, QHBoxLayout, QSizePolicy, QVBoxLayo
class MessageType:
Text = 1
- Image = 2
+ Image = 3
class TextMessage(QLabel):
@@ -104,20 +104,28 @@ class OpenImageThread(QThread):
class ImageMessage(QLabel):
- def __init__(self, avatar, parent=None):
+ def __init__(self, image, image_link='', max_width=480, max_height=720, parent=None):
+ """
+ param:image 图像路径或者QPixmap对象
+ param:image_link='' 点击图像打开的文件路径
+ """
super().__init__(parent)
self.image = QLabel(self)
- if isinstance(avatar, str):
- self.setPixmap(QPixmap(avatar))
- self.image_path = avatar
- elif isinstance(avatar, QPixmap):
- self.setPixmap(avatar)
- self.setMaximumWidth(480)
- self.setMaximumHeight(720)
- self.setScaledContents(True)
+
+ if isinstance(image, str):
+ self.setPixmap(QPixmap(image))
+ self.image_path = image
+ elif isinstance(image, QPixmap):
+ self.setPixmap(image)
+ if image_link:
+ self.image_path = image_link
+ self.setMaximumWidth(max_width)
+ self.setMaximumHeight(max_height)
+ # self.setScaledContents(True)
def mousePressEvent(self, event):
if event.buttons() == Qt.LeftButton: # 左键按下
+ print('打开图像', self.image_path)
self.open_image_thread = OpenImageThread(self.image_path)
self.open_image_thread.start()
diff --git a/app/data/icons/404.png b/app/data/icons/404.png
new file mode 100644
index 0000000000000000000000000000000000000000..d16f27210343876fa927c10082faa5a2f8e61b93
GIT binary patch
literal 1994
zcmcgt`#ThP7yr%;5mHgPKP{1l31Kss$$gqgnQ=E%6g5ijWEr-RxYlksAn0NXQ-kRkyS!rcy0Dvsc(e|R)
zQof6ngjjc3UFsJbNccquYfwL+x&(k^D$e!{A%?`EVX{?-``%8!{X^%VTJly+ttx^Z
z?BmfAoP3w@kdd|~XMQ%5;0VvqLujkv%!7_sU)Cz0AwLi8^0YO~sohEquv@%uoOQJz
zXVbLp7N7IpOI_%_#PC_`7%$-pJ21jeo99-|t*l<+MGLW0PFLR7ZB75(W{x<9GG2=<
z<>TAf35V-CWfG6b{j#wTCIFSS#-B}QagQ!OXJ2oIo`eDtRrH6+{)t+m|5xGeg=do-
z1mFpG91aVvvyjv+#_*EQKN2agA8>`IHs&Ub5b@KZi50#uV0X4~^w%&y-Ju^q5U0T=
zzmDK<4Ys^J%`@c=_9C#&UM51Ju+pvejAN*q6gpS0}bL0
zBPnS67$M7!T>Far*42+;3W;H%A>6$nvYfWc;UH*dRwZMwc}YzrS-IOmBUMv8
z(MW?HKVklqM|Sfq@OBb+K=;Gs2eu%lh+*
z0L1)T&6Ncs-n}O@4^SBH1?}Ds`Fe`!uh5}Zd*Gn93BOAMSduGI0YcGhn=e3sb!ttf
z6d;Uimmxvk7=dUD%HJ6X0>s@_)*OWbVpN}w445||Dk^}gr+6z*pxIDelMb-=eAoM+
zAl8X!2M0B)znxbCy*Fy~jslm!qWGu(F$8f>CsTtFbmp;C+-GE^U
z<_?5MZPNr?-cs%1OYQyKm)E9Rr%s~TDrsMTkJPIzwZPTDDCek&(Wu52Gt74HQ0|J|
z&lusX@C#c?D!IJ36iqbD>hp&u4u-^)TaATvlxNRfqP0ii?()OA|*@ZmanVBw2G~yLR;Bt5Ae9XzBscOUxix7!2j8$yo>2u>TN+k%!%6Jgyg)8gh
z4wXbM%$=t%Kg&s&BwsdW1uEs$_f&6rTv0Tpgwz?Ve=br&4PN~1)7baGwF<}+%VW>8
zU$|)9wD1;L;1&40s?36a>v#5Q8h(A4Hd!gM$jxtALJyu!jj;65{G?1VGCdn?=)1W;
z_}JBM-HOs2i5XtjJj=J$O=rjQhQ2d8ie-e-i=gIv-bpuF9`^w2ef`ic|7hF6em$ZGWhL@8ti{{^@F5=JL}PRLVQ0
z$BS}SdQCF6fnzXWbTEAo)T^{I{xVR(ftmE6@#NdNmzkeU%CsjZquexEVdT
z_dA^zPjq+R6sGOC>@`h$F`)@XP2@4E0CX0XVTLH{y6I46u7PqYQ4Td!i`oZy!W`iSt=Qfb2b$(Own9RyT^Zs~7^HiRYxg!sit4
zOJ01IL|$@CFw~0EsE+ete3`Js`Y=M74rRNKG$yvvu&LYwL9UK|vf(?sXGk{UD|-vEC;~<4L}A|R%NwY?W*lQ{|#xRl8mu(&SSHI?aPiGB(r9(
zkd5)VU&)AX|2#jE+hYNOcxKA7@1bP0n+C-m!-BS)2$v`yfJ0btG#U*qZCII4-!`R{
zEJaX*tq=nUO1Q*gxjh6rlW+K~keZ!eRRslDf^+0+^*Aw65Ak;-moGZJAtNjX(d)X>
zg^-p)Wf;$#KEMH#*-#HZgQD}N+>-8R9e1fF)Hi$8;Q&_ZwLlB%
z-n}1;Ffn_xb#}tehYlZh?HNwmk7o{RG4H(OirAbeu02g8-)?&}(3R|xCY}Yr**V+R
ITl**f4|^-6F#rGn
literal 0
HcmV?d00001
diff --git a/app/ui_pc/Icon.py b/app/ui_pc/Icon.py
index 88a0f0e..9a569b1 100644
--- a/app/ui_pc/Icon.py
+++ b/app/ui_pc/Icon.py
@@ -3,6 +3,7 @@ from PyQt5.QtGui import QIcon
class Icon:
Default_avatar_path = './app/data/icons/default_avatar.svg'
+ Default_image_path = './app/data/icons/404.png'
MainWindow_Icon = QIcon('./app/data/icons/logo.svg')
Default_avatar = QIcon(Default_avatar_path)
Output = QIcon('./app/data/icons/output.svg')
diff --git a/app/ui_pc/chat/chat_info.py b/app/ui_pc/chat/chat_info.py
index 96b3d0b..d5a7958 100644
--- a/app/ui_pc/chat/chat_info.py
+++ b/app/ui_pc/chat/chat_info.py
@@ -1,9 +1,12 @@
+import traceback
+
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QHBoxLayout
-from app.DataBase import msg
+from app.DataBase import msg, hard_link
from app.components.bubble_message import BubbleMessage, ChatWidget, Notice
from app.person import MePC
+from app.util import get_abs_path
class ChatInfo(QWidget):
@@ -84,7 +87,7 @@ class ChatInfo(QWidget):
is_send = message[4]
avatar = MePC().avatar if is_send else self.contact.avatar
timestamp = message[5]
- if type_ == 1 or type_ == 3:
+ if type_ == 1:
if self.is_5_min(timestamp):
time_message = Notice(self.last_str_time)
self.last_str_time = str_time
@@ -96,8 +99,23 @@ class ChatInfo(QWidget):
is_send
)
self.chat_window.add_message_item(bubble_message, 0)
+ elif type_ == 3:
+ if self.is_5_min(timestamp):
+ time_message = Notice(self.last_str_time)
+ self.last_str_time = str_time
+ self.chat_window.add_message_item(time_message, 0)
+ image_path = hard_link.get_image(content=str_content, thumb=False)
+ image_path = get_abs_path(image_path)
+ bubble_message = BubbleMessage(
+ image_path,
+ avatar,
+ type_,
+ is_send
+ )
+ self.chat_window.add_message_item(bubble_message, 0)
except:
print(message)
+ traceback.print_exc()
class ShowChatThread(QThread):
diff --git a/app/ui_pc/mainview.py b/app/ui_pc/mainview.py
index cf2005b..3448422 100644
--- a/app/ui_pc/mainview.py
+++ b/app/ui_pc/mainview.py
@@ -89,7 +89,6 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
me.name = dic.get('name')
me.mobile = dic.get('mobile')
me.wx_dir = dic.get('wx_dir')
-
self.set_my_info(wxid)
else:
QMessageBox.information(
diff --git a/app/util/__init__.py b/app/util/__init__.py
index e69de29..ed49344 100644
--- a/app/util/__init__.py
+++ b/app/util/__init__.py
@@ -0,0 +1 @@
+from .path import get_abs_path
diff --git a/app/util/path.py b/app/util/path.py
new file mode 100644
index 0000000..ab32b28
--- /dev/null
+++ b/app/util/path.py
@@ -0,0 +1,11 @@
+import os
+
+from app.person import MePC
+
+
+def get_abs_path(path):
+ return os.path.join(os.getcwd(), 'app/data/icons/404.png')
+ if path:
+ return os.path.join(MePC().wx_dir, path)
+ else:
+ return os.path.join(os.getcwd(), 'app/data/icons/404.png')
From 13903a1a735a70c14db9d422b1a76b18622bb6ef Mon Sep 17 00:00:00 2001
From: DzhiWang <2429634486@qq.com>
Date: Mon, 20 Nov 2023 23:51:08 +0800
Subject: [PATCH 3/3] add decoding for dat-picture
---
.gitignore | 1 +
app/decrypt/dat2pic.py | 91 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 92 insertions(+)
create mode 100644 app/decrypt/dat2pic.py
diff --git a/.gitignore b/.gitignore
index d8cc5fe..5379ef4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ TEST
app/data/avatar
app/data/image2
app/data/emoji
+app/DataBase/Msg/*
*.db
*.pyc
*.log
diff --git a/app/decrypt/dat2pic.py b/app/decrypt/dat2pic.py
new file mode 100644
index 0000000..f66abd6
--- /dev/null
+++ b/app/decrypt/dat2pic.py
@@ -0,0 +1,91 @@
+
+import os
+# 图片字节头信息,
+# [0][1]为jpg头信息,
+# [2][3]为png头信息,
+# [4][5]为gif头信息
+pic_head = [0xff, 0xd8, 0x89, 0x50, 0x47, 0x49]
+# 解密码
+decode_code = 0
+
+
+def get_code(file_path):
+ """
+ 自动判断文件类型,并获取dat文件解密码
+ :param file_path: dat文件路径
+ :return: 如果文件为jpg/png/gif格式,则返回解密码,否则返回-1
+ """
+ if os.path.isdir(file_path):
+ return -1, -1
+ if file_path[-4:] != ".dat":
+ return -1, -1
+ dat_file = open(file_path, "rb")
+ dat_read = dat_file.read(2)
+ print(dat_read)
+ head_index = 0
+ while head_index < len(pic_head):
+ # 使用第一个头信息字节来计算加密码
+ # 第二个字节来验证解密码是否正确
+ code = dat_read[0] ^ pic_head[head_index]
+ idf_code = dat_read[1] ^ code
+ head_index = head_index + 1
+ if idf_code == pic_head[head_index]:
+ dat_file.close()
+ return head_index, code
+ head_index = head_index + 1
+
+ print("not jpg, png, gif")
+ return -1, -1
+
+
+def decode_dat(file_path, out_path):
+ """
+ 解密文件,并生成图片
+ :param file_path: dat文件路径
+ :return: 无
+ """
+ file_type, decode_code = get_code(file_path)
+
+ if decode_code == -1:
+ return
+ if file_type == 1:
+ pic_name = file_path.split("\\")[-1][:-4] + ".jpg"
+ elif file_type == 3:
+ pic_name = file_path[:-4] + ".png"
+ elif file_type == 5:
+ pic_name = file_path[:-4] + ".gif"
+ else:
+ pic_name = file_path[:-4] + ".jpg"
+
+ dat_file = open(file_path, "rb")
+ file_outpath = os.path.join(out_path, pic_name)
+ print(pic_name)
+ print(file_outpath)
+ pic_write = open(file_outpath, "wb")
+ for dat_data in dat_file:
+ for dat_byte in dat_data:
+ pic_data = dat_byte ^ decode_code
+ pic_write.write(bytes([pic_data]))
+ print(pic_name + "完成")
+ dat_file.close()
+ pic_write.close()
+
+
+def find_datfile(dir_path, out_path):
+ """
+ 获取dat文件目录下所有的文件
+ :param dir_path: dat文件目录
+ :return: 无
+ """
+ files_list = os.listdir(dir_path)
+ for file_name in files_list:
+ file_path = dir_path + "\\" + file_name
+ decode_dat(file_path, out_path)
+
+
+if __name__ == "__main__":
+ path = r"D:\download\wechat\WeChat Files\wxid_0o18ef858vnu22\FileStorage\MsgAttach\febd8caf62dd403a7212aef63fd55910\Thumb\2023-11"
+ outpath = "D:\\test"
+ if not os.path.exists(outpath):
+ os.mkdir(outpath)
+ find_datfile(path, outpath)
\ No newline at end of file