mirror of
https://github.com/LC044/WeChatMsg
synced 2025-02-22 19:02:17 +08:00
新增手动获取基址
This commit is contained in:
parent
8f16ef5e60
commit
c7995ca776
@ -1,77 +1,9 @@
|
||||
import os
|
||||
from collections import Counter
|
||||
|
||||
from PyQt5.QtCore import QFile, QTextStream, QIODevice
|
||||
|
||||
import sys
|
||||
|
||||
sys.path.append('.')
|
||||
|
||||
from app.DataBase import msg_db, MsgType
|
||||
from pyecharts import options as opts
|
||||
from pyecharts.charts import WordCloud, Calendar, Bar, Line
|
||||
from app.resources import resource_rc
|
||||
|
||||
var = resource_rc.qt_resource_name
|
||||
charts_width = 800
|
||||
charts_height = 450
|
||||
wordcloud_width = 780
|
||||
wordcloud_height = 720
|
||||
|
||||
|
||||
def wordcloud(wxid, is_Annual_report=False, year='2023', who='1'):
|
||||
import jieba
|
||||
txt_messages = msg_db.get_messages_by_type(wxid, MsgType.TEXT, year)
|
||||
if not txt_messages:
|
||||
return {
|
||||
'chart_data': None,
|
||||
'keyword': "没有聊天你想分析啥",
|
||||
'max_num': "0",
|
||||
'dialogs': []
|
||||
}
|
||||
# text = ''.join(map(lambda x: x[7], txt_messages))
|
||||
text = ''.join(map(lambda x: x[7] if x[4] == int(who) else '', txt_messages)) # 1“我”说的话,0“Ta”说的话
|
||||
|
||||
total_msg_len = len(text)
|
||||
# 使用jieba进行分词,并加入停用词
|
||||
words = jieba.cut(text)
|
||||
# 统计词频
|
||||
word_count = Counter(words)
|
||||
# 过滤停用词
|
||||
stopwords_file = './app000/data/stopwords.txt'
|
||||
try:
|
||||
with open(stopwords_file, "r", encoding="utf-8") as stopword_file:
|
||||
stopwords = set(stopword_file.read().splitlines())
|
||||
except:
|
||||
file = QFile(':/data/stopwords.txt')
|
||||
if file.open(QIODevice.ReadOnly | QIODevice.Text):
|
||||
stream = QTextStream(file)
|
||||
stream.setCodec('utf-8')
|
||||
content = stream.readAll()
|
||||
file.close()
|
||||
stopwords = set(content.splitlines())
|
||||
filtered_word_count = {word: count for word, count in word_count.items() if len(word) > 1 and word not in stopwords}
|
||||
|
||||
# 转换为词云数据格式
|
||||
data = [(word, count) for word, count in filtered_word_count.items()]
|
||||
# text_data = data
|
||||
data.sort(key=lambda x: x[1], reverse=True)
|
||||
|
||||
text_data = data[:100] if len(data) > 100 else data
|
||||
# 创建词云图
|
||||
keyword, max_num = text_data[0]
|
||||
w = (
|
||||
WordCloud(init_opts=opts.InitOpts(width=f"{wordcloud_width}px", height=f"{wordcloud_height}px"))
|
||||
.add(series_name="聊天文字", data_pair=text_data, word_size_range=[5, 40])
|
||||
)
|
||||
# return w.render_embed()
|
||||
return {
|
||||
'chart_data': w.dump_options_with_quotes(),
|
||||
'keyword': keyword,
|
||||
'max_num': str(max_num),
|
||||
'dialogs': msg_db.get_messages_by_keyword(wxid, keyword, num=5, max_len=12)
|
||||
}
|
||||
|
||||
|
||||
def wordcloud_(wxid, time_range=None):
|
||||
import jieba
|
||||
@ -115,7 +47,7 @@ def wordcloud_(wxid, time_range=None):
|
||||
# 创建词云图
|
||||
keyword, max_num = text_data[0]
|
||||
w = (
|
||||
WordCloud(init_opts=opts.InitOpts(width=f"{wordcloud_width}px", height=f"{wordcloud_height}px"))
|
||||
WordCloud(init_opts=opts.InitOpts())
|
||||
.add(series_name="聊天文字", data_pair=text_data, word_size_range=[5, 100])
|
||||
)
|
||||
# return w.render_embed()
|
||||
@ -267,7 +199,7 @@ def hour_count(wxid, is_Annual_report=False, year='2023'):
|
||||
y_data = list(map(lambda x: x[1], msg_data))
|
||||
x_axis = list(map(lambda x: x[0], msg_data))
|
||||
h = (
|
||||
Line(init_opts=opts.InitOpts(width=f"{charts_width}px", height=f"{charts_height}px"))
|
||||
Line(init_opts=opts.InitOpts())
|
||||
.add_xaxis(xaxis_data=x_axis)
|
||||
.add_yaxis(
|
||||
series_name="聊天频率",
|
||||
|
272
app/decrypt/get_bias_addr.py
Normal file
272
app/decrypt/get_bias_addr.py
Normal file
@ -0,0 +1,272 @@
|
||||
# -*- coding: utf-8 -*-#
|
||||
# -------------------------------------------------------------------------------
|
||||
# Name: get_base_addr.py
|
||||
# Description:
|
||||
# Author: xaoyaoo
|
||||
# Date: 2023/08/22
|
||||
# -------------------------------------------------------------------------------
|
||||
import argparse
|
||||
import ctypes
|
||||
import hashlib
|
||||
import json
|
||||
import multiprocessing
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
import psutil
|
||||
from win32com.client import Dispatch
|
||||
from pymem import Pymem
|
||||
import pymem
|
||||
import hmac
|
||||
|
||||
ReadProcessMemory = ctypes.windll.kernel32.ReadProcessMemory
|
||||
void_p = ctypes.c_void_p
|
||||
KEY_SIZE = 32
|
||||
DEFAULT_PAGESIZE = 4096
|
||||
DEFAULT_ITER = 64000
|
||||
|
||||
|
||||
def validate_key(key, salt, first, mac_salt):
|
||||
byteKey = hashlib.pbkdf2_hmac("sha1", key, salt, DEFAULT_ITER, KEY_SIZE)
|
||||
mac_key = hashlib.pbkdf2_hmac("sha1", byteKey, mac_salt, 2, KEY_SIZE)
|
||||
hash_mac = hmac.new(mac_key, first[:-32], hashlib.sha1)
|
||||
hash_mac.update(b'\x01\x00\x00\x00')
|
||||
|
||||
if hash_mac.digest() == first[-32:-12]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def get_exe_bit(file_path):
|
||||
"""
|
||||
获取 PE 文件的位数: 32 位或 64 位
|
||||
:param file_path: PE 文件路径(可执行文件)
|
||||
:return: 如果遇到错误则返回 64
|
||||
"""
|
||||
try:
|
||||
with open(file_path, 'rb') as f:
|
||||
dos_header = f.read(2)
|
||||
if dos_header != b'MZ':
|
||||
print('get exe bit error: Invalid PE file')
|
||||
return 64
|
||||
# Seek to the offset of the PE signature
|
||||
f.seek(60)
|
||||
pe_offset_bytes = f.read(4)
|
||||
pe_offset = int.from_bytes(pe_offset_bytes, byteorder='little')
|
||||
|
||||
# Seek to the Machine field in the PE header
|
||||
f.seek(pe_offset + 4)
|
||||
machine_bytes = f.read(2)
|
||||
machine = int.from_bytes(machine_bytes, byteorder='little')
|
||||
|
||||
if machine == 0x14c:
|
||||
return 32
|
||||
elif machine == 0x8664:
|
||||
return 64
|
||||
else:
|
||||
print('get exe bit error: Unknown architecture: %s' % hex(machine))
|
||||
return 64
|
||||
except IOError:
|
||||
print('get exe bit error: File not found or cannot be opened')
|
||||
return 64
|
||||
|
||||
|
||||
def get_exe_version(file_path):
|
||||
"""
|
||||
获取 PE 文件的版本号
|
||||
:param file_path: PE 文件路径(可执行文件)
|
||||
:return: 如果遇到错误则返回
|
||||
"""
|
||||
file_version = Dispatch("Scripting.FileSystemObject").GetFileVersion(file_path)
|
||||
return file_version
|
||||
|
||||
|
||||
def find_all(c: bytes, string: bytes, base_addr=0):
|
||||
"""
|
||||
查找字符串中所有子串的位置
|
||||
:param c: 子串 b'123'
|
||||
:param string: 字符串 b'123456789123'
|
||||
:return:
|
||||
"""
|
||||
return [base_addr + m.start() for m in re.finditer(re.escape(c), string)]
|
||||
|
||||
|
||||
class BiasAddr:
|
||||
def __init__(self, account, mobile, name, key, db_path):
|
||||
self.account = account.encode("utf-8")
|
||||
self.mobile = mobile.encode("utf-8")
|
||||
self.name = name.encode("utf-8")
|
||||
self.key = bytes.fromhex(key) if key else b""
|
||||
self.db_path = db_path if db_path and os.path.exists(db_path) else ""
|
||||
|
||||
self.process_name = "WeChat.exe"
|
||||
self.module_name = "WeChatWin.dll"
|
||||
|
||||
self.pm = None # Pymem 对象
|
||||
self.is_WoW64 = None # True: 32位进程运行在64位系统上 False: 64位进程运行在64位系统上
|
||||
self.process_handle = None # 进程句柄
|
||||
self.pid = None # 进程ID
|
||||
self.version = None # 微信版本号
|
||||
self.process = None # 进程对象
|
||||
self.exe_path = None # 微信路径
|
||||
self.address_len = None # 4 if self.bits == 32 else 8 # 4字节或8字节
|
||||
self.bits = 64 if sys.maxsize > 2 ** 32 else 32 # 系统:32位或64位
|
||||
|
||||
def get_process_handle(self):
|
||||
try:
|
||||
self.pm = Pymem(self.process_name)
|
||||
self.pm.check_wow64()
|
||||
self.is_WoW64 = self.pm.is_WoW64
|
||||
self.process_handle = self.pm.process_handle
|
||||
self.pid = self.pm.process_id
|
||||
self.process = psutil.Process(self.pid)
|
||||
self.exe_path = self.process.exe()
|
||||
self.version = get_exe_version(self.exe_path)
|
||||
|
||||
version_nums = list(map(int, self.version.split("."))) # 将版本号拆分为数字列表
|
||||
if version_nums[0] <= 3 and version_nums[1] <= 9 and version_nums[2] <= 2:
|
||||
self.address_len = 4
|
||||
else:
|
||||
self.address_len = 8
|
||||
return True, ""
|
||||
except pymem.exception.ProcessNotFound:
|
||||
return False, "[-] WeChat No Run"
|
||||
|
||||
def search_memory_value(self, value: bytes, module_name="WeChatWin.dll"):
|
||||
# 创建 Pymem 对象
|
||||
module = pymem.process.module_from_name(self.pm.process_handle, module_name)
|
||||
ret = self.pm.pattern_scan_module(value, module, return_multiple=True)
|
||||
ret = ret[-1] - module.lpBaseOfDll if len(ret) > 0 else 0
|
||||
return ret
|
||||
|
||||
def get_key_bias1(self):
|
||||
try:
|
||||
byteLen = self.address_len # 4 if self.bits == 32 else 8 # 4字节或8字节
|
||||
|
||||
keyLenOffset = 0x8c if self.bits == 32 else 0xd0
|
||||
keyWindllOffset = 0x90 if self.bits == 32 else 0xd8
|
||||
|
||||
module = pymem.process.module_from_name(self.process_handle, self.module_name)
|
||||
keyBytes = b'-----BEGIN PUBLIC KEY-----\n...'
|
||||
publicKeyList = pymem.pattern.pattern_scan_all(self.process_handle, keyBytes, return_multiple=True)
|
||||
|
||||
keyaddrs = []
|
||||
for addr in publicKeyList:
|
||||
keyBytes = addr.to_bytes(byteLen, byteorder="little", signed=True) # 低位在前
|
||||
may_addrs = pymem.pattern.pattern_scan_module(self.process_handle, module, keyBytes,
|
||||
return_multiple=True)
|
||||
if may_addrs != 0 and len(may_addrs) > 0:
|
||||
for addr in may_addrs:
|
||||
keyLen = self.pm.read_uchar(addr - keyLenOffset)
|
||||
if keyLen != 32:
|
||||
continue
|
||||
keyaddrs.append(addr - keyWindllOffset)
|
||||
|
||||
return keyaddrs[-1] - module.lpBaseOfDll if len(keyaddrs) > 0 else 0
|
||||
except:
|
||||
return 0
|
||||
|
||||
def search_key(self, key: bytes):
|
||||
key = re.escape(key) # 转义特殊字符
|
||||
key_addr = self.pm.pattern_scan_all(key, return_multiple=False)
|
||||
key = key_addr.to_bytes(self.address_len, byteorder='little', signed=True)
|
||||
result = self.search_memory_value(key, self.module_name)
|
||||
return result
|
||||
|
||||
def get_key_bias2(self, wx_db_path):
|
||||
|
||||
addr_len = get_exe_bit(self.exe_path) // 8
|
||||
db_path = wx_db_path
|
||||
|
||||
def read_key_bytes(h_process, address, address_len=8):
|
||||
array = ctypes.create_string_buffer(address_len)
|
||||
if ReadProcessMemory(h_process, void_p(address), array, address_len, 0) == 0: return "None"
|
||||
address = int.from_bytes(array, byteorder='little') # 逆序转换为int地址(key地址)
|
||||
key = ctypes.create_string_buffer(32)
|
||||
if ReadProcessMemory(h_process, void_p(address), key, 32, 0) == 0: return "None"
|
||||
key_bytes = bytes(key)
|
||||
return key_bytes
|
||||
|
||||
def verify_key(key, wx_db_path):
|
||||
KEY_SIZE = 32
|
||||
DEFAULT_PAGESIZE = 4096
|
||||
DEFAULT_ITER = 64000
|
||||
with open(wx_db_path, "rb") as file:
|
||||
blist = file.read(5000)
|
||||
salt = blist[:16]
|
||||
byteKey = hashlib.pbkdf2_hmac("sha1", key, salt, DEFAULT_ITER, KEY_SIZE)
|
||||
first = blist[16:DEFAULT_PAGESIZE]
|
||||
|
||||
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, first[:-32], hashlib.sha1)
|
||||
hash_mac.update(b'\x01\x00\x00\x00')
|
||||
|
||||
if hash_mac.digest() != first[-32:-12]:
|
||||
return False
|
||||
return True
|
||||
|
||||
phone_type1 = "iphone\x00"
|
||||
phone_type2 = "android\x00"
|
||||
phone_type3 = "ipad\x00"
|
||||
|
||||
pm = pymem.Pymem("WeChat.exe")
|
||||
module_name = "WeChatWin.dll"
|
||||
|
||||
MicroMsg_path = os.path.join(db_path, "MSG", "MicroMsg.db")
|
||||
|
||||
module = pymem.process.module_from_name(pm.process_handle, module_name)
|
||||
|
||||
type1_addrs = pm.pattern_scan_module(phone_type1.encode(), module, return_multiple=True)
|
||||
type2_addrs = pm.pattern_scan_module(phone_type2.encode(), module, return_multiple=True)
|
||||
type3_addrs = pm.pattern_scan_module(phone_type3.encode(), module, return_multiple=True)
|
||||
type_addrs = type1_addrs if len(type1_addrs) >= 2 else type2_addrs if len(
|
||||
type2_addrs) >= 2 else type3_addrs if len(type3_addrs) >= 2 else "None"
|
||||
if type_addrs == "None":
|
||||
return 0
|
||||
for i in type_addrs[::-1]:
|
||||
for j in range(i, i - 2000, -addr_len):
|
||||
key_bytes = read_key_bytes(pm.process_handle, j, addr_len)
|
||||
if key_bytes == "None":
|
||||
continue
|
||||
if verify_key(key_bytes, MicroMsg_path):
|
||||
return j - module.lpBaseOfDll
|
||||
return 0
|
||||
|
||||
def run(self, logging_path=False, version_list_path=None):
|
||||
if not self.get_process_handle()[0]:
|
||||
return None
|
||||
mobile_bias = self.search_memory_value(self.mobile, self.module_name)
|
||||
name_bias = self.search_memory_value(self.name, self.module_name)
|
||||
account_bias = self.search_memory_value(self.account, self.module_name)
|
||||
key_bias = 0
|
||||
key_bias = self.get_key_bias1()
|
||||
key_bias = self.search_key(self.key) if key_bias <= 0 and self.key else key_bias
|
||||
key_bias = self.get_key_bias2(self.db_path) if key_bias <= 0 and self.db_path else key_bias
|
||||
|
||||
rdata = {self.version: [name_bias, account_bias, mobile_bias, 0, key_bias]}
|
||||
|
||||
if version_list_path and os.path.exists(version_list_path):
|
||||
with open(version_list_path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
data.update(rdata)
|
||||
with open(version_list_path, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=4)
|
||||
if os.path.exists(logging_path) and isinstance(logging_path, str):
|
||||
with open(logging_path, "a", encoding="utf-8") as f:
|
||||
f.write("{版本号:昵称,账号,手机号,邮箱,KEY}" + "\n")
|
||||
f.write(str(rdata) + "\n")
|
||||
elif logging_path:
|
||||
print("{版本号:昵称,账号,手机号,邮箱,KEY}")
|
||||
print(rdata)
|
||||
return rdata
|
||||
|
||||
|
||||
def get_info_without_key(h_process, address, n_size=64):
|
||||
array = ctypes.create_string_buffer(n_size)
|
||||
if ReadProcessMemory(h_process, void_p(address), array, n_size, 0) == 0: return "None"
|
||||
array = bytes(array).split(b"\x00")[0] if b"\x00" in array else bytes(array)
|
||||
text = array.decode('utf-8', errors='ignore')
|
||||
return text.strip() if text.strip() != "" else "None"
|
206
app/ui/tool/get_bias_addr/getBiasAddrUi.py
Normal file
206
app/ui/tool/get_bias_addr/getBiasAddrUi.py
Normal file
@ -0,0 +1,206 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'getBiasAddrUi.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.10
|
||||
#
|
||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||
# run again. Do not edit this file unless you know what you are doing.
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_Form(object):
|
||||
def setupUi(self, Form):
|
||||
Form.setObjectName("Form")
|
||||
Form.resize(650, 580)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(Form)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.scrollArea = QtWidgets.QScrollArea(Form)
|
||||
self.scrollArea.setFrameShape(QtWidgets.QFrame.NoFrame)
|
||||
self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||
self.scrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||
self.scrollArea.setWidgetResizable(True)
|
||||
self.scrollArea.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
|
||||
self.scrollArea.setObjectName("scrollArea")
|
||||
self.scrollAreaWidgetContents = QtWidgets.QWidget()
|
||||
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 632, 562))
|
||||
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
|
||||
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
|
||||
self.verticalLayout_3.setObjectName("verticalLayout_3")
|
||||
self.label_4 = QtWidgets.QLabel(self.scrollAreaWidgetContents)
|
||||
self.label_4.setMaximumSize(QtCore.QSize(16777215, 20))
|
||||
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_4.setObjectName("label_4")
|
||||
self.verticalLayout_3.addWidget(self.label_4)
|
||||
self.widget = QtWidgets.QWidget(self.scrollAreaWidgetContents)
|
||||
self.widget.setStyleSheet("QWidget{\n"
|
||||
" background-color:rgb(251,251,251);\n"
|
||||
" border-radius: 10px;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"QPushButton{\n"
|
||||
" background-color: rgb(250,252,253);\n"
|
||||
" border-radius: 5px;\n"
|
||||
" padding: 8px;\n"
|
||||
" border-right: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||
" border-bottom: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||
" border-left: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||
" border-top: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||
"}\n"
|
||||
"QPushButton:hover { \n"
|
||||
" background-color: lightgray;\n"
|
||||
"}")
|
||||
self.widget.setObjectName("widget")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.label = QtWidgets.QLabel(self.widget)
|
||||
self.label.setMinimumSize(QtCore.QSize(80, 0))
|
||||
self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label.setObjectName("label")
|
||||
self.horizontalLayout.addWidget(self.label)
|
||||
self.lineEdit_tel = QtWidgets.QLineEdit(self.widget)
|
||||
self.lineEdit_tel.setObjectName("lineEdit_tel")
|
||||
self.horizontalLayout.addWidget(self.lineEdit_tel)
|
||||
self.verticalLayout_3.addWidget(self.widget)
|
||||
self.widget_3 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
|
||||
self.widget_3.setStyleSheet("QWidget{\n"
|
||||
" background-color:rgb(251,251,251);\n"
|
||||
" border-radius: 10px;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"QPushButton{\n"
|
||||
" background-color: rgb(250,252,253);\n"
|
||||
" border-radius: 5px;\n"
|
||||
" padding: 8px;\n"
|
||||
" border-right: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||
" border-bottom: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||
" border-left: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||
" border-top: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||
"}\n"
|
||||
"QPushButton:hover { \n"
|
||||
" background-color: lightgray;\n"
|
||||
"}")
|
||||
self.widget_3.setObjectName("widget_3")
|
||||
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.widget_3)
|
||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||
self.label_2 = QtWidgets.QLabel(self.widget_3)
|
||||
self.label_2.setMinimumSize(QtCore.QSize(80, 0))
|
||||
self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.horizontalLayout_3.addWidget(self.label_2)
|
||||
self.lineEdit_wx_alias = QtWidgets.QLineEdit(self.widget_3)
|
||||
self.lineEdit_wx_alias.setObjectName("lineEdit_wx_alias")
|
||||
self.horizontalLayout_3.addWidget(self.lineEdit_wx_alias)
|
||||
self.verticalLayout_3.addWidget(self.widget_3)
|
||||
self.widget_4 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
|
||||
self.widget_4.setStyleSheet("QWidget{\n"
|
||||
" background-color:rgb(251,251,251);\n"
|
||||
" border-radius: 10px;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"QPushButton{\n"
|
||||
" background-color: rgb(250,252,253);\n"
|
||||
" border-radius: 5px;\n"
|
||||
" padding: 8px;\n"
|
||||
" border-right: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||
" border-bottom: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||
" border-left: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||
" border-top: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||
"}\n"
|
||||
"QPushButton:hover { \n"
|
||||
" background-color: lightgray;\n"
|
||||
"}")
|
||||
self.widget_4.setObjectName("widget_4")
|
||||
self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.widget_4)
|
||||
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
|
||||
self.label_3 = QtWidgets.QLabel(self.widget_4)
|
||||
self.label_3.setMinimumSize(QtCore.QSize(80, 0))
|
||||
self.label_3.setLayoutDirection(QtCore.Qt.LeftToRight)
|
||||
self.label_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.horizontalLayout_4.addWidget(self.label_3)
|
||||
self.lineEdit_wx_name = QtWidgets.QLineEdit(self.widget_4)
|
||||
self.lineEdit_wx_name.setObjectName("lineEdit_wx_name")
|
||||
self.horizontalLayout_4.addWidget(self.lineEdit_wx_name)
|
||||
self.verticalLayout_3.addWidget(self.widget_4)
|
||||
self.btn_get_bias_addr = QtWidgets.QPushButton(self.scrollAreaWidgetContents)
|
||||
self.btn_get_bias_addr.setObjectName("btn_get_bias_addr")
|
||||
self.verticalLayout_3.addWidget(self.btn_get_bias_addr)
|
||||
self.widget_2 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
|
||||
self.widget_2.setStyleSheet("QWidget{\n"
|
||||
" background-color:rgb(251,251,251);\n"
|
||||
" border-radius: 10px;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"QPushButton{\n"
|
||||
" background-color: rgb(250,252,253);\n"
|
||||
" border-radius: 5px;\n"
|
||||
" padding: 8px;\n"
|
||||
" border-right: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||
" border-bottom: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||
" border-left: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||
" border-top: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||
"}\n"
|
||||
"QPushButton:hover { \n"
|
||||
" background-color: lightgray;\n"
|
||||
"}")
|
||||
self.widget_2.setObjectName("widget_2")
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.widget_2)
|
||||
self.horizontalLayout_2.setContentsMargins(9, -1, -1, -1)
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.commandLinkButton = QtWidgets.QCommandLinkButton(self.widget_2)
|
||||
self.commandLinkButton.setEnabled(True)
|
||||
self.commandLinkButton.setTabletTracking(False)
|
||||
self.commandLinkButton.setFocusPolicy(QtCore.Qt.StrongFocus)
|
||||
self.commandLinkButton.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
|
||||
self.commandLinkButton.setToolTipDuration(-1)
|
||||
self.commandLinkButton.setLayoutDirection(QtCore.Qt.LeftToRight)
|
||||
self.commandLinkButton.setAutoFillBackground(False)
|
||||
self.commandLinkButton.setCheckable(False)
|
||||
self.commandLinkButton.setChecked(False)
|
||||
self.commandLinkButton.setAutoRepeat(False)
|
||||
self.commandLinkButton.setAutoExclusive(False)
|
||||
self.commandLinkButton.setAutoDefault(False)
|
||||
self.commandLinkButton.setDefault(False)
|
||||
self.commandLinkButton.setObjectName("commandLinkButton")
|
||||
self.horizontalLayout_2.addWidget(self.commandLinkButton)
|
||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_2.addItem(spacerItem)
|
||||
self.label_error_log = QtWidgets.QLabel(self.widget_2)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_error_log.sizePolicy().hasHeightForWidth())
|
||||
self.label_error_log.setSizePolicy(sizePolicy)
|
||||
self.label_error_log.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_error_log.setObjectName("label_error_log")
|
||||
self.horizontalLayout_2.addWidget(self.label_error_log)
|
||||
self.checkBox_send_error_log = QtWidgets.QCheckBox(self.widget_2)
|
||||
self.checkBox_send_error_log.setText("")
|
||||
self.checkBox_send_error_log.setIconSize(QtCore.QSize(64, 64))
|
||||
self.checkBox_send_error_log.setChecked(True)
|
||||
self.checkBox_send_error_log.setObjectName("checkBox_send_error_log")
|
||||
self.horizontalLayout_2.addWidget(self.checkBox_send_error_log)
|
||||
self.verticalLayout_3.addWidget(self.widget_2)
|
||||
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
|
||||
self.verticalLayout.addWidget(self.scrollArea)
|
||||
|
||||
self.retranslateUi(Form)
|
||||
QtCore.QMetaObject.connectSlotsByName(Form)
|
||||
|
||||
def retranslateUi(self, Form):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
Form.setWindowTitle(_translate("Form", "Form"))
|
||||
self.label_4.setText(_translate("Form", "为避免输入错误,下面信息请从微信里复制"))
|
||||
self.label.setText(_translate("Form", "手机号:"))
|
||||
self.lineEdit_tel.setPlaceholderText(_translate("Form", "填入微信绑定的手机号"))
|
||||
self.label_2.setText(_translate("Form", "微信号:"))
|
||||
self.lineEdit_wx_alias.setPlaceholderText(_translate("Form", "填入您的微信号"))
|
||||
self.label_3.setText(_translate("Form", "微信昵称:"))
|
||||
self.lineEdit_wx_name.setPlaceholderText(_translate("Form", "填入您的微信昵称"))
|
||||
self.btn_get_bias_addr.setText(_translate("Form", "获取信息"))
|
||||
self.commandLinkButton.setText(_translate("Form", "收集版本信息"))
|
||||
self.commandLinkButton.setDescription(_translate("Form", "需要收集微信版本信息以支持更多用户"))
|
||||
self.label_error_log.setText(_translate("Form", "开"))
|
145
app/ui/tool/get_bias_addr/get_bias_addr.py
Normal file
145
app/ui/tool/get_bias_addr/get_bias_addr.py
Normal file
@ -0,0 +1,145 @@
|
||||
import json
|
||||
import os.path
|
||||
|
||||
import requests
|
||||
from PyQt5.QtCore import pyqtSignal, QThread
|
||||
from PyQt5.QtWidgets import QWidget, QMessageBox
|
||||
|
||||
from app.components.QCursorGif import QCursorGif
|
||||
from app.decrypt.get_bias_addr import BiasAddr
|
||||
from .getBiasAddrUi import Ui_Form
|
||||
|
||||
Stylesheet = """
|
||||
QPushButton{
|
||||
background-color: rgb(250,252,253);
|
||||
border-radius: 5px;
|
||||
padding: 8px;
|
||||
border-right: 2px solid #888888; /* 按钮边框,2px宽,白色 */
|
||||
border-bottom: 2px solid #888888; /* 按钮边框,2px宽,白色 */
|
||||
border-left: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */
|
||||
border-top: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: lightgray;
|
||||
}
|
||||
/*去掉item虚线边框*/
|
||||
QListWidget, QListView, QTreeWidget, QTreeView {
|
||||
outline: 0px;
|
||||
border:none;
|
||||
}
|
||||
/*设置左侧选项的最小最大宽度,文字颜色和背景颜色*/
|
||||
QListWidget {
|
||||
min-width: 400px;
|
||||
max-width: 400px;
|
||||
min-height: 80px;
|
||||
max-height: 80px;
|
||||
color: black;
|
||||
border:none;
|
||||
}
|
||||
QListWidget::item{
|
||||
min-width: 80px;
|
||||
max-width: 400px;
|
||||
min-height: 80px;
|
||||
max-height: 80px;
|
||||
}
|
||||
/*被选中时的背景颜色和左边框颜色*/
|
||||
QListWidget::item:selected {
|
||||
border-left:none;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
QCheckBox::indicator {
|
||||
background: rgb(251, 251, 251);
|
||||
Width:60px;
|
||||
Height:60px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
QCheckBox::indicator:unchecked{
|
||||
Width:60px;
|
||||
Height:60px;
|
||||
image: url(:/icons/icons/按钮_关闭.svg);
|
||||
}
|
||||
QCheckBox::indicator:checked{
|
||||
Width:60px;
|
||||
Height:60px;
|
||||
image: url(:/icons/icons/按钮_开启.svg);
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class GetBiasAddrControl(QWidget, Ui_Form, QCursorGif):
|
||||
biasAddrSignal = pyqtSignal(dict)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(GetBiasAddrControl, self).__init__(parent)
|
||||
self.thread = None
|
||||
self.setStyleSheet(Stylesheet)
|
||||
self.setupUi(self)
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
self.initCursor([':/icons/icons/Cursors/%d.png' %
|
||||
i for i in range(8)], self)
|
||||
self.setCursorTimeout(100)
|
||||
self.btn_get_bias_addr.clicked.connect(self.get_bias_addr)
|
||||
self.commandLinkButton.clicked.connect(self.show_info)
|
||||
self.checkBox_send_error_log.clicked.connect(self.set_error_log)
|
||||
|
||||
def set_error_log(self):
|
||||
if self.checkBox_send_error_log.isChecked():
|
||||
self.label_error_log.setText('开')
|
||||
else:
|
||||
self.label_error_log.setText('关')
|
||||
|
||||
def show_info(self):
|
||||
QMessageBox.information(self, "收集版本信息",
|
||||
"为了适配更多版本,需要收集微信的版本信息,该操作不会上传包括手机号、微信号、昵称等在内的任何信息\n示例数据:\n\"3.9.9.27\": [68065304, 0, 68065112, 0, 68066576]"
|
||||
)
|
||||
|
||||
def upload(self, version_data):
|
||||
url = "http://api.lc044.love/wxBiasAddr"
|
||||
try:
|
||||
requests.post(url, json=version_data)
|
||||
print('版本信息上传成功')
|
||||
except:
|
||||
pass
|
||||
|
||||
def get_bias_addr(self):
|
||||
|
||||
account = self.lineEdit_wx_alias.text()
|
||||
mobile = self.lineEdit_tel.text()
|
||||
name = self.lineEdit_wx_name.text()
|
||||
if not all([account, mobile, name]):
|
||||
QMessageBox.critical(self, "错误",
|
||||
"请把所有信息填写完整")
|
||||
return
|
||||
key = None
|
||||
db_path = "test"
|
||||
self.startBusy()
|
||||
self.thread = MyThread(account, mobile, name, key, db_path)
|
||||
self.thread.signal.connect(self.set_bias_addr)
|
||||
self.thread.start()
|
||||
|
||||
def set_bias_addr(self, data):
|
||||
if self.checkBox_send_error_log.isChecked():
|
||||
self.upload(data)
|
||||
self.stopBusy()
|
||||
self.biasAddrSignal.emit(data)
|
||||
|
||||
|
||||
class MyThread(QThread):
|
||||
signal = pyqtSignal(dict)
|
||||
|
||||
def __init__(self, account, mobile, name, key, db_path):
|
||||
super(MyThread, self).__init__()
|
||||
self.account = account
|
||||
self.mobile = mobile
|
||||
self.name = name
|
||||
self.key = key
|
||||
self.db_path = db_path
|
||||
|
||||
def run(self):
|
||||
bias_addr = BiasAddr(self.account, self.mobile, self.name, self.key, self.db_path)
|
||||
data = bias_addr.run(logging_path=True)
|
||||
self.signal.emit(data)
|
@ -21,14 +21,17 @@ from ...Icon import Icon
|
||||
class DecryptControl(QWidget, decryptUi.Ui_Dialog, QCursorGif):
|
||||
DecryptSignal = pyqtSignal(bool)
|
||||
get_wxidSignal = pyqtSignal(str)
|
||||
versionErrorSignal = pyqtSignal(str)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(DecryptControl, self).__init__(parent)
|
||||
self.max_val = 0
|
||||
self.setupUi(self)
|
||||
# 设置忙碌光标图片数组
|
||||
self.initCursor([':/icons/icons/Cursors/%d.png' %
|
||||
i for i in range(8)], self)
|
||||
self.setCursorTimeout(100)
|
||||
self.version_list = None
|
||||
self.btn_start.clicked.connect(self.decrypt)
|
||||
self.btn_getinfo.clicked.connect(self.get_info)
|
||||
self.btn_db_dir.clicked.connect(self.select_db_dir)
|
||||
@ -53,7 +56,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog, QCursorGif):
|
||||
# @log
|
||||
def get_info(self):
|
||||
self.startBusy()
|
||||
self.get_info_thread = MyThread()
|
||||
self.get_info_thread = MyThread(self.version_list)
|
||||
self.get_info_thread.signal.connect(self.set_info)
|
||||
self.get_info_thread.start()
|
||||
|
||||
@ -62,8 +65,10 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog, QCursorGif):
|
||||
if result[0] == -1:
|
||||
QMessageBox.critical(self, "错误", "请登录微信")
|
||||
elif result[0] == -2:
|
||||
self.versionErrorSignal.emit(result[1])
|
||||
QMessageBox.critical(self, "错误",
|
||||
"微信版本不匹配\n请更新微信版本为:3.9.9.27(去微信官网下载)\n或更新本软件")
|
||||
"微信版本不匹配\n请手动填写信息")
|
||||
|
||||
elif result[0] == -3:
|
||||
QMessageBox.critical(self, "错误", "WeChat WeChatWin.dll Not Found")
|
||||
elif result[0] == -10086:
|
||||
@ -151,11 +156,12 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog, QCursorGif):
|
||||
# print("enter clicked")
|
||||
# 中间可以添加处理逻辑
|
||||
# QMessageBox.about(self, "解密成功", "数据库文件存储在app/DataBase/Msg文件夹下")
|
||||
|
||||
self.progressBar_view(self.max_val)
|
||||
self.DecryptSignal.emit(True)
|
||||
# self.close()
|
||||
|
||||
def setProgressBarMaxNum(self, max_val):
|
||||
self.max_val = max_val
|
||||
self.progressBar.setRange(0, max_val)
|
||||
|
||||
def progressBar_view(self, value):
|
||||
@ -184,7 +190,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog, QCursorGif):
|
||||
except:
|
||||
with open('./info.json', 'w', encoding='utf-8') as f:
|
||||
f.write(json.dumps(dic))
|
||||
|
||||
self.progressBar_view(self.max_val)
|
||||
self.DecryptSignal.emit(True)
|
||||
self.close()
|
||||
|
||||
@ -271,8 +277,9 @@ class DecryptThread(QThread):
|
||||
class MyThread(QThread):
|
||||
signal = pyqtSignal(list)
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self,version_list = None):
|
||||
super(MyThread, self).__init__()
|
||||
self.version_list = version_list
|
||||
|
||||
def __del__(self):
|
||||
pass
|
||||
@ -283,8 +290,11 @@ class MyThread(QThread):
|
||||
'version': version
|
||||
}
|
||||
try:
|
||||
response = requests.post(url, json=data)
|
||||
response = requests.get(url, json=data)
|
||||
print(response)
|
||||
print(response.text)
|
||||
if response.status_code == 200:
|
||||
|
||||
update_info = response.json()
|
||||
return update_info
|
||||
else:
|
||||
@ -293,12 +303,15 @@ class MyThread(QThread):
|
||||
return {}
|
||||
|
||||
def run(self):
|
||||
file_path = './app/resources/data/version_list.json'
|
||||
if not os.path.exists(file_path):
|
||||
resource_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
|
||||
file_path = os.path.join(resource_dir, 'app', 'resources', 'data', 'version_list.json')
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
VERSION_LIST = json.loads(f.read())
|
||||
if self.version_list:
|
||||
VERSION_LIST = self.version_list
|
||||
else:
|
||||
file_path = './app/resources/data/version_list.json'
|
||||
if not os.path.exists(file_path):
|
||||
resource_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
|
||||
file_path = os.path.join(resource_dir, 'app', 'resources', 'data', 'version_list.json')
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
VERSION_LIST = json.loads(f.read())
|
||||
try:
|
||||
result = get_wx_info.get_info(VERSION_LIST)
|
||||
if result == -1:
|
||||
@ -313,6 +326,9 @@ class MyThread(QThread):
|
||||
if version_bias.get(version):
|
||||
logger.info(f"从云端获取内存基址:{version_bias}")
|
||||
result = get_wx_info.get_info(version_bias)
|
||||
else:
|
||||
logger.info(f"从云端获取内存基址失败:{version}")
|
||||
result = [-2,version]
|
||||
except:
|
||||
logger.error(traceback.format_exc())
|
||||
result = [-10086]
|
||||
|
@ -78,6 +78,7 @@ class SettingControl(QWidget, Ui_Form):
|
||||
def init_ui(self):
|
||||
self.checkBox.setText('是')
|
||||
self.checkBox_send_error_log.clicked.connect(self.set_error_log)
|
||||
|
||||
def set_error_log(self):
|
||||
if self.checkBox_send_error_log.isChecked():
|
||||
self.label_error_log.setText('开')
|
||||
|
@ -5,6 +5,7 @@ from PyQt5.QtWidgets import QWidget, QListWidgetItem, QLabel
|
||||
from app.ui.Icon import Icon
|
||||
from .pc_decrypt import DecryptControl
|
||||
from .setting.setting import SettingControl
|
||||
from .get_bias_addr.get_bias_addr import GetBiasAddrControl
|
||||
from .toolUI import Ui_Dialog
|
||||
|
||||
# 美化样式表
|
||||
@ -68,14 +69,22 @@ class ToolWindow(QWidget, Ui_Dialog):
|
||||
self.listWidget.currentRowChanged.connect(self.setCurrentIndex)
|
||||
chat_item = QListWidgetItem(Icon.Decrypt_Icon, '解密', self.listWidget)
|
||||
contact_item = QListWidgetItem(Icon.Contact_Icon, '设置', self.listWidget)
|
||||
myinfo_item = QListWidgetItem(Icon.Home_Icon, '别点', self.listWidget)
|
||||
myinfo_item = QListWidgetItem(Icon.Home_Icon, '解密2', self.listWidget)
|
||||
tool_item = QListWidgetItem(Icon.Home_Icon, '别点', self.listWidget)
|
||||
decrypt_window = DecryptControl()
|
||||
decrypt_window.get_wxidSignal.connect(self.get_info_signal)
|
||||
decrypt_window.DecryptSignal.connect(self.decrypt_success_signal)
|
||||
self.stackedWidget.addWidget(decrypt_window)
|
||||
|
||||
self.decrypt_window = DecryptControl()
|
||||
self.decrypt_window.get_wxidSignal.connect(self.get_info_signal)
|
||||
self.decrypt_window.DecryptSignal.connect(self.decrypt_success_signal)
|
||||
self.decrypt_window.versionErrorSignal.connect(self.show_decrypt2)
|
||||
self.stackedWidget.addWidget(self.decrypt_window)
|
||||
|
||||
setting_window = SettingControl()
|
||||
self.stackedWidget.addWidget(setting_window)
|
||||
|
||||
self.get_bias_addr_window = GetBiasAddrControl()
|
||||
self.get_bias_addr_window.biasAddrSignal.connect(self.decrypt)
|
||||
self.stackedWidget.addWidget(self.get_bias_addr_window)
|
||||
|
||||
label = QLabel('都说了不让你点', self)
|
||||
label.setFont(QFont("微软雅黑", 50))
|
||||
label.setAlignment(Qt.AlignCenter)
|
||||
@ -84,10 +93,19 @@ class ToolWindow(QWidget, Ui_Dialog):
|
||||
# label.setStyleSheet('background: rgb(%d, %d, %d);margin: 50px;' % (
|
||||
# randint(0, 255), randint(0, 255), randint(0, 255)))
|
||||
|
||||
self.stackedWidget.addWidget(label)
|
||||
self.stackedWidget.addWidget(label)
|
||||
self.listWidget.setCurrentRow(0)
|
||||
self.stackedWidget.setCurrentIndex(0)
|
||||
|
||||
def decrypt(self, version_list):
|
||||
self.listWidget.setCurrentRow(0)
|
||||
self.stackedWidget.setCurrentIndex(0)
|
||||
self.decrypt_window.version_list = version_list
|
||||
self.decrypt_window.get_info()
|
||||
|
||||
def show_decrypt2(self, version):
|
||||
self.listWidget.setCurrentRow(2)
|
||||
self.stackedWidget.setCurrentIndex(2)
|
||||
|
||||
def setCurrentIndex(self, row):
|
||||
self.stackedWidget.setCurrentIndex(row)
|
||||
|
@ -33,6 +33,7 @@ def get_code(dat_read):
|
||||
return head_index, code
|
||||
head_index = head_index + 1
|
||||
print("not jpg, png, gif")
|
||||
return -1, -1
|
||||
except:
|
||||
logger.error(f'image解析发生了错误:\n\n{traceback.format_exc()}')
|
||||
return -1, -1
|
||||
@ -48,8 +49,8 @@ def decode_dat(file_path, out_path):
|
||||
return None
|
||||
with open(file_path, 'rb') as file_in:
|
||||
data = file_in.read()
|
||||
file_type, decode_code = get_code(data[:2])
|
||||
|
||||
data = get_code(data[:2])
|
||||
file_type, decode_code = data
|
||||
if decode_code == -1:
|
||||
return
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user